Thanks to visit codestin.com
Credit goes to github.com

Skip to content

pardnchiu/go-pg

Repository files navigation

PostgreSQL Pool

Golang PostgreSQL wrapper supporting chain calls, read-write separation, query builder, and complete connection management.

MySQL version here

pkg license version card

Key Features

Read-Write Separation

Support read-write connection pool configuration, enabling pre-connections to improve efficiency.

Query Builder

Provide a chainable SQL query builder interface to prevent SQL injection attacks.

CRUD Operations

Complete support for create, read, update, and delete operations.

PostgreSQL-Specific Features

  • Support for schemas
  • ILIKE operator for case-insensitive pattern matching
  • ON CONFLICT for upsert operations
  • RETURNING clause for insert/update operations

Dependencies

Installation

go get github.com/pardnchiu/go-pg

Environment Variables

# default 127.0.0.1
PG_READ_HOST=
# default 5432
PG_READ_PORT=
# default postgres
PG_READ_USER=
# default empty
PG_READ_PASSWORD=
# default postgres
PG_READ_DATABASE=
# default disable
PG_READ_SSLMODE=
# default 4
PG_READ_CONNECTION=

# * default is read
PG_WRITE_HOST=
PG_WRITE_PORT=
PG_WRITE_USER=
PG_WRITE_PASSWORD=
PG_WRITE_DATABASE=
PG_WRITE_SSLMODE=
PG_WRITE_CONNECTION=

Configuration

Method 1: Using Config Struct

config := goPg.Config{
    Read: &goPg.DBConfig{
        Host:       "localhost",
        Port:       5432,
        User:       "postgres",
        Password:   "password",
        Database:   "myapp",
        SSLMode:    "disable",
        Connection: 10,
    },
    Write: &goPg.DBConfig{
        Host:       "localhost",
        Port:       5432,
        User:       "postgres",
        Password:   "password",
        Database:   "myapp",
        SSLMode:    "disable",
        Connection: 5,
    },
}

pool, err := goPg.New(config)

Method 2: Using Environment Variables

pool, err := goPg.New()

Query Operations

Basic Query

rows, err := pool.Read.
    Schema("public").
    Table("users").
    Select("id", "name", "email").
    Where("status", "active").
    Get()

defer rows.Close()
for rows.Next() {
    var id int
    var name, email string
    rows.Scan(&id, &name, &email)
}

Complex Conditions

rows, err := pool.Read.
    Schema("public").
    Table("users").
    Select("*").
    Where("age", ">", 18).
    Where("status", "active").
    Where("name", "ILIKE", "john").  // Case-insensitive
    OrderBy("created_at", "DESC").
    Limit(10).
    Offset(20).
    Get()

JOIN Query

rows, err := pool.Read.
    Schema("public").
    Table("users").
    Select("users.name", "profiles.bio").
    LeftJoin("profiles", "users.id", "profiles.user_id").
    Where("users.status", "active").
    Get()

Query with Total Count

rows, err := pool.Read.
    Schema("public").
    Table("users").
    Select("id", "name").
    Where("status", "active").
    Total().
    Limit(10).
    Get()

for rows.Next() {
    var total, id int
    var name string
    rows.Scan(&total, &id, &name)
}

Insert Operations

Basic Insert

data := map[string]interface{}{
    "name":  "Jane Doe",
    "email": "[email protected]",
    "age":   25,
}

lastID, err := pool.Write.
    Schema("public").
    Table("users").
    Insert(data)

Update Operations

Basic Update

updateData := map[string]interface{}{
    "age":    26,
    "status": "updated",
}

result, err := pool.Write.
    Schema("public").
    Table("users").
    Where("id", 1).
    Update(updateData)

rowsAffected, _ := result.RowsAffected()

Using PostgreSQL Functions

updateData := map[string]interface{}{
    "updated_at": "NOW()",
    "last_login": "CURRENT_TIMESTAMP",
}

result, err := pool.Write.
    Schema("public").
    Table("users").
    Where("id", 1).
    Update(updateData)

Increase Values

result, err := pool.Write.
    Schema("public").
    Table("users").
    Where("id", 1).
    Increase("view_count", 1).
    Update()

Upsert Operations

Basic Upsert

data := map[string]interface{}{
    "email": "[email protected]",
    "name":  "New User",
    "age":   30,
}

// Update all fields on conflict
lastID, err := pool.Write.
    Schema("public").
    Table("users").
    Upsert(data, []string{"email"})

Upsert with Specific Update Fields

data := map[string]interface{}{
    "email": "[email protected]",
    "name":  "New User",
}

updateData := map[string]interface{}{
    "name": "Updated User",
    "last_login": "NOW()",
}

lastID, err := pool.Write.
    Schema("public").
    Table("users").
    Upsert(data, []string{"email"}, updateData)

Direct SQL Execution

Query

rows, err := pool.Read.Query(
    "SELECT * FROM users WHERE age > $1 AND status = $2",
    18,
    "active",
)

Execute

result, err := pool.Write.Exec(
    "UPDATE users SET status = $1 WHERE age > $2",
    "senior",
    35,
)

Supported PostgreSQL Functions

  • NOW()
  • CURRENT_TIMESTAMP
  • CURRENT_DATE
  • CURRENT_TIME
  • LOCALTIMESTAMP
  • LOCALTIME
  • TRANSACTION_TIMESTAMP()
  • STATEMENT_TIMESTAMP()
  • CLOCK_TIMESTAMP()
  • GEN_RANDOM_UUID()
  • RANDOM()
  • And more...

Connection Pool Management

defer pool.Close()

The package automatically listens for SIGINT and SIGTERM signals for graceful shutdown.

Slow Query Logging

Queries taking longer than 20ms are automatically logged.

Complete Example

package main

import (
    "log"
    goPg "github.com/pardnchiu/go-pg"
)

func main() {
    pool, err := goPg.New()
    if err != nil {
        log.Fatal(err)
    }
    defer pool.Close()

    // Insert
    data := map[string]interface{}{
        "name":  "John Doe",
        "email": "[email protected]",
        "age":   30,
    }
    lastID, _ := pool.Write.Schema("public").Table("users").Insert(data)

    // Query
    rows, _ := pool.Read.
        Schema("public").
        Table("users").
        Select("id", "name", "email").
        Where("age", ">", 18).
        OrderBy("created_at", "DESC").
        Limit(10).
        Get()
    defer rows.Close()

    for rows.Next() {
        var id int
        var name, email string
        rows.Scan(&id, &name, &email)
        log.Printf("User: %s (%s)\n", name, email)
    }

    // Update
    updateData := map[string]interface{}{
        "age": 31,
    }
    pool.Write.Schema("public").Table("users").Where("id", lastID).Update(updateData)
}

License

This project is licensed under the MIT license.

Author

邱敬幃 Pardn Chiu


©️ 2025 邱敬幃 Pardn Chiu

About

(Go Package) PostgreSQL client with chained method calls

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages