{"id":26455052,"url":"https://github.com/donghquinn/gqbd","last_synced_at":"2026-06-06T15:01:46.796Z","repository":{"id":281619562,"uuid":"945694805","full_name":"donghquinn/gqbd","owner":"donghquinn","description":"go-query-builder","archived":false,"fork":false,"pushed_at":"2026-05-31T03:41:43.000Z","size":108,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-31T05:12:13.143Z","etag":null,"topics":["builder","go","query","querybuilder"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/donghquinn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-10T01:21:42.000Z","updated_at":"2026-05-31T03:41:15.000Z","dependencies_parsed_at":"2025-04-10T06:24:55.391Z","dependency_job_id":"2e3f386e-8642-4f96-9d10-6995c495b23f","html_url":"https://github.com/donghquinn/gqbd","commit_stats":null,"previous_names":["donghquinn/go-query-builder","donghquinn/gqbd"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/donghquinn/gqbd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donghquinn%2Fgqbd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donghquinn%2Fgqbd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donghquinn%2Fgqbd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donghquinn%2Fgqbd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donghquinn","download_url":"https://codeload.github.com/donghquinn/gqbd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donghquinn%2Fgqbd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33986901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builder","go","query","querybuilder"],"created_at":"2025-03-18T20:29:46.943Z","updated_at":"2026-06-06T15:01:46.779Z","avatar_url":"https://github.com/donghquinn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GQBD - High-Performance Go Query Builder\n\n## Introduction\n**GQBD** is a high-performance, zero-allocation SQL query builder for Go, inspired by gdct design principles.\n\n✨ **Key Features:**\n- 🚀 **Zero allocations** in critical query building paths\n- 🔒 **SQL injection safe** with automatic parameter binding and identifier escaping  \n- 🎯 **Multi-database support**: PostgreSQL, MySQL, MariaDB, SQLite\n- ⚡ **Performance optimized** - designed for high-throughput applications\n- 📦 **Zero dependencies** - pure Go implementation\n- 🔧 **Fluent API** - chainable method design for readable code\n\n## Installation\n\n```bash\ngo get github.com/donghquinn/gqbd\n```\n\n## Performance \u0026 Features\n\n🏆 **Performance Benefits:**\n- Zero allocations in query building (similar to gdct)\n- Optimized string building and parameter handling\n- Minimal overhead compared to other query builders\n- Built for high-throughput, low-latency applications\n\n📋 **Full Feature Set:**\n- ✅ **SELECT**: Complex queries with joins, conditions, grouping, ordering\n- ✅ **INSERT**: Bulk inserts with optional RETURNING clause (PostgreSQL)\n- ✅ **UPDATE**: Conditional updates with proper parameter binding\n- ✅ **DELETE**: Safe deletion with WHERE conditions\n- ✅ **Advanced Clauses**: IN, BETWEEN, aggregate functions, DISTINCT\n- ✅ **Security**: Automatic SQL injection prevention\n- ✅ **Cross-Database**: PostgreSQL ($N), MySQL/MariaDB/SQLite (?) placeholder formats\n- ✅ **Connection Strings**: Built-in database connection string generation\n\n## Quick Start\n\nGQBD follows the same patterns as gdct but without database connections. Just build queries and use them with your preferred driver.\n\n```go\n// Simple example - matches gdct API pattern\nquery, args, err := gqbd.BuildSelect(gqbd.PostgreSQL, \"users\").\n    Where(\"age \u003e ?\", 18).\n    OrderBy(\"created_at\", \"DESC\", nil).\n    Limit(10).\n    Build()\n\n// Use with any database driver\nrows, err := db.Query(query, args...)\n```\n\n## Detailed Examples\n\n### PostgreSQL Examples\n\nPostgreSQL uses `$N` parameter placeholders and double quotes for identifiers.\n\n#### SELECT Query\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/donghquinn/gqbd\"\n)\n\nfunc main() {\n    // Basic SELECT with joins and conditions\n    qb := gqbd.BuildSelect(gqbd.PostgreSQL, \"example_table e\", \"e.id\", \"e.name\", \"u.username\").\n        LeftJoin(\"user_table u\", \"u.user_id = e.id\").\n        Where(\"e.status = ?\", \"active\").\n        OrderBy(\"e.created_at\", \"DESC\", nil).\n        Limit(10).\n        Offset(0)\n\n    query, args, err := qb.Build()\n    if err != nil {\n        panic(err)\n    }\n\n    fmt.Printf(\"Query: %s\\n\", query)\n    fmt.Printf(\"Args: %v\\n\", args)\n    \n    // Output:\n    // Query: SELECT \"e\".\"id\", \"e\".\"name\", \"u\".\"username\" FROM \"example_table\" e LEFT JOIN \"user_table\" u ON u.user_id = e.id WHERE e.status = $1 ORDER BY \"e\".\"created_at\" DESC LIMIT $2 OFFSET $3\n    // Args: [active 10 0]\n}\n```\n\n#### Dynamic WHERE Conditions\n\n```go\nfunc buildDynamicQuery(userName, title string, status string) (string, []interface{}, error) {\n    qb := gqbd.BuildSelect(gqbd.PostgreSQL, \"posts p\", \"p.id\", \"p.title\", \"u.username\").\n        LeftJoin(\"users u\", \"u.id = p.user_id\")\n\n    // Add conditions only if values are provided\n    if userName != \"\" {\n        qb = qb.Where(\"u.username ILIKE ?\", \"%\"+userName+\"%\")\n    }\n    \n    if title != \"\" {\n        qb = qb.Where(\"p.title ILIKE ?\", \"%\"+title+\"%\")\n    }\n    \n    // Always add status filter\n    qb = qb.Where(\"p.status = ?\", status)\n\n    return qb.Build()\n}\n```\n\n#### INSERT with RETURNING\n\n```go\ndata := map[string]interface{}{\n    \"name\":    \"John Doe\",\n    \"email\":   \"john@example.com\",\n    \"active\":  true,\n}\n\nqb := gqbd.BuildInsert(gqbd.PostgreSQL, \"users\").\n    Values(data).\n    Returning(\"id, created_at\")\n\nquery, args, err := qb.Build()\n// Query: INSERT INTO \"users\" (\"name\", \"email\", \"active\") VALUES ($1, $2, $3) RETURNING id, created_at\n// Args: [John Doe john@example.com true]\n```\n\n#### UPDATE Query\n\n```go\ndata := map[string]interface{}{\n    \"name\":       \"Jane Doe\",\n    \"updated_at\": \"NOW()\",\n}\n\nqb := gqbd.BuildUpdate(gqbd.PostgreSQL, \"users\").\n    Set(data).\n    Where(\"id = ?\", 123)\n\nquery, args, err := qb.Build()\n// Query: UPDATE \"users\" SET \"name\" = $1, \"updated_at\" = $2 WHERE id = $3\n// Args: [Jane Doe NOW() 123]\n```\n\n### MySQL/MariaDB Examples\n\nMySQL/MariaDB uses `?` parameter placeholders and backticks for identifiers.\n\n#### SELECT Query\n\n```go\nqb := gqbd.BuildSelect(gqbd.MariaDB, \"products\", \"id\", \"name\", \"price\").\n    Where(\"category_id = ?\", 10).\n    Where(\"price BETWEEN ? AND ?\", 100, 500).\n    OrderBy(\"price\", \"ASC\", nil).\n    Limit(20)\n\nquery, args, err := qb.Build()\n// Query: SELECT `id`, `name`, `price` FROM `products` WHERE category_id = ? AND price BETWEEN ? AND ? ORDER BY `price` ASC LIMIT ?\n// Args: [10 100 500 20]\n```\n\n#### INSERT Query\n\n```go\ndata := map[string]interface{}{\n    \"name\":        \"New Product\",\n    \"price\":       99.99,\n    \"category_id\": 5,\n}\n\nqb := gqbd.BuildInsert(gqbd.MariaDB, \"products\").\n    Values(data)\n\nquery, args, err := qb.Build()\n// Query: INSERT INTO `products` (`name`, `price`, `category_id`) VALUES (?, ?, ?)\n// Args: [New Product 99.99 5]\n```\n\n### SQLite Examples\n\nSQLite uses `?` parameter placeholders and double quotes for identifiers, with support for RETURNING clause.\n\n#### SELECT Query\n\n```go\nqb := gqbd.BuildSelect(gqbd.SQLite, \"users\", \"id\", \"name\", \"email\").\n    Where(\"age \u003e ?\", 18).\n    Where(\"status = ?\", \"active\").\n    OrderBy(\"created_at\", \"DESC\", nil).\n    Limit(10).\n    Offset(5)\n\nquery, args, err := qb.Build()\n// Query: SELECT \"id\", \"name\", \"email\" FROM \"users\" WHERE age \u003e ? AND status = ? ORDER BY \"created_at\" DESC LIMIT ? OFFSET ?\n// Args: [18 active 10 5]\n```\n\n#### INSERT with RETURNING\n\n```go\ndata := map[string]interface{}{\n    \"name\":  \"Alice\",\n    \"email\": \"alice@example.com\",\n    \"age\":   28,\n}\n\nqb := gqbd.BuildInsert(gqbd.SQLite, \"users\").\n    Values(data).\n    Returning(\"id, name\")\n\nquery, args, err := qb.Build()\n// Query: INSERT INTO \"users\" (\"name\", \"email\", \"age\") VALUES (?, ?, ?) RETURNING id, name\n// Args: [Alice alice@example.com 28]\n```\n\n#### UPDATE Query\n\n```go\nqb := gqbd.BuildUpdate(gqbd.SQLite, \"users\").\n    Set(map[string]interface{}{\n        \"name\":   \"Updated Name\",\n        \"status\": \"inactive\",\n    }).\n    Where(\"id = ?\", 1)\n\nquery, args, err := qb.Build()\n// Query: UPDATE \"users\" SET \"name\" = ?, \"status\" = ? WHERE id = ?\n// Args: [Updated Name inactive 1]\n```\n\n## Database Connection Strings\n\nGQBD includes built-in support for generating database connection strings for use with `sql.Open()`.\n\n### Connection String Generation\n\n```go\nimport \"github.com/donghquinn/gqbd\"\n\n// PostgreSQL connection string\npgConfig := gqbd.DBConfig{\n    Host:     \"localhost\",\n    Port:     5432,\n    User:     \"postgres\",\n    Password: \"postgres\",\n    DBName:   \"myapp\",\n    SSLMode:  \"disable\",\n}\npgDSN := gqbd.BuildConnectionString(gqbd.PostgreSQL, pgConfig)\n// Result: \"host=localhost port=5432 user=postgres password=postgres dbname=myapp sslmode=disable\"\n\n// MySQL connection string\nmysqlConfig := gqbd.DBConfig{\n    Host:     \"localhost\",\n    Port:     3306,\n    User:     \"root\",\n    Password: \"password\",\n    DBName:   \"myapp\",\n    Charset:  \"utf8mb4\",\n}\nmysqlDSN := gqbd.BuildConnectionString(gqbd.Mysql, mysqlConfig)\n// Result: \"root:password@tcp(localhost:3306)/myapp?charset=utf8mb4\u0026parseTime=True\u0026loc=Local\"\n\n// SQLite connection strings\nsqliteConfig := gqbd.DBConfig{\n    FilePath: \"/path/to/database.db\",\n}\nsqliteDSN := gqbd.BuildConnectionString(gqbd.SQLite, sqliteConfig)\n// Result: \"/path/to/database.db\"\n\n// SQLite in-memory\nsqliteMemConfig := gqbd.DBConfig{} // Empty config\nsqliteMemDSN := gqbd.BuildConnectionString(gqbd.SQLite, sqliteMemConfig)\n// Result: \":memory:\"\n```\n\n### Complete Database Setup Example\n\n```go\npackage main\n\nimport (\n    \"database/sql\"\n    \"fmt\"\n    \"log\"\n    \n    _ \"github.com/lib/pq\"           // PostgreSQL driver\n    _ \"github.com/go-sql-driver/mysql\" // MySQL driver  \n    _ \"github.com/mattn/go-sqlite3\"    // SQLite driver\n    \"github.com/donghquinn/gqbd\"\n)\n\nfunc main() {\n    // Configure database connection\n    config := gqbd.DBConfig{\n        Host:     \"localhost\",\n        Port:     5432,\n        User:     \"postgres\",\n        Password: \"password\",\n        DBName:   \"myapp\",\n        SSLMode:  \"disable\",\n    }\n    \n    // Generate connection string\n    dsn := gqbd.BuildConnectionString(gqbd.PostgreSQL, config)\n    \n    // Open database connection\n    db, err := sql.Open(\"postgres\", dsn)\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer db.Close()\n    \n    // Build and execute query\n    qb := gqbd.BuildSelect(gqbd.PostgreSQL, \"users\", \"id\", \"name\", \"email\").\n        Where(\"status = ?\", \"active\").\n        OrderBy(\"name\", \"ASC\", nil).\n        Limit(10)\n    \n    query, args, err := qb.Build()\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    rows, err := db.Query(query, args...)\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer rows.Close()\n    \n    // Process results...\n    for rows.Next() {\n        var id int\n        var name, email string\n        if err := rows.Scan(\u0026id, \u0026name, \u0026email); err != nil {\n            log.Fatal(err)\n        }\n        fmt.Printf(\"ID: %d, Name: %s, Email: %s\\n\", id, name, email)\n    }\n}\n```\n\n### Advanced Features\n\n#### IN Clause\n\n```go\nqb := gqbd.BuildSelect(gqbd.PostgreSQL, \"users\", \"id\", \"name\").\n    WhereIn(\"status\", []interface{}{\"active\", \"pending\", \"verified\"})\n\nquery, args, err := qb.Build()\n// Query: SELECT \"id\", \"name\" FROM \"users\" WHERE \"status\" IN ($1, $2, $3)\n// Args: [active pending verified]\n```\n\n#### BETWEEN Clause\n\n```go\nqb := gqbd.BuildSelect(gqbd.PostgreSQL, \"orders\", \"id\", \"total\").\n    WhereBetween(\"created_at\", \"2023-01-01\", \"2023-12-31\")\n\nquery, args, err := qb.Build()\n// Query: SELECT \"id\", \"total\" FROM \"orders\" WHERE \"created_at\" BETWEEN $1 AND $2\n// Args: [2023-01-01 2023-12-31]\n```\n\n#### Aggregate Functions\n\n```go\nqb := gqbd.BuildSelect(gqbd.PostgreSQL, \"orders\", \"customer_id\").\n    Aggregate(\"COUNT\", \"*\").\n    Aggregate(\"SUM\", \"total\").\n    GroupBy(\"customer_id\").\n    Having(\"COUNT(*) \u003e ?\", 5)\n\nquery, args, err := qb.Build()\n// Query: SELECT \"customer_id\", COUNT(\"*\"), SUM(\"total\") FROM \"orders\" GROUP BY \"customer_id\" HAVING COUNT(*) \u003e $1\n```\n\n## Database Driver Integration\n\nGQBD works with any Go database driver. Here are the recommended drivers for each database type:\n\n### PostgreSQL\n```go\nimport _ \"github.com/lib/pq\"              // Most common\n// OR\nimport _ \"github.com/jackc/pgx/v5/stdlib\" // High performance\n```\n\n### MySQL\n```go\nimport _ \"github.com/go-sql-driver/mysql\"\n```\n\n### SQLite\n```go\nimport _ \"github.com/mattn/go-sqlite3\"\n```\n\n### Example Usage with Drivers\n\n```go\n// PostgreSQL example\nfunc queryPostgreSQL() {\n    config := gqbd.DBConfig{\n        Host: \"localhost\", Port: 5432, User: \"postgres\",\n        Password: \"password\", DBName: \"myapp\", SSLMode: \"disable\",\n    }\n    dsn := gqbd.BuildConnectionString(gqbd.PostgreSQL, config)\n    db, _ := sql.Open(\"postgres\", dsn)\n    \n    qb := gqbd.BuildSelect(gqbd.PostgreSQL, \"users\", \"id\", \"name\")\n    query, args, _ := qb.Where(\"active = ?\", true).Build()\n    rows, _ := db.Query(query, args...)\n    defer rows.Close()\n}\n\n// MySQL example  \nfunc queryMySQL() {\n    config := gqbd.DBConfig{\n        Host: \"localhost\", Port: 3306, User: \"root\",\n        Password: \"password\", DBName: \"myapp\", Charset: \"utf8mb4\",\n    }\n    dsn := gqbd.BuildConnectionString(gqbd.Mysql, config)\n    db, _ := sql.Open(\"mysql\", dsn)\n    \n    qb := gqbd.BuildSelect(gqbd.Mysql, \"users\", \"id\", \"name\")\n    query, args, _ := qb.Where(\"active = ?\", true).Build()\n    rows, _ := db.Query(query, args...)\n    defer rows.Close()\n}\n\n// SQLite example\nfunc querySQLite() {\n    config := gqbd.DBConfig{FilePath: \"./app.db\"}\n    dsn := gqbd.BuildConnectionString(gqbd.SQLite, config)\n    db, _ := sql.Open(\"sqlite3\", dsn)\n    \n    qb := gqbd.BuildSelect(gqbd.SQLite, \"users\", \"id\", \"name\")\n    query, args, _ := qb.Where(\"active = ?\", true).Build()\n    rows, _ := db.Query(query, args...)\n    defer rows.Close()\n}\n```\n\n## Supported Database Types\n\n| Database | Constant | Placeholders | Identifiers | RETURNING Support |\n|----------|----------|--------------|-------------|-------------------|\n| PostgreSQL | `gqbd.PostgreSQL` | `$1, $2, $3...` | `\"identifier\"` | ✅ Yes |\n| MySQL | `gqbd.Mysql` | `?, ?, ?...` | `` `identifier` `` | ❌ No |\n| MariaDB | `gqbd.MariaDB` | `?, ?, ?...` | `` `identifier` `` | ❌ No |\n| SQLite | `gqbd.SQLite` | `?, ?, ?...` | `\"identifier\"` | ✅ Yes (3.35.0+) |\n\n## Performance Comparison\n\nGQBD is designed with the same performance principles as gdct:\n\n```go\n// Benchmark example - zero allocations in hot path\nfunc BenchmarkQueryBuilder(b *testing.B) {\n    for i := 0; i \u003c b.N; i++ {\n        query, args, _ := gqbd.BuildSelect(gqbd.PostgreSQL, \"users\", \"id\", \"name\").\n            Where(\"active = ?\", true).\n            Where(\"age \u003e ?\", 21).\n            OrderBy(\"created_at\", \"DESC\", nil).\n            Limit(100).\n            Build()\n        _ = query\n        _ = args\n    }\n}\n```\n\n## Why Choose GQBD?\n\n🎯 **Same design philosophy as gdct**:\n- Zero allocations in critical paths\n- SQL injection prevention by design\n- Cross-database compatibility\n- Pure query building (no database connections)\n\n🚀 **Performance focused**:\n- Minimal overhead\n- Optimized for high-throughput applications\n- Memory efficient\n\n🔒 **Security first**:\n- Automatic parameter binding\n- Identifier escaping\n- Input validation\n\n📋 **Complete solution**:\n- Query building for all major databases\n- Connection string generation\n- Database-specific optimizations\n- Modular, maintainable code structure\n\n## Project Structure\n\nThe codebase is organized for maintainability and database-specific optimizations:\n\n- `gqbd.go` - Main API, shared logic, and database selection\n- `postgres.go` - PostgreSQL-specific query building methods\n- `mariadb.go` - MySQL/MariaDB-specific query building methods  \n- `sqlite.go` - SQLite-specific query building methods\n\nThis separation allows for:\n- Database-specific optimizations\n- Clean, maintainable code\n- Easy addition of new database types\n- Consistent API across all databases\n\n## Contributing\n\nFeel free to open issues or submit pull requests. All major SQL databases are now supported!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonghquinn%2Fgqbd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonghquinn%2Fgqbd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonghquinn%2Fgqbd/lists"}