Skip to content

goflower-io/xsql

Repository files navigation

xsql — Type-Safe SQL Builder & DB Client for Go

xsql is the SQL query builder and database client library powering the crud ORM. It provides a generics-based, fluent API for building and executing SQL across MySQL, PostgreSQL, and SQLite3 — with built-in read-write separation and per-operation timeout control.

中文文档 | crud | golib | example


Features

  • Generics-based field operationsFieldOp[int64], StrFieldOp — fully type-safe, no casting
  • Fluent query builder — SELECT / INSERT / UPDATE / DELETE chainable API
  • Multi-dialect — MySQL, PostgreSQL, SQLite3
  • Read-write separation — automatic master/slave routing with round-robin load balancing
  • Per-operation timeouts — independent QueryTimeout and ExecTimeout
  • Composable predicatesAnd, Or, Not combinators for complex WHERE clauses
  • Custom result scanning — scan into any struct using JSON tags
  • Debug mode — print generated SQL and parameters with one wrapper call

Installation

go get github.com/goflower-io/xsql

Open a Connection

import (
    "github.com/goflower-io/xsql"
    "github.com/goflower-io/xsql/mysql"
)

db, err := mysql.NewDB(&xsql.Config{
    DSN:          "root:123456@tcp(127.0.0.1:3306)/test?parseTime=true&loc=Local",
    ReadDSN:      []string{"root:123456@tcp(127.0.0.1:3307)/test?parseTime=true&loc=Local"},
    Active:       20,
    Idle:         20,
    IdleTimeout:  24 * time.Hour,
    QueryTimeout: 10 * time.Second,  // applied to SELECT
    ExecTimeout:  10 * time.Second,  // applied to INSERT/UPDATE/DELETE
})

PostgreSQL and SQLite3:

import "github.com/goflower-io/xsql/postgres"
db, _ := postgres.NewDB(&xsql.Config{
    DSN: "host=127.0.0.1 user=postgres password=123456 dbname=test sslmode=disable",
})

import "github.com/goflower-io/xsql/sqlite3"
db, _ := sqlite3.NewDB(&xsql.Config{
    DSN: "/path/to/my.db",
})

Field Operations

xsql is typically consumed through code generated by crud. The generated code declares typed field operators for each column:

// Generated in crud/user/user.go
var IdOp   = xsql.FieldOp[int64]("id")
var NameOp = xsql.StrFieldOp("name")
var AgeOp  = xsql.FieldOp[int64]("age")

Numeric / comparable fields — FieldOp[T]

IdOp.EQ(1)           // id = 1
IdOp.NEQ(1)          // id != 1
IdOp.GT(10)          // id > 10
IdOp.GTE(10)         // id >= 10
IdOp.LT(100)         // id < 100
IdOp.LTE(100)        // id <= 100
IdOp.In(1, 2, 3)     // id IN (1, 2, 3)
IdOp.NotIn(4, 5)     // id NOT IN (4, 5)

String fields — StrFieldOp

NameOp.EQ("alice")           // name = 'alice'
NameOp.NEQ("alice")          // name != 'alice'
NameOp.Contains("ali")       // name LIKE '%ali%'
NameOp.HasPrefix("ali")      // name LIKE 'ali%'
NameOp.HasSuffix("ice")      // name LIKE '%ice'
NameOp.IsNull()              // name IS NULL
NameOp.NotNull()             // name IS NOT NULL

Composing predicates

// Implicit AND — multiple args to Where()
finder.Where(IdOp.GT(10), AgeOp.LT(30))
// WHERE id > 10 AND age < 30

// OR
finder.Where(xsql.OrOp(IdOp.EQ(1), IdOp.EQ(2)))
// WHERE id = 1 OR id = 2

// NOT
finder.Where(xsql.NotOp(AgeOp.In(10, 20)))
// WHERE NOT age IN (10, 20)

// Nested: (id > 10 OR age IN (18, 25)) AND name LIKE 'ali%'
finder.Where(
    xsql.OrOp(IdOp.GT(10), AgeOp.In(18, 25)),
    NameOp.HasPrefix("ali"),
)

Aggregate & Expression Helpers

xsql.Count("*")              // COUNT(*)
xsql.As(expr, "alias")       // expr AS alias
xsql.GT("cnt", 1)            // cnt > 1  — for HAVING clauses
xsql.And(ps...)              // AND-combine multiple *Predicate
xsql.Or(ps...)               // OR-combine multiple *Predicate
xsql.GenP(col, op, val)      // build *Predicate from dynamic string inputs

Dynamic predicate from user input

// Accepts op strings: EQ NEQ GT GTE LT LTE IN NOT_IN CONTAINS HAS_PREFIX HAS_SUFFIX
p, err := xsql.GenP("age", "GT", "18")
if err != nil {
    return err
}
finder.WhereP(p)

Config Reference

type Config struct {
    DSN          string        // Write (master) DSN
    ReadDSN      []string      // Read replica DSNs — round-robin balanced
    Active       int           // Max open connections
    Idle         int           // Max idle connections
    IdleTimeout  time.Duration // Connection max idle time
    QueryTimeout time.Duration // Context timeout for SELECT
    ExecTimeout  time.Duration // Context timeout for INSERT / UPDATE / DELETE
}

Debug Mode

// Wrap any *DB to log SQL and params
user.Create(xsql.Debug(db)).SetUser(u).Save(ctx)
// [xsql] INSERT INTO `user` (`name`, `age`, `ctime`, `mtime`) VALUES (?, ?, ?, ?) [alice 18 ...]

Read-Write Routing

  • Write operations (INSERT, UPDATE, DELETE) always go to DSN (master).
  • Read operations (SELECT) round-robin across ReadDSN replicas.
  • If ReadDSN is empty, reads also use DSN.

Dialect Support

Dialect Driver Import
MySQL / MariaDB github.com/go-sql-driver/mysql github.com/goflower-io/xsql/mysql
PostgreSQL github.com/jackc/pgx/v5 github.com/goflower-io/xsql/postgres
SQLite3 github.com/mattn/go-sqlite3 github.com/goflower-io/xsql/sqlite3

Related

  • crud — generate type-safe CRUD code from SQL DDL using xsql as runtime
  • golib — HTTP/gRPC application server framework
  • example — full-stack examples showing all four libraries together

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages