Files
antrean-anjungan/internal/utils/query/example.go
T
rachmadiyanti.annisa.3004 3a53de2ae1
Go-test / build (push) Has been cancelled
Initial commit
2025-12-01 09:15:48 +07:00

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%]
}