package query import ( "context" "database/sql" "github.com/jmoiron/sqlx" "go.mongodb.org/mongo-driver/mongo" ) // Main entry point for backward compatibility // This file provides the main interface and factory functions // QueryBuilderFactory creates query builders for different database types type QueryBuilderFactory interface { CreateSQLQueryBuilder(dbType DBType) QueryBuilder CreateMongoQueryBuilder() MongoQueryBuilder CreateQueryParser() QueryParser } // DefaultQueryBuilderFactory implements QueryBuilderFactory type DefaultQueryBuilderFactory struct{} // NewQueryBuilderFactory creates a new query builder factory func NewQueryBuilderFactory() QueryBuilderFactory { return &DefaultQueryBuilderFactory{} } // CreateSQLQueryBuilder creates a new SQL query builder func (f *DefaultQueryBuilderFactory) CreateSQLQueryBuilder(dbType DBType) QueryBuilder { return NewSQLQueryBuilder(dbType) } // CreateMongoQueryBuilder creates a new MongoDB query builder func (f *DefaultQueryBuilderFactory) CreateMongoQueryBuilder() MongoQueryBuilder { return NewMongoQueryBuilder() } // CreateQueryParser creates a new query parser func (f *DefaultQueryBuilderFactory) CreateQueryParser() QueryParser { return NewQueryParser() } // QueryManager provides a unified interface for all query operations type QueryManager struct { SQLBuilder QueryBuilder MongoBuilder MongoQueryBuilder QueryParser QueryParser } // NewQueryManager creates a new query manager with all builders func NewQueryManager(dbType DBType) *QueryManager { return &QueryManager{ SQLBuilder: NewSQLQueryBuilder(dbType), MongoBuilder: NewMongoQueryBuilder(), QueryParser: NewQueryParser(), } } // NewQueryManagerWithFactory creates a new query manager using factory func NewQueryManagerWithFactory(factory QueryBuilderFactory, dbType DBType) *QueryManager { return &QueryManager{ SQLBuilder: factory.CreateSQLQueryBuilder(dbType), MongoBuilder: factory.CreateMongoQueryBuilder(), QueryParser: factory.CreateQueryParser(), } } // GetSQLBuilder returns the SQL query builder func (qm *QueryManager) GetSQLBuilder() QueryBuilder { return qm.SQLBuilder } // GetMongoBuilder returns the MongoDB query builder func (qm *QueryManager) GetMongoBuilder() MongoQueryBuilder { return qm.MongoBuilder } // GetQueryParser returns the query parser func (qm *QueryManager) GetQueryParser() QueryParser { return qm.QueryParser } // ExecuteSQLQuery executes a SQL query with the SQL builder func (qm *QueryManager) ExecuteSQLQuery(ctx context.Context, db *sqlx.DB, query DynamicQuery, dest interface{}) error { return qm.SQLBuilder.ExecuteQuery(ctx, db, query, dest) } // ExecuteMongoQuery executes a MongoDB query with the MongoDB builder func (qm *QueryManager) ExecuteMongoQuery(ctx context.Context, collection *mongo.Collection, query DynamicQuery, dest interface{}) error { return qm.MongoBuilder.ExecuteFind(ctx, collection, query, dest) } // ParseQuery parses URL query parameters into a DynamicQuery func (qm *QueryManager) ParseQuery(values interface{}, defaultTable string) (DynamicQuery, error) { return qm.QueryParser.ParseQuery(values, defaultTable) } // ParseQueryWithDefaultFields parses URL query parameters with default fields func (qm *QueryManager) ParseQueryWithDefaultFields(values interface{}, defaultTable string, defaultFields []string) (DynamicQuery, error) { return qm.QueryParser.ParseQueryWithDefaultFields(values, defaultTable, defaultFields) } // Convenience functions for common operations // CreateQueryBuilder creates a query builder with default settings func CreateQueryBuilder(dbType DBType) QueryBuilder { return NewSQLQueryBuilder(dbType). SetSecurityOptions(true, 1000). SetQueryLogging(true). SetQueryTimeout(30) } // CreateMongoQueryBuilder creates a MongoDB query builder with default settings func CreateMongoQueryBuilder() MongoQueryBuilder { return NewMongoQueryBuilder(). SetSecurityOptions(true, 1000). SetQueryLogging(true). SetQueryTimeout(30) } // CreateQueryParser creates a query parser with default settings func CreateQueryParser() QueryParser { return NewQueryParser().SetLimits(10, 100) } // ExecuteQuery is a convenience function for executing SQL queries func ExecuteQuery(ctx context.Context, db *sqlx.DB, dbType DBType, query DynamicQuery, dest interface{}) error { builder := CreateQueryBuilder(dbType) return builder.ExecuteQuery(ctx, db, query, dest) } // ExecuteMongoQuery is a convenience function for executing MongoDB queries func ExecuteMongoQuery(ctx context.Context, collection *mongo.Collection, query DynamicQuery, dest interface{}) error { builder := CreateMongoQueryBuilder() return builder.ExecuteFind(ctx, collection, query, dest) } // ParseURLQuery is a convenience function for parsing URL queries func ParseURLQuery(urlValues interface{}, defaultTable string) (DynamicQuery, error) { parser := CreateQueryParser() return parser.ParseQuery(urlValues, defaultTable) } // ParseURLQueryWithFields is a convenience function for parsing URL queries with default fields func ParseURLQueryWithFields(urlValues interface{}, defaultTable string, defaultFields []string) (DynamicQuery, error) { parser := CreateQueryParser() return parser.ParseQueryWithDefaultFields(urlValues, defaultTable, defaultFields) } // Database-specific helpers // ForPostgreSQL creates a PostgreSQL-specific query builder func ForPostgreSQL() QueryBuilder { return NewSQLQueryBuilder(DBTypePostgreSQL) } // ForMySQL creates a MySQL-specific query builder func ForMySQL() QueryBuilder { return NewSQLQueryBuilder(DBTypeMySQL) } // ForSQLite creates a SQLite-specific query builder func ForSQLite() QueryBuilder { return NewSQLQueryBuilder(DBTypeSQLite) } // ForSQLServer creates a SQL Server-specific query builder func ForSQLServer() QueryBuilder { return NewSQLQueryBuilder(DBTypeSQLServer) } // ForMongoDB creates a MongoDB-specific query builder func ForMongoDB() MongoQueryBuilder { return NewMongoQueryBuilder() } // Query execution helpers // ExecuteCount executes a count query func ExecuteCount(ctx context.Context, db *sqlx.DB, dbType DBType, query DynamicQuery) (int64, error) { builder := CreateQueryBuilder(dbType) return builder.ExecuteCount(ctx, db, query) } // ExecuteInsert executes an insert query func ExecuteInsert(ctx context.Context, db *sqlx.DB, dbType DBType, table string, data InsertData, returningColumns ...string) (sql.Result, error) { builder := CreateQueryBuilder(dbType) return builder.ExecuteInsert(ctx, db, table, data, returningColumns...) } // ExecuteUpdate executes an update query func ExecuteUpdate(ctx context.Context, db *sqlx.DB, dbType DBType, table string, updateData UpdateData, filters []FilterGroup, returningColumns ...string) (sql.Result, error) { builder := CreateQueryBuilder(dbType) return builder.ExecuteUpdate(ctx, db, table, updateData, filters, returningColumns...) } // ExecuteDelete executes a delete query func ExecuteDelete(ctx context.Context, db *sqlx.DB, dbType DBType, table string, filters []FilterGroup, returningColumns ...string) (sql.Result, error) { builder := CreateQueryBuilder(dbType) return builder.ExecuteDelete(ctx, db, table, filters, returningColumns...) } // ExecuteUpsert executes an upsert query func ExecuteUpsert(ctx context.Context, db *sqlx.DB, dbType DBType, table string, insertData InsertData, conflictColumns []string, updateColumns []string, returningColumns ...string) (sql.Result, error) { builder := CreateQueryBuilder(dbType) return builder.ExecuteUpsert(ctx, db, table, insertData, conflictColumns, updateColumns, returningColumns...) } // MongoDB execution helpers // ExecuteMongoCount executes a MongoDB count query func ExecuteMongoCount(ctx context.Context, collection *mongo.Collection, query DynamicQuery) (int64, error) { builder := CreateMongoQueryBuilder() return builder.ExecuteCount(ctx, collection, query) } // ExecuteMongoInsert executes a MongoDB insert query func ExecuteMongoInsert(ctx context.Context, collection *mongo.Collection, data InsertData) (*mongo.InsertOneResult, error) { builder := CreateMongoQueryBuilder() return builder.ExecuteInsert(ctx, collection, data) } // ExecuteMongoUpdate executes a MongoDB update query func ExecuteMongoUpdate(ctx context.Context, collection *mongo.Collection, updateData UpdateData, filters []FilterGroup) (*mongo.UpdateResult, error) { builder := CreateMongoQueryBuilder() return builder.ExecuteUpdate(ctx, collection, updateData, filters) } // ExecuteMongoDelete executes a MongoDB delete query func ExecuteMongoDelete(ctx context.Context, collection *mongo.Collection, filters []FilterGroup) (*mongo.DeleteResult, error) { builder := CreateMongoQueryBuilder() return builder.ExecuteDelete(ctx, collection, filters) } // ExecuteMongoAggregate executes a MongoDB aggregation query func ExecuteMongoAggregate(ctx context.Context, collection *mongo.Collection, query DynamicQuery, dest interface{}) error { builder := CreateMongoQueryBuilder() return builder.ExecuteAggregate(ctx, collection, query, dest) } // Utility functions for creating common queries // CreateSimpleQuery creates a simple query with basic fields func CreateSimpleQuery(table string, fields []string, limit int) DynamicQuery { selectFields := make([]SelectField, len(fields)) for i, field := range fields { selectFields[i] = SelectField{Expression: field} } return DynamicQuery{ From: table, Fields: selectFields, Limit: limit, Offset: 0, } } // CreateFilterQuery creates a query with filters func CreateFilterQuery(table string, fields []string, filters []DynamicFilter, limit int) DynamicQuery { selectFields := make([]SelectField, len(fields)) for i, field := range fields { selectFields[i] = SelectField{Expression: field} } return DynamicQuery{ From: table, Fields: selectFields, Filters: []FilterGroup{{Filters: filters, LogicOp: "AND"}}, Limit: limit, Offset: 0, } } // CreateSortedQuery creates a query with sorting func CreateSortedQuery(table string, fields []string, sorts []SortField, limit int) DynamicQuery { selectFields := make([]SelectField, len(fields)) for i, field := range fields { selectFields[i] = SelectField{Expression: field} } return DynamicQuery{ From: table, Fields: selectFields, Sort: sorts, Limit: limit, Offset: 0, } } // CreatePaginatedQuery creates a paginated query func CreatePaginatedQuery(table string, fields []string, filters []DynamicFilter, sorts []SortField, limit, offset int) DynamicQuery { selectFields := make([]SelectField, len(fields)) for i, field := range fields { selectFields[i] = SelectField{Expression: field} } return DynamicQuery{ From: table, Fields: selectFields, Filters: []FilterGroup{{Filters: filters, LogicOp: "AND"}}, Sort: sorts, Limit: limit, Offset: offset, } } // CreateInsertData creates insert data from a map func CreateInsertData(data map[string]interface{}) InsertData { columns := make([]string, 0, len(data)) values := make([]interface{}, 0, len(data)) for col, val := range data { columns = append(columns, col) values = append(values, val) } return InsertData{ Columns: columns, Values: values, } } // CreateUpdateData creates update data from a map func CreateUpdateData(data map[string]interface{}) UpdateData { columns := make([]string, 0, len(data)) values := make([]interface{}, 0, len(data)) for col, val := range data { columns = append(columns, col) values = append(values, val) } return UpdateData{ Columns: columns, Values: values, } } // CreateFilter creates a simple filter func CreateFilter(column string, operator FilterOperator, value interface{}) DynamicFilter { return DynamicFilter{ Column: column, Operator: operator, Value: value, } } // CreateEqualFilter creates an equality filter func CreateEqualFilter(column string, value interface{}) DynamicFilter { return CreateFilter(column, OpEqual, value) } // CreateLikeFilter creates a LIKE filter func CreateLikeFilter(column string, value string) DynamicFilter { return CreateFilter(column, OpLike, value) } // CreateInFilter creates an IN filter func CreateInFilter(column string, values []interface{}) DynamicFilter { return CreateFilter(column, OpIn, values) } // CreateBetweenFilter creates a BETWEEN filter func CreateBetweenFilter(column string, min, max interface{}) DynamicFilter { return CreateFilter(column, OpBetween, []interface{}{min, max}) } // CreateSort creates a sort field func CreateSort(column string, order string) SortField { return SortField{ Column: column, Order: order, } } // CreateAscSort creates an ascending sort func CreateAscSort(column string) SortField { return CreateSort(column, "ASC") } // CreateDescSort creates a descending sort func CreateDescSort(column string) SortField { return CreateSort(column, "DESC") } // CreateFilterGroup creates a filter group func CreateFilterGroup(filters []DynamicFilter, logicOp string) FilterGroup { return FilterGroup{ Filters: filters, LogicOp: logicOp, } } // CreateAndFilterGroup creates an AND filter group func CreateAndFilterGroup(filters []DynamicFilter) FilterGroup { return CreateFilterGroup(filters, "AND") } // CreateOrFilterGroup creates an OR filter group func CreateOrFilterGroup(filters []DynamicFilter) FilterGroup { return CreateFilterGroup(filters, "OR") }