first commit
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// ExecuteFind executes a MongoDB find query
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteFind(ctx context.Context, collection *mongo.Collection, query DynamicQuery, dest interface{}) error {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
filter, findOptions, err := mqb.BuildFindQuery(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
cursor, err := collection.Find(ctx, filter.(bson.M), findOptions.(*options.FindOptions))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
err = cursor.All(ctx, dest)
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Find executed in %v\n", time.Since(start))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecuteAggregate executes a MongoDB aggregation pipeline
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteAggregate(ctx context.Context, collection *mongo.Collection, query DynamicQuery, dest interface{}) error {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
pipeline, err := mqb.BuildAggregateQuery(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
cursor, err := collection.Aggregate(ctx, pipeline.([]bson.D))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
err = cursor.All(ctx, dest)
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Aggregate executed in %v\n", time.Since(start))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecuteCount executes a MongoDB count query
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteCount(ctx context.Context, collection *mongo.Collection, query DynamicQuery) (int64, error) {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return 0, fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
filter, _, err := mqb.BuildFindQuery(query)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
count, err := collection.CountDocuments(ctx, filter.(bson.M))
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Count executed in %v\n", time.Since(start))
|
||||
}
|
||||
return count, err
|
||||
}
|
||||
|
||||
// ExecuteInsert executes a MongoDB insert operation
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteInsert(ctx context.Context, collection *mongo.Collection, data InsertData) (*mongo.InsertOneResult, error) {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return nil, fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
document := bson.M{}
|
||||
for i, col := range data.Columns {
|
||||
if mqb.allowedFields != nil && !mqb.allowedFields[col] {
|
||||
return nil, fmt.Errorf("disallowed field: %s", col)
|
||||
}
|
||||
document[col] = data.Values[i]
|
||||
}
|
||||
|
||||
// Handle JSON values
|
||||
for col, val := range data.JsonValues {
|
||||
if mqb.allowedFields != nil && !mqb.allowedFields[col] {
|
||||
return nil, fmt.Errorf("disallowed field: %s", col)
|
||||
}
|
||||
document[col] = val
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
result, err := collection.InsertOne(ctx, document)
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Insert executed in %v\n", time.Since(start))
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ExecuteUpdate executes a MongoDB update operation
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteUpdate(ctx context.Context, collection *mongo.Collection, updateData UpdateData, filters []FilterGroup) (*mongo.UpdateResult, error) {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return nil, fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
filter, err := mqb.buildFilter(filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update := bson.M{"$set": bson.M{}}
|
||||
for i, col := range updateData.Columns {
|
||||
if mqb.allowedFields != nil && !mqb.allowedFields[col] {
|
||||
return nil, fmt.Errorf("disallowed field: %s", col)
|
||||
}
|
||||
update["$set"].(bson.M)[col] = updateData.Values[i]
|
||||
}
|
||||
|
||||
// Handle JSON updates
|
||||
for col, jsonUpdate := range updateData.JsonUpdates {
|
||||
if mqb.allowedFields != nil && !mqb.allowedFields[col] {
|
||||
return nil, fmt.Errorf("disallowed field: %s", col)
|
||||
}
|
||||
// Use dot notation for nested JSON updates
|
||||
update["$set"].(bson.M)[col+"."+jsonUpdate.Path] = jsonUpdate.Value
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
result, err := collection.UpdateMany(ctx, filter, update)
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Update executed in %v\n", time.Since(start))
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ExecuteDelete executes a MongoDB delete operation
|
||||
func (mqb *MongoQueryBuilderImpl) ExecuteDelete(ctx context.Context, collection *mongo.Collection, filters []FilterGroup) (*mongo.DeleteResult, error) {
|
||||
// Security check for collection name
|
||||
if mqb.enableSecurityChecks && len(mqb.allowedCollections) > 0 && !mqb.allowedCollections[collection.Name()] {
|
||||
return nil, fmt.Errorf("disallowed collection: %s", collection.Name())
|
||||
}
|
||||
|
||||
filter, err := mqb.buildFilter(filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set timeout if not already in context
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline && mqb.queryTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(mqb.queryTimeout)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
result, err := collection.DeleteMany(ctx, filter)
|
||||
if mqb.enableQueryLogging {
|
||||
fmt.Printf("[DEBUG] MongoDB Delete executed in %v\n", time.Since(start))
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
Reference in New Issue
Block a user