{"id":50506167,"url":"https://github.com/pardnchiu/go-pg","last_synced_at":"2026-06-02T16:03:17.562Z","repository":{"id":332668611,"uuid":"1074702616","full_name":"pardnchiu/go-pg","owner":"pardnchiu","description":"(Go Package) PostgreSQL client with chained method calls","archived":false,"fork":false,"pushed_at":"2025-10-12T10:13:16.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-15T04:56:34.917Z","etag":null,"topics":["backend","chain-syntax","go","golang","pardnchiu","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pardnchiu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-10-12T10:10:37.000Z","updated_at":"2025-12-05T06:09:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pardnchiu/go-pg","commit_stats":null,"previous_names":["pardnchiu/go-pg"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pardnchiu/go-pg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pardnchiu%2Fgo-pg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pardnchiu%2Fgo-pg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pardnchiu%2Fgo-pg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pardnchiu%2Fgo-pg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pardnchiu","download_url":"https://codeload.github.com/pardnchiu/go-pg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pardnchiu%2Fgo-pg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33829346,"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-02T02:00:07.132Z","response_time":109,"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":["backend","chain-syntax","go","golang","pardnchiu","postgresql"],"created_at":"2026-06-02T16:03:16.612Z","updated_at":"2026-06-02T16:03:17.553Z","avatar_url":"https://github.com/pardnchiu.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostgreSQL Pool\n\n\u003e Golang PostgreSQL wrapper supporting chain calls, read-write separation, query builder, and complete connection management.\n\u003e\n\u003e MySQL version [here](https://github.com/pardnchiu/go-mysql)\n\n[![pkg](https://pkg.go.dev/badge/github.com/pardnchiu/go-pg.svg)](https://pkg.go.dev/github.com/pardnchiu/go-pg)\n[![license](https://img.shields.io/github/license/pardnchiu/go-pg)](LICENSE)\n[![version](https://img.shields.io/github/v/tag/pardnchiu/go-pg)](https://github.com/pardnchiu/go-pg/releases)\n![card](https://goreportcard.com/badge/github.com/pardnchiu/go-pg)\n\n## Key Features\n\n### Read-Write Separation\nSupport read-write connection pool configuration, enabling pre-connections to improve efficiency.\n\n### Query Builder\nProvide a chainable SQL query builder interface to prevent SQL injection attacks.\n\n### CRUD Operations\nComplete support for create, read, update, and delete operations.\n\n### PostgreSQL-Specific Features\n- Support for schemas\n- ILIKE operator for case-insensitive pattern matching\n- ON CONFLICT for upsert operations\n- RETURNING clause for insert/update operations\n\n## Dependencies\n\n- [`github.com/lib/pq`](https://github.com/lib/pq)\n- [`github.com/joho/godotenv`](https://github.com/joho/godotenv)\n\n## Installation\n\n```bash\ngo get github.com/pardnchiu/go-pg\n```\n\n## Environment Variables\n\n```env\n# default 127.0.0.1\nPG_READ_HOST=\n# default 5432\nPG_READ_PORT=\n# default postgres\nPG_READ_USER=\n# default empty\nPG_READ_PASSWORD=\n# default postgres\nPG_READ_DATABASE=\n# default disable\nPG_READ_SSLMODE=\n# default 4\nPG_READ_CONNECTION=\n\n# * default is read\nPG_WRITE_HOST=\nPG_WRITE_PORT=\nPG_WRITE_USER=\nPG_WRITE_PASSWORD=\nPG_WRITE_DATABASE=\nPG_WRITE_SSLMODE=\nPG_WRITE_CONNECTION=\n```\n\n## Configuration\n\n### Method 1: Using Config Struct\n\n```go\nconfig := goPg.Config{\n    Read: \u0026goPg.DBConfig{\n        Host:       \"localhost\",\n        Port:       5432,\n        User:       \"postgres\",\n        Password:   \"password\",\n        Database:   \"myapp\",\n        SSLMode:    \"disable\",\n        Connection: 10,\n    },\n    Write: \u0026goPg.DBConfig{\n        Host:       \"localhost\",\n        Port:       5432,\n        User:       \"postgres\",\n        Password:   \"password\",\n        Database:   \"myapp\",\n        SSLMode:    \"disable\",\n        Connection: 5,\n    },\n}\n\npool, err := goPg.New(config)\n```\n\n### Method 2: Using Environment Variables\n\n```go\npool, err := goPg.New()\n```\n\n## Query Operations\n\n### Basic Query\n\n```go\nrows, err := pool.Read.\n    Schema(\"public\").\n    Table(\"users\").\n    Select(\"id\", \"name\", \"email\").\n    Where(\"status\", \"active\").\n    Get()\n\ndefer rows.Close()\nfor rows.Next() {\n    var id int\n    var name, email string\n    rows.Scan(\u0026id, \u0026name, \u0026email)\n}\n```\n\n### Complex Conditions\n\n```go\nrows, err := pool.Read.\n    Schema(\"public\").\n    Table(\"users\").\n    Select(\"*\").\n    Where(\"age\", \"\u003e\", 18).\n    Where(\"status\", \"active\").\n    Where(\"name\", \"ILIKE\", \"john\").  // Case-insensitive\n    OrderBy(\"created_at\", \"DESC\").\n    Limit(10).\n    Offset(20).\n    Get()\n```\n\n### JOIN Query\n\n```go\nrows, err := pool.Read.\n    Schema(\"public\").\n    Table(\"users\").\n    Select(\"users.name\", \"profiles.bio\").\n    LeftJoin(\"profiles\", \"users.id\", \"profiles.user_id\").\n    Where(\"users.status\", \"active\").\n    Get()\n```\n\n### Query with Total Count\n\n```go\nrows, err := pool.Read.\n    Schema(\"public\").\n    Table(\"users\").\n    Select(\"id\", \"name\").\n    Where(\"status\", \"active\").\n    Total().\n    Limit(10).\n    Get()\n\nfor rows.Next() {\n    var total, id int\n    var name string\n    rows.Scan(\u0026total, \u0026id, \u0026name)\n}\n```\n\n## Insert Operations\n\n### Basic Insert\n\n```go\ndata := map[string]interface{}{\n    \"name\":  \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"age\":   25,\n}\n\nlastID, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Insert(data)\n```\n\n## Update Operations\n\n### Basic Update\n\n```go\nupdateData := map[string]interface{}{\n    \"age\":    26,\n    \"status\": \"updated\",\n}\n\nresult, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Where(\"id\", 1).\n    Update(updateData)\n\nrowsAffected, _ := result.RowsAffected()\n```\n\n### Using PostgreSQL Functions\n\n```go\nupdateData := map[string]interface{}{\n    \"updated_at\": \"NOW()\",\n    \"last_login\": \"CURRENT_TIMESTAMP\",\n}\n\nresult, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Where(\"id\", 1).\n    Update(updateData)\n```\n\n### Increase Values\n\n```go\nresult, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Where(\"id\", 1).\n    Increase(\"view_count\", 1).\n    Update()\n```\n\n## Upsert Operations\n\n### Basic Upsert\n\n```go\ndata := map[string]interface{}{\n    \"email\": \"unique@example.com\",\n    \"name\":  \"New User\",\n    \"age\":   30,\n}\n\n// Update all fields on conflict\nlastID, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Upsert(data, []string{\"email\"})\n```\n\n### Upsert with Specific Update Fields\n\n```go\ndata := map[string]interface{}{\n    \"email\": \"unique@example.com\",\n    \"name\":  \"New User\",\n}\n\nupdateData := map[string]interface{}{\n    \"name\": \"Updated User\",\n    \"last_login\": \"NOW()\",\n}\n\nlastID, err := pool.Write.\n    Schema(\"public\").\n    Table(\"users\").\n    Upsert(data, []string{\"email\"}, updateData)\n```\n\n## Direct SQL Execution\n\n### Query\n\n```go\nrows, err := pool.Read.Query(\n    \"SELECT * FROM users WHERE age \u003e $1 AND status = $2\",\n    18,\n    \"active\",\n)\n```\n\n### Execute\n\n```go\nresult, err := pool.Write.Exec(\n    \"UPDATE users SET status = $1 WHERE age \u003e $2\",\n    \"senior\",\n    35,\n)\n```\n\n## Supported PostgreSQL Functions\n\n- `NOW()`\n- `CURRENT_TIMESTAMP`\n- `CURRENT_DATE`\n- `CURRENT_TIME`\n- `LOCALTIMESTAMP`\n- `LOCALTIME`\n- `TRANSACTION_TIMESTAMP()`\n- `STATEMENT_TIMESTAMP()`\n- `CLOCK_TIMESTAMP()`\n- `GEN_RANDOM_UUID()`\n- `RANDOM()`\n- And more...\n\n## Connection Pool Management\n\n```go\ndefer pool.Close()\n```\n\nThe package automatically listens for `SIGINT` and `SIGTERM` signals for graceful shutdown.\n\n## Slow Query Logging\n\nQueries taking longer than 20ms are automatically logged.\n\n## Complete Example\n\n```go\npackage main\n\nimport (\n    \"log\"\n    goPg \"github.com/pardnchiu/go-pg\"\n)\n\nfunc main() {\n    pool, err := goPg.New()\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer pool.Close()\n\n    // Insert\n    data := map[string]interface{}{\n        \"name\":  \"John Doe\",\n        \"email\": \"john@example.com\",\n        \"age\":   30,\n    }\n    lastID, _ := pool.Write.Schema(\"public\").Table(\"users\").Insert(data)\n\n    // Query\n    rows, _ := pool.Read.\n        Schema(\"public\").\n        Table(\"users\").\n        Select(\"id\", \"name\", \"email\").\n        Where(\"age\", \"\u003e\", 18).\n        OrderBy(\"created_at\", \"DESC\").\n        Limit(10).\n        Get()\n    defer rows.Close()\n\n    for rows.Next() {\n        var id int\n        var name, email string\n        rows.Scan(\u0026id, \u0026name, \u0026email)\n        log.Printf(\"User: %s (%s)\\n\", name, email)\n    }\n\n    // Update\n    updateData := map[string]interface{}{\n        \"age\": 31,\n    }\n    pool.Write.Schema(\"public\").Table(\"users\").Where(\"id\", lastID).Update(updateData)\n}\n```\n\n## License\n\nThis project is licensed under the [MIT](LICENSE) license.\n\n## Author\n\n\u003cimg src=\"https://avatars.githubusercontent.com/u/25631760\" align=\"left\" width=\"96\" height=\"96\" style=\"margin-right: 0.5rem;\"\u003e\n\n\u003ch4 style=\"padding-top: 0\"\u003e邱敬幃 Pardn Chiu\u003c/h4\u003e\n\n\u003ca href=\"mailto:dev@pardn.io\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://pardn.io/image/email.svg\" width=\"48\" height=\"48\"\u003e\n\u003c/a\u003e \u003ca href=\"https://linkedin.com/in/pardnchiu\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://pardn.io/image/linkedin.svg\" width=\"48\" height=\"48\"\u003e\n\u003c/a\u003e\n\n***\n\n©️ 2025 [邱敬幃 Pardn Chiu](https://pardn.io)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpardnchiu%2Fgo-pg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpardnchiu%2Fgo-pg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpardnchiu%2Fgo-pg/lists"}