38844939b5
- Changed API tags from "Admin-Users" to "Admin-Authorization" for better clarity in user management endpoints. - Removed unused endpoints for retrieving users by company ID and role, streamlining the user management functionality. - Updated user entity and forms to reflect new example values for improved clarity in API documentation. - Enhanced pagination handling in user listing responses, ensuring consistent metadata structure. - Updated API documentation to reflect changes in endpoint structure and response formats, improving clarity for API consumers.
306 lines
8.7 KiB
Go
306 lines
8.7 KiB
Go
package mongo
|
|
|
|
import (
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
// Index represents a MongoDB index
|
|
type Index struct {
|
|
Name string `json:"name"`
|
|
Keys bson.D `json:"keys"`
|
|
Options *options.IndexOptions `json:"options"`
|
|
}
|
|
|
|
// NewIndex creates a new index with default options
|
|
func NewIndex(name string, keys bson.D) *Index {
|
|
return &Index{
|
|
Name: name,
|
|
Keys: keys,
|
|
Options: options.Index(),
|
|
}
|
|
}
|
|
|
|
// WithUnique sets the unique option for the index
|
|
func (i *Index) WithUnique(unique bool) *Index {
|
|
i.Options.SetUnique(unique)
|
|
return i
|
|
}
|
|
|
|
// WithSparse sets the sparse option for the index
|
|
func (i *Index) WithSparse(sparse bool) *Index {
|
|
i.Options.SetSparse(sparse)
|
|
return i
|
|
}
|
|
|
|
// WithBackground sets the background option for the index
|
|
func (i *Index) WithBackground(background bool) *Index {
|
|
i.Options.SetBackground(background)
|
|
return i
|
|
}
|
|
|
|
// WithExpireAfterSeconds sets the TTL for the index
|
|
func (i *Index) WithExpireAfterSeconds(seconds int32) *Index {
|
|
i.Options.SetExpireAfterSeconds(seconds)
|
|
return i
|
|
}
|
|
|
|
// WithPartialFilterExpression sets the partial filter expression for the index
|
|
func (i *Index) WithPartialFilterExpression(filter bson.M) *Index {
|
|
i.Options.SetPartialFilterExpression(filter)
|
|
return i
|
|
}
|
|
|
|
// WithCollation sets the collation for the index
|
|
func (i *Index) WithCollation(collation *options.Collation) *Index {
|
|
i.Options.SetCollation(collation)
|
|
return i
|
|
}
|
|
|
|
// Common index builders
|
|
|
|
// CreateUniqueIndex creates a unique index
|
|
func CreateUniqueIndex(name string, keys bson.D) *Index {
|
|
return NewIndex(name, keys).WithUnique(true)
|
|
}
|
|
|
|
// CreateTTLIndex creates a TTL index
|
|
func CreateTTLIndex(name string, field string, expireAfterSeconds int32) *Index {
|
|
return NewIndex(name, bson.D{{Key: field, Value: 1}}).WithExpireAfterSeconds(expireAfterSeconds)
|
|
}
|
|
|
|
// CreateTextIndex creates a text index
|
|
func CreateTextIndex(name string, fields ...string) *Index {
|
|
keys := bson.D{}
|
|
for _, field := range fields {
|
|
keys = append(keys, bson.E{Key: field, Value: "text"})
|
|
}
|
|
return NewIndex(name, keys)
|
|
}
|
|
|
|
// CreateCompoundIndex creates a compound index
|
|
func CreateCompoundIndex(name string, fields map[string]int) *Index {
|
|
keys := bson.D{}
|
|
for field, direction := range fields {
|
|
keys = append(keys, bson.E{Key: field, Value: direction})
|
|
}
|
|
return NewIndex(name, keys)
|
|
}
|
|
|
|
// CreateGeospatialIndex creates a 2dsphere geospatial index
|
|
func CreateGeospatialIndex(name string, field string) *Index {
|
|
return NewIndex(name, bson.D{{Key: field, Value: "2dsphere"}})
|
|
}
|
|
|
|
// CreateHashedIndex creates a hashed index
|
|
func CreateHashedIndex(name string, field string) *Index {
|
|
return NewIndex(name, bson.D{{Key: field, Value: "hashed"}})
|
|
}
|
|
|
|
// Common index patterns
|
|
|
|
// DefaultIndexes returns common default indexes for most collections
|
|
func DefaultIndexes() []Index {
|
|
return []Index{
|
|
*CreateUniqueIndex("_id_", bson.D{{Key: "_id", Value: 1}}),
|
|
*NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
|
*NewIndex("updated_at_idx", bson.D{{Key: "updated_at", Value: -1}}),
|
|
}
|
|
}
|
|
|
|
// UserIndexes returns common indexes for user collections
|
|
func UserIndexes() []Index {
|
|
return []Index{
|
|
*CreateUniqueIndex("_id_", bson.D{{Key: "_id", Value: 1}}),
|
|
*CreateUniqueIndex("email_idx", bson.D{{Key: "email", Value: 1}}),
|
|
*NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
|
*NewIndex("updated_at_idx", bson.D{{Key: "updated_at", Value: -1}}),
|
|
*NewIndex("is_active_idx", bson.D{{Key: "is_active", Value: 1}}),
|
|
}
|
|
}
|
|
|
|
// TenderIndexes returns common indexes for tender collections
|
|
func TenderIndexes() []Index {
|
|
return []Index{
|
|
*CreateUniqueIndex("_id_", bson.D{{Key: "_id", Value: 1}}),
|
|
*NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
|
*NewIndex("updated_at_idx", bson.D{{Key: "updated_at", Value: -1}}),
|
|
*NewIndex("status_idx", bson.D{{Key: "status", Value: 1}}),
|
|
*NewIndex("deadline_idx", bson.D{{Key: "deadline", Value: 1}}),
|
|
*NewIndex("category_idx", bson.D{{Key: "category", Value: 1}}),
|
|
*NewIndex("location_idx", bson.D{{Key: "location", Value: 1}}),
|
|
}
|
|
}
|
|
|
|
// CompanyIndexes returns common indexes for company collections
|
|
func CompanyIndexes() []Index {
|
|
return []Index{
|
|
*CreateUniqueIndex("_id_", bson.D{{Key: "_id", Value: 1}}),
|
|
*CreateUniqueIndex("name_idx", bson.D{{Key: "name", Value: 1}}),
|
|
*NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
|
*NewIndex("updated_at_idx", bson.D{{Key: "updated_at", Value: -1}}),
|
|
*NewIndex("is_active_idx", bson.D{{Key: "is_active", Value: 1}}),
|
|
}
|
|
}
|
|
|
|
// QueryBuilder provides a fluent interface for building MongoDB queries
|
|
type QueryBuilder struct {
|
|
filter bson.M
|
|
}
|
|
|
|
// NewQueryBuilder creates a new query builder
|
|
func NewQueryBuilder() *QueryBuilder {
|
|
return &QueryBuilder{
|
|
filter: bson.M{},
|
|
}
|
|
}
|
|
|
|
// Where adds a simple equality condition
|
|
func (qb *QueryBuilder) Where(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = value
|
|
return qb
|
|
}
|
|
|
|
// WhereIn adds an $in condition
|
|
func (qb *QueryBuilder) WhereIn(field string, values []interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$in": values}
|
|
return qb
|
|
}
|
|
|
|
// WhereNotIn adds a $nin condition
|
|
func (qb *QueryBuilder) WhereNotIn(field string, values []interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$nin": values}
|
|
return qb
|
|
}
|
|
|
|
// WhereGreaterThan adds a $gt condition
|
|
func (qb *QueryBuilder) WhereGreaterThan(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$gt": value}
|
|
return qb
|
|
}
|
|
|
|
// WhereGreaterThanOrEqual adds a $gte condition
|
|
func (qb *QueryBuilder) WhereGreaterThanOrEqual(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$gte": value}
|
|
return qb
|
|
}
|
|
|
|
// WhereLessThan adds a $lt condition
|
|
func (qb *QueryBuilder) WhereLessThan(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$lt": value}
|
|
return qb
|
|
}
|
|
|
|
// WhereLessThanOrEqual adds a $lte condition
|
|
func (qb *QueryBuilder) WhereLessThanOrEqual(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$lte": value}
|
|
return qb
|
|
}
|
|
|
|
// WhereNotEqual adds a $ne condition
|
|
func (qb *QueryBuilder) WhereNotEqual(field string, value interface{}) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$ne": value}
|
|
return qb
|
|
}
|
|
|
|
// WhereExists adds an $exists condition
|
|
func (qb *QueryBuilder) WhereExists(field string, exists bool) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$exists": exists}
|
|
return qb
|
|
}
|
|
|
|
// WhereRegex adds a $regex condition
|
|
func (qb *QueryBuilder) WhereRegex(field string, pattern string, options string) *QueryBuilder {
|
|
qb.filter[field] = bson.M{"$regex": pattern, "$options": options}
|
|
return qb
|
|
}
|
|
|
|
// WhereText adds a $text condition
|
|
func (qb *QueryBuilder) WhereText(search string) *QueryBuilder {
|
|
qb.filter["$text"] = bson.M{"$search": search}
|
|
return qb
|
|
}
|
|
|
|
// WhereAnd adds an $and condition
|
|
func (qb *QueryBuilder) WhereAnd(conditions ...bson.M) *QueryBuilder {
|
|
qb.filter["$and"] = conditions
|
|
return qb
|
|
}
|
|
|
|
// WhereOr adds an $or condition
|
|
func (qb *QueryBuilder) WhereOr(conditions ...bson.M) *QueryBuilder {
|
|
qb.filter["$or"] = conditions
|
|
return qb
|
|
}
|
|
|
|
// WhereNor adds a $nor condition
|
|
func (qb *QueryBuilder) WhereNor(conditions ...bson.M) *QueryBuilder {
|
|
qb.filter["$nor"] = conditions
|
|
return qb
|
|
}
|
|
|
|
// Build returns the final filter
|
|
func (qb *QueryBuilder) Build() bson.M {
|
|
return qb.filter
|
|
}
|
|
|
|
// PaginationBuilder provides a fluent interface for building pagination options
|
|
type PaginationBuilder struct {
|
|
pagination Pagination
|
|
}
|
|
|
|
// NewPaginationBuilder creates a new pagination builder
|
|
func NewPaginationBuilder() *PaginationBuilder {
|
|
return &PaginationBuilder{
|
|
pagination: Pagination{
|
|
Limit: 10,
|
|
SortField: "_id",
|
|
SortOrder: -1,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Limit sets the limit
|
|
func (pb *PaginationBuilder) Limit(limit int) *PaginationBuilder {
|
|
pb.pagination.Limit = limit
|
|
return pb
|
|
}
|
|
|
|
// Skip sets the skip value for offset-based pagination
|
|
func (pb *PaginationBuilder) Skip(skip int) *PaginationBuilder {
|
|
pb.pagination.Skip = skip
|
|
return pb
|
|
}
|
|
|
|
// Cursor sets the cursor for cursor-based pagination
|
|
func (pb *PaginationBuilder) Cursor(cursor string) *PaginationBuilder {
|
|
pb.pagination.Cursor = cursor
|
|
return pb
|
|
}
|
|
|
|
// SortBy sets the sort field and order
|
|
func (pb *PaginationBuilder) SortBy(field string, order string) *PaginationBuilder {
|
|
pb.pagination.SortField = field
|
|
if order == "asc" {
|
|
pb.pagination.SortOrder = 1
|
|
} else {
|
|
pb.pagination.SortOrder = -1
|
|
}
|
|
return pb
|
|
}
|
|
|
|
// SortAsc sorts in ascending order
|
|
func (pb *PaginationBuilder) SortAsc(field string) *PaginationBuilder {
|
|
return pb.SortBy(field, "asc")
|
|
}
|
|
|
|
// SortDesc sorts in descending order
|
|
func (pb *PaginationBuilder) SortDesc(field string) *PaginationBuilder {
|
|
return pb.SortBy(field, "desc")
|
|
}
|
|
|
|
// Build returns the final pagination options
|
|
func (pb *PaginationBuilder) Build() Pagination {
|
|
return pb.pagination
|
|
}
|