221 lines
7.3 KiB
Go
221 lines
7.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/url"
|
|
|
|
"your_module_path/utils" // Ganti dengan path modul Anda
|
|
)
|
|
|
|
func main() {
|
|
// --- 1. Setup QueryBuilder ---
|
|
// Kita akan menggunakan PostgreSQL untuk contoh ini.
|
|
// Untuk database lain, cukup ganti DBTypePostgreSQL menjadi DBTypeMySQL, dll.
|
|
qb := utils.NewQueryBuilder("users", utils.DBTypePostgreSQL).
|
|
SetColumnMapping(map[string]string{
|
|
// API Field -> DB Column
|
|
"userId": "id",
|
|
"username": "user_name",
|
|
"email": "email_address",
|
|
"isActive": "is_active",
|
|
"createdAt": "created_at",
|
|
}).
|
|
SetAllowedColumns([]string{
|
|
"id", "user_name", "email_address", "is_active", "created_at", "updated_at",
|
|
})
|
|
|
|
fmt.Println("=== QUERY BUILDER EXAMPLES ===\n")
|
|
|
|
// --- 2. CREATE (INSERT) ---
|
|
fmt.Println("--- CREATE (INSERT) ---")
|
|
|
|
// Contoh data user baru
|
|
newUser := utils.InsertData{
|
|
Columns: []string{"username", "email", "is_active"},
|
|
Values: []interface{}{"john_doe", "[email protected]", true},
|
|
}
|
|
|
|
// Build INSERT query
|
|
sql, args, err := qb.BuildInsertQuery(newUser, "id", "created_at")
|
|
if err != nil {
|
|
log.Fatalf("Failed to build INSERT query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: INSERT INTO users (user_name, email_address, is_active) VALUES ($1, $2, $3) RETURNING id, created_at
|
|
// Args: [john_doe [email protected] true]
|
|
|
|
// --- 3. UPDATE ---
|
|
fmt.Println("--- UPDATE ---")
|
|
|
|
// Data yang akan diupdate untuk user dengan ID 1
|
|
updateData := utils.UpdateData{
|
|
Columns: []string{"username", "is_active"},
|
|
Values: []interface{}{"john_doe_updated", false},
|
|
}
|
|
|
|
// Filter untuk menentukan user mana yang akan diupdate
|
|
filters := []utils.FilterGroup{{
|
|
Filters: []utils.DynamicFilter{{
|
|
Column: "userId",
|
|
Operator: utils.OpEqual,
|
|
Value: 1,
|
|
}},
|
|
}}
|
|
|
|
// Build UPDATE query
|
|
sql, args, err = qb.BuildUpdateQuery(updateData, filters, "updated_at")
|
|
if err != nil {
|
|
log.Fatalf("Failed to build UPDATE query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: UPDATE "users" SET "user_name" = $1, "is_active" = $2 WHERE ("id" = $3) RETURNING updated_at
|
|
// Args: [john_doe_updated false 1]
|
|
|
|
// --- 4. DELETE ---
|
|
fmt.Println("--- DELETE ---")
|
|
|
|
// Filter untuk menghapus user yang tidak aktif
|
|
deleteFilters := []utils.FilterGroup{{
|
|
Filters: []utils.DynamicFilter{{
|
|
Column: "isActive",
|
|
Operator: utils.OpEqual,
|
|
Value: false,
|
|
}},
|
|
}}
|
|
|
|
// Build DELETE query
|
|
sql, args, err = qb.BuildDeleteQuery(deleteFilters, "id")
|
|
if err != nil {
|
|
log.Fatalf("Failed to build DELETE query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: DELETE FROM "users" WHERE ("is_active" = $1) RETURNING id
|
|
// Args: [false]
|
|
|
|
// --- 5. UPSERT (INSERT ... ON CONFLICT) ---
|
|
fmt.Println("--- UPSERT ---")
|
|
|
|
// Data untuk upsert (insert atau update jika sudah ada)
|
|
upsertData := utils.InsertData{
|
|
Columns: []string{"id", "username", "email"},
|
|
Values: []interface{}{1, "unique_user", "[email protected]"}, // ID 1 mungkin sudah ada
|
|
}
|
|
|
|
// Kolom yang menjadi penentu konflik (misalnya, primary key atau unique key)
|
|
conflictColumns := []string{"id"}
|
|
|
|
// Data yang akan diupdate jika terjadi konflik
|
|
upsertUpdateData := utils.UpdateData{
|
|
Columns: []string{"username", "email"},
|
|
Values: []interface{}{"unique_user_updated", "[email protected]"},
|
|
}
|
|
|
|
// Build UPSERT query
|
|
sql, args, err = qb.BuildUpsertQuery(upsertData, conflictColumns, upsertUpdateData, "updated_at")
|
|
if err != nil {
|
|
log.Fatalf("Failed to build UPSERT query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: INSERT INTO users (id, user_name, email_address) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET "user_name" = EXCLUDED.user_name, "email_address" = EXCLUDED.email_address RETURNING updated_at
|
|
// Args: [1 unique_user [email protected] unique_user_updated [email protected]]
|
|
|
|
// --- 6. SELECT dengan JOIN ---
|
|
fmt.Println("--- SELECT with JOIN ---")
|
|
|
|
// Reset builder untuk query baru
|
|
qbJoin := utils.NewQueryBuilder("users", utils.DBTypePostgreSQL).
|
|
SetColumnMapping(map[string]string{"userId": "id", "username": "user_name"}).
|
|
SetAllowedColumns([]string{"id", "user_name", "profile_id"}).
|
|
Join("INNER", "profiles", "users.id = profiles.user_id") // Tambahkan JOIN
|
|
|
|
// Query untuk mendapatkan user dan profilnya
|
|
joinQuery := utils.DynamicQuery{
|
|
Fields: []string{"users.id", "user_name", "profiles.bio"},
|
|
Filters: []utils.FilterGroup{{
|
|
Filters: []utils.DynamicFilter{{
|
|
Column: "isActive",
|
|
Operator: utils.OpEqual,
|
|
Value: true,
|
|
}},
|
|
}},
|
|
Limit: 10,
|
|
}
|
|
|
|
sql, args, err = qbJoin.BuildQuery(joinQuery)
|
|
if err != nil {
|
|
log.Fatalf("Failed to build JOIN query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: SELECT "users"."id", "user_name", "profiles"."bio" FROM "users" INNER JOIN "profiles" ON users.id = profiles.user_id WHERE ("is_active" = $1) LIMIT 10
|
|
// Args: [true]
|
|
|
|
// --- 7. SELECT dengan UNION ---
|
|
fmt.Println("--- SELECT with UNION ---")
|
|
|
|
// Buat dua query builder untuk dua tabel berbeda
|
|
qbActive := utils.NewQueryBuilder("users", utils.DBTypePostgreSQL)
|
|
qbArchived := utils.NewQueryBuilder("archived_users", utils.DBTypePostgreSQL)
|
|
|
|
// Query pertama: user aktif dari tabel 'users'
|
|
query1 := qbActive.sqlBuilder.Select("id", "user_name", "'active' as status").Where("is_active = ?", true)
|
|
|
|
// Query kedua: user aktif dari tabel 'archived_users'
|
|
query2 := qbArchived.sqlBuilder.Select("id", "user_name", "'archived' as status").Where("is_active = ?", true)
|
|
|
|
// Gabungkan dengan UNION
|
|
unionQuery := query1.Union(query2)
|
|
|
|
sql, args, err = unionQuery.ToSql()
|
|
if err != nil {
|
|
log.Fatalf("Failed to build UNION query: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: SELECT id, user_name, 'active' as status FROM users WHERE is_active = $1 UNION SELECT id, user_name, 'archived' as status FROM archived_users WHERE is_active = $2
|
|
// Args: [true true]
|
|
|
|
// --- 8. Integrasi dengan QueryParser (Web Context) ---
|
|
fmt.Println("--- Integration with QueryParser ---")
|
|
|
|
// Simulasi query parameter dari URL: /users?fields=id,username&filter[username][_contains]=john&sort=-createdAt&limit=5
|
|
mockURLValues := url.Values{
|
|
"fields": []string{"id", "username"},
|
|
"filter[username][_contains]": []string{"john"},
|
|
"sort": []string{"-createdAt"},
|
|
"limit": []string{"5"},
|
|
}
|
|
|
|
parser := utils.NewQueryParser()
|
|
dynamicQuery, err := parser.ParseQuery(mockURLValues)
|
|
if err != nil {
|
|
log.Fatalf("Failed to parse query: %v", err)
|
|
}
|
|
|
|
// Build query dari hasil parsing
|
|
qbParser := utils.NewQueryBuilder("users", utils.DBTypePostgreSQL).
|
|
SetColumnMapping(map[string]string{"username": "user_name", "createdAt": "created_at"}).
|
|
SetAllowedColumns([]string{"id", "user_name", "created_at"})
|
|
|
|
sql, args, err = qbParser.BuildQuery(dynamicQuery)
|
|
if err != nil {
|
|
log.Fatalf("Failed to build query from parser: %v", err)
|
|
}
|
|
fmt.Printf("SQL: %s\n", sql)
|
|
fmt.Printf("Args: %v\n\n", args)
|
|
// Output (PostgreSQL):
|
|
// SQL: SELECT "id", "user_name" FROM "users" WHERE ("user_name" ILIKE $1) ORDER BY "created_at" DESC LIMIT 5
|
|
// Args: [%john%]
|
|
}
|