package main import ( "context" "database/sql" "fmt" "log" "time" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" // PostgreSQL driver "yourpackage/utils" ) func main() { // Inisialisasi koneksi database db, err := sqlx.Connect("postgres", "user=postgres dbname=testdb sslmode=disable") if err != nil { log.Fatalf("Failed to connect to database: %v", err) } defer db.Close() // Inisialisasi QueryBuilder qb := utils.NewQueryBuilder(utils.DBTypePostgreSQL) // Contoh penggunaan simpleQueryExample(db, qb) complexQueryExample(db, qb) nestedJoinExample(db, qb) multiJoinExample(db, qb) commonQueriesExample(db, qb) jsonQueryExample(db, qb) windowFunctionExample(db, qb) cteExample(db, qb) unionExample(db, qb) aggregateExample(db, qb) } func simpleQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Simple Query Example ===") // Query sederhana dengan filter query := utils.DynamicQuery{ From: "users", Fields: []utils.SelectField{ {Expression: "id", Alias: "user_id"}, {Expression: "name", Alias: "user_name"}, {Expression: "email"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, {Column: "created_at", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(0, -1, 0)}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "name", Order: "ASC"}, }, Limit: 10, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing simple query: %v", err) return } fmt.Printf("Found %d users\n", len(results)) for _, user := range results { fmt.Printf("User: %+v\n", user) } } func complexQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Complex Query Example ===") // Query dengan nested filter dan berbagai operator query := utils.DynamicQuery{ From: "orders", Fields: []utils.SelectField{ {Expression: "id", Alias: "order_id"}, {Expression: "customer_id"}, {Expression: "total_amount"}, {Expression: "order_date"}, {Expression: "status"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpIn, Value: []string{"completed", "processing"}}, {Column: "total_amount", Operator: utils.OpGreaterThan, Value: 1000}, }, LogicOp: "AND", }, { Filters: []utils.DynamicFilter{ {Column: "order_date", Operator: utils.OpBetween, Value: []interface{}{time.Now().AddDate(0, -3, 0), time.Now()}}, {Column: "customer_id", Operator: utils.OpNotIn, Value: []int{1, 2, 3}}, }, LogicOp: "OR", }, }, Sort: []utils.SortField{ {Column: "order_date", Order: "DESC"}, {Column: "total_amount", Order: "DESC"}, }, Limit: 20, Offset: 10, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing complex query: %v", err) return } fmt.Printf("Found %d orders\n", len(results)) for _, order := range results { fmt.Printf("Order: %+v\n", order) } } func nestedJoinExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Nested Join Example ===") // Query dengan nested join query := utils.DynamicQuery{ From: "customers", Fields: []utils.SelectField{ {Expression: "customers.id", Alias: "customer_id"}, {Expression: "customers.name", Alias: "customer_name"}, {Expression: "orders.id", Alias: "order_id"}, {Expression: "orders.total_amount"}, {Expression: "order_items.product_id"}, {Expression: "order_items.quantity"}, {Expression: "products.name", Alias: "product_name"}, }, Joins: []utils.Join{ { Type: "LEFT", Table: "orders", Alias: "orders", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "customers.id", Operator: utils.OpEqual, Value: "orders.customer_id"}, }, }, }, { Type: "LEFT", Table: "order_items", Alias: "order_items", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "orders.id", Operator: utils.OpEqual, Value: "order_items.order_id"}, }, }, }, { Type: "LEFT", Table: "products", Alias: "products", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "order_items.product_id", Operator: utils.OpEqual, Value: "products.id"}, }, }, }, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "customers.status", Operator: utils.OpEqual, Value: "active"}, {Column: "orders.status", Operator: utils.OpEqual, Value: "completed"}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "customers.name", Order: "ASC"}, {Column: "orders.id", Order: "DESC"}, }, Limit: 50, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing nested join query: %v", err) return } fmt.Printf("Found %d customer-order-product records\n", len(results)) for _, record := range results { fmt.Printf("Record: %+v\n", record) } } func multiJoinExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Multi Join Example ===") // Query dengan multiple join types query := utils.DynamicQuery{ From: "employees", Fields: []utils.SelectField{ {Expression: "employees.id", Alias: "employee_id"}, {Expression: "employees.name", Alias: "employee_name"}, {Expression: "departments.name", Alias: "department_name"}, {Expression: "projects.name", Alias: "project_name"}, {Expression: "tasks.title", Alias: "task_title"}, {Expression: "task_assignments.assigned_date"}, }, Joins: []utils.Join{ { Type: "INNER", Table: "departments", Alias: "departments", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "employees.department_id", Operator: utils.OpEqual, Value: "departments.id"}, }, }, }, { Type: "LEFT", Table: "task_assignments", Alias: "task_assignments", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "employees.id", Operator: utils.OpEqual, Value: "task_assignments.employee_id"}, }, }, }, { Type: "LEFT", Table: "tasks", Alias: "tasks", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "task_assignments.task_id", Operator: utils.OpEqual, Value: "tasks.id"}, }, }, }, { Type: "LEFT", Table: "projects", Alias: "projects", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "tasks.project_id", Operator: utils.OpEqual, Value: "projects.id"}, }, }, }, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "employees.status", Operator: utils.OpEqual, Value: "active"}, {Column: "departments.status", Operator: utils.OpEqual, Value: "active"}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "departments.name", Order: "ASC"}, {Column: "employees.name", Order: "ASC"}, {Column: "task_assignments.assigned_date", Order: "DESC"}, }, Limit: 100, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing multi join query: %v", err) return } fmt.Printf("Found %d employee-task-project records\n", len(results)) for _, record := range results { fmt.Printf("Record: %+v\n", record) } } func commonQueriesExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Common Queries Example ===") // 1. Query dengan LIKE/ILIKE likeQuery := utils.DynamicQuery{ From: "products", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "name"}, {Expression: "price"}, {Expression: "category"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "name", Operator: utils.OpILike, Value: "%laptop%"}, {Column: "category", Operator: utils.OpEqual, Value: "electronics"}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "price", Order: "ASC"}, }, Limit: 10, } var products []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, likeQuery, &products) if err != nil { log.Printf("Error executing LIKE query: %v", err) } else { fmt.Printf("Found %d products matching 'laptop'\n", len(products)) } // 2. Query dengan pagination page := 2 pageSize := 20 paginationQuery := utils.DynamicQuery{ From: "orders", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "customer_id"}, {Expression: "total_amount"}, {Expression: "order_date"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "completed"}, }, }, }, Sort: []utils.SortField{ {Column: "order_date", Order: "DESC"}, }, Limit: pageSize, Offset: (page - 1) * pageSize, } var orders []map[string]interface{} err = qb.ExecuteQuery(context.Background(), db, paginationQuery, &orders) if err != nil { log.Printf("Error executing pagination query: %v", err) } else { fmt.Printf("Found %d orders on page %d\n", len(orders), page) } // 3. Query dengan NULL/NOT NULL nullQuery := utils.DynamicQuery{ From: "customers", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "name"}, {Expression: "email"}, {Expression: "phone"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "email", Operator: utils.OpNotNull}, {Column: "phone", Operator: utils.OpNull}, }, LogicOp: "AND", }, }, Limit: 10, } var customers []map[string]interface{} err = qb.ExecuteQuery(context.Background(), db, nullQuery, &customers) if err != nil { log.Printf("Error executing NULL query: %v", err) } else { fmt.Printf("Found %d customers with email but no phone\n", len(customers)) } // 4. Query dengan BETWEEN betweenQuery := utils.DynamicQuery{ From: "transactions", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "account_id"}, {Expression: "amount"}, {Expression: "transaction_date"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "amount", Operator: utils.OpBetween, Value: []interface{}{100, 1000}}, {Column: "transaction_date", Operator: utils.OpBetween, Value: []interface{}{time.Now().AddDate(0, -1, 0), time.Now()}}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "transaction_date", Order: "DESC"}, }, Limit: 20, } var transactions []map[string]interface{} err = qb.ExecuteQuery(context.Background(), db, betweenQuery, &transactions) if err != nil { log.Printf("Error executing BETWEEN query: %v", err) } else { fmt.Printf("Found %d transactions between $100 and $1000 in the last month\n", len(transactions)) } } func jsonQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== JSON Query Example ===") // Query dengan operasi JSON query := utils.DynamicQuery{ From: "products", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "name"}, {Expression: "price"}, {Expression: "attributes"}, }, JsonOperations: []utils.JsonOperation{ { Type: "extract", Column: "attributes", Path: "$.color", Alias: "color", }, { Type: "extract", Column: "attributes", Path: "$.size", Alias: "size", }, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ { Column: "attributes", Operator: utils.OpJsonContains, Value: map[string]interface{}{"category": "electronics"}, Options: map[string]interface{}{"path": "$"}, }, }, }, }, Sort: []utils.SortField{ {Column: "name", Order: "ASC"}, }, Limit: 10, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing JSON query: %v", err) return } fmt.Printf("Found %d products with JSON attributes\n", len(results)) for _, product := range results { fmt.Printf("Product: %+v\n", product) } } func windowFunctionExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Window Function Example ===") // Query dengan window functions query := utils.DynamicQuery{ From: "sales", Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "salesperson_id"}, {Expression: "amount"}, {Expression: "sale_date"}, }, WindowFunctions: []utils.WindowFunction{ { Function: "ROW_NUMBER", Over: "salesperson_id", OrderBy: "amount DESC", Alias: "sales_rank", }, { Function: "SUM", Over: "salesperson_id", OrderBy: "sale_date", Frame: "ROWS UNBOUNDED PRECEDING", Alias: "running_total", }, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "sale_date", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(0, -6, 0)}, }, }, }, Sort: []utils.SortField{ {Column: "salesperson_id", Order: "ASC"}, {Column: "amount", Order: "DESC"}, }, Limit: 50, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing window function query: %v", err) return } fmt.Printf("Found %d sales records with window functions\n", len(results)) for _, sale := range results { fmt.Printf("Sale: %+v\n", sale) } } func cteExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== CTE Example ===") // Query dengan CTE query := utils.DynamicQuery{ CTEs: []utils.CTE{ { Name: "monthly_sales", Query: utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "salesperson_id"}, {Expression: "EXTRACT(MONTH FROM sale_date) AS month"}, {Expression: "SUM(amount) AS total"}, }, From: "sales", Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "sale_date", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(-1, 0, 0)}, }, }, }, GroupBy: []string{"salesperson_id", "EXTRACT(MONTH FROM sale_date)"}, }, }, { Name: "top_salespeople", Query: utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "salesperson_id"}, {Expression: "SUM(total) AS yearly_total"}, }, From: "monthly_sales", GroupBy: []string{"salesperson_id"}, Having: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "SUM(total)", Operator: utils.OpGreaterThan, Value: 10000}, }, }, }, }, }, }, Fields: []utils.SelectField{ {Expression: "salespeople.id"}, {Expression: "salespeople.name"}, {Expression: "top_salespeople.yearly_total"}, }, From: "salespeople", Joins: []utils.Join{ { Type: "INNER", Table: "top_salespeople", Alias: "top_salespeople", OnConditions: utils.FilterGroup{ Filters: []utils.DynamicFilter{ {Column: "salespeople.id", Operator: utils.OpEqual, Value: "top_salespeople.salesperson_id"}, }, }, }, }, Sort: []utils.SortField{ {Column: "top_salespeople.yearly_total", Order: "DESC"}, }, Limit: 10, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing CTE query: %v", err) return } fmt.Printf("Found %d top salespeople\n", len(results)) for _, salesperson := range results { fmt.Printf("Salesperson: %+v\n", salesperson) } } func unionExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== UNION Example ===") // Query dengan UNION query := utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "name"}, {Expression: "email"}, {Expression: "'customer' AS user_type"}, }, From: "customers", Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, }, }, }, Unions: []utils.Union{ { Type: "UNION ALL", Query: utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "id"}, {Expression: "name"}, {Expression: "email"}, {Expression: "'employee' AS user_type"}, }, From: "employees", Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, }, }, }, }, }, }, Sort: []utils.SortField{ {Column: "name", Order: "ASC"}, }, Limit: 20, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing UNION query: %v", err) return } fmt.Printf("Found %d users (customers + employees)\n", len(results)) for _, user := range results { fmt.Printf("User: %+v\n", user) } } func aggregateExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Aggregate Example ===") // Query dengan fungsi agregasi query := utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "category"}, {Expression: "COUNT(*) AS product_count"}, {Expression: "AVG(price) AS avg_price"}, {Expression: "MIN(price) AS min_price"}, {Expression: "MAX(price) AS max_price"}, {Expression: "SUM(stock_quantity) AS total_stock"}, }, From: "products", Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, }, }, }, GroupBy: []string{"category"}, Having: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "COUNT(*)", Operator: utils.OpGreaterThan, Value: 5}, }, }, }, Sort: []utils.SortField{ {Column: "product_count", Order: "DESC"}, }, Limit: 10, } var results []map[string]interface{} err := qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing aggregate query: %v", err) return } fmt.Printf("Found %d product categories\n", len(results)) for _, category := range results { fmt.Printf("Category: %+v\n", category) } } func crudOperationsExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== CRUD Operations Example ===") // INSERT insertData := utils.InsertData{ Columns: []string{"name", "email", "status", "created_at"}, Values: []interface{}{"John Doe", "john@example.com", "active", time.Now()}, JsonValues: map[string]interface{}{ "preferences": map[string]interface{}{ "theme": "dark", "language": "en", }, }, } result, err := qb.ExecuteInsert(context.Background(), db, "customers", insertData, "id") if err != nil { log.Printf("Error executing INSERT: %v", err) return } id, err := result.LastInsertId() if err != nil { log.Printf("Error getting inserted ID: %v", err) return } fmt.Printf("Inserted customer with ID: %d\n", id) // UPDATE updateData := utils.UpdateData{ Columns: []string{"name", "status"}, Values: []interface{}{"John Smith", "inactive"}, JsonUpdates: map[string]utils.JsonUpdate{ "preferences": { Path: "$.theme", Value: "light", }, }, } filters := []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "id", Operator: utils.OpEqual, Value: id}, }, }, } result, err = qb.ExecuteUpdate(context.Background(), db, "customers", updateData, filters, "updated_at") if err != nil { log.Printf("Error executing UPDATE: %v", err) return } rowsAffected, err := result.RowsAffected() if err != nil { log.Printf("Error getting rows affected: %v", err) return } fmt.Printf("Updated %d customer(s)\n", rowsAffected) // DELETE result, err = qb.ExecuteDelete(context.Background(), db, "customers", filters) if err != nil { log.Printf("Error executing DELETE: %v", err) return } rowsAffected, err = result.RowsAffected() if err != nil { log.Printf("Error getting rows affected: %v", err) return } fmt.Printf("Deleted %d customer(s)\n", rowsAffected) } func mongoExample() { fmt.Println("\n=== MongoDB Example ===") // Inisialisasi koneksi MongoDB client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { log.Fatalf("Failed to connect to MongoDB: %v", err) } defer client.Disconnect(context.Background()) db := client.Database("testdb") collection := db.Collection("users") // Inisialisasi MongoQueryBuilder mqb := utils.NewMongoQueryBuilder() // Query sederhana query := utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "name"}, {Expression: "email"}, {Expression: "status"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, {Column: "age", Operator: utils.OpGreaterThan, Value: 18}, }, LogicOp: "AND", }, }, Sort: []utils.SortField{ {Column: "name", Order: "ASC"}, }, Limit: 10, } var results []map[string]interface{} err = mqb.ExecuteFind(context.Background(), collection, query, &results) if err != nil { log.Printf("Error executing MongoDB query: %v", err) return } fmt.Printf("Found %d users\n", len(results)) for _, user := range results { fmt.Printf("User: %+v\n", user) } // Aggregation pipeline aggQuery := utils.DynamicQuery{ Fields: []utils.SelectField{ {Expression: "department", Alias: "_id"}, {Expression: "COUNT(*)", Alias: "employee_count"}, {Expression: "AVG(salary)", Alias: "avg_salary"}, }, Filters: []utils.FilterGroup{ { Filters: []utils.DynamicFilter{ {Column: "status", Operator: utils.OpEqual, Value: "active"}, }, }, }, GroupBy: []string{"department"}, Sort: []utils.SortField{ {Column: "employee_count", Order: "DESC"}, }, Limit: 10, } var aggResults []map[string]interface{} err = mqb.ExecuteAggregate(context.Background(), collection, aggQuery, &aggResults) if err != nil { log.Printf("Error executing MongoDB aggregation: %v", err) return } fmt.Printf("Found %d departments\n", len(aggResults)) for _, dept := range aggResults { fmt.Printf("Department: %+v\n", dept) } } func queryParserExample(db *sqlx.DB, qb *utils.QueryBuilder) { fmt.Println("\n=== Query Parser Example ===") // Inisialisasi QueryParser qp := utils.NewQueryParser() // Parse URL query parameters values := url.Values{} values.Add("fields", "id,name,email,status") values.Add("filter[status][_eq]", "active") values.Add("filter[created_at][_gte]", "2023-01-01") values.Add("filter[age][_between]", "18,65") values.Add("sort", "+name,-created_at") values.Add("limit", "20") values.Add("offset", "10") // Parse query parameters into DynamicQuery query, err := qp.ParseQuery(values, "users") if err != nil { log.Printf("Error parsing query: %v", err) return } // Execute the parsed query var results []map[string]interface{} err = qb.ExecuteQuery(context.Background(), db, query, &results) if err != nil { log.Printf("Error executing parsed query: %v", err) return } fmt.Printf("Found %d users using parsed query\n", len(results)) for _, user := range results { fmt.Printf("User: %+v\n", user) } }