From 976a02d4b639eae6aff2a9d182f8187465a7b7ea Mon Sep 17 00:00:00 2001 From: August Vi Date: Sun, 11 Oct 2026 15:38:46 -0700 Subject: [PATCH 1/3] Rewrite the README around the fork: tagline, why-this-fork table, quick start, feature snippets, fixes table and compatibility. --- README.md | 357 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 286 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index bef80a2..20497ad 100644 --- a/README.md +++ b/README.md @@ -1,119 +1,314 @@ # sqlx -[![CI](https://github.com/secondwindoss/sqlx/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/secondwindoss/sqlx/actions/workflows/ci.yml) [![Go Reference](https://pkg.go.dev/badge/github.com/secondwindoss/sqlx.svg)](https://pkg.go.dev/github.com/secondwindoss/sqlx) [![license](https://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/secondwindoss/sqlx/master/LICENSE) +**The maintained fork of [jmoiron/sqlx](https://github.com/jmoiron/sqlx). +Same API, same package name, with the fixes upstream never merged.** + +[![CI](https://github.com/secondwindoss/sqlx/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/secondwindoss/sqlx/actions/workflows/ci.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/secondwindoss/sqlx.svg)](https://pkg.go.dev/github.com/secondwindoss/sqlx) +[![Go version](https://img.shields.io/github/go-mod/go-version/secondwindoss/sqlx)](go.mod) +[![Release](https://img.shields.io/github/v/release/secondwindoss/sqlx)](https://github.com/secondwindoss/sqlx/releases) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) + +sqlx extends Go's standard `database/sql` package. Its `DB`, `Tx`, `Stmt` and +`Rows` types embed the standard ones, so every `database/sql` method still +works and the extensions sit next to them: scan rows into structs, maps and +slices, run named queries with `:name` parameters, expand slices with `In`, +and go from query to struct in one call with `Get` and `Select`. + +## Why this fork + +- **Drop-in.** Every exported identifier of upstream v1.4.0 is unchanged. + CI runs `apidiff` against the v1.4.0 tag on every pull request to keep it + that way. Migration is an import path change. +- **Fixed.** Named queries, `In` and `Rebind` now read SQL instead of counting + bytes. A `?` or `:` inside a string literal, a quoted identifier or a comment + is no longer mistaken for a parameter, and `now()::date` works as written. + Twelve more upstream pull requests are merged with their original authors. +- **Maintained.** Every change runs the race tests on four Go versions against + PostgreSQL 16, MySQL 8 and SQLite, plus `vet`, `staticcheck`, `goimports` + and `govulncheck`. + +| | jmoiron/sqlx | secondwindoss/sqlx | +|--------------------|------------------------------|-----------------------------------| +| Last release | v1.4.0, April 2024 | v1.4.1, October 2026 | +| Last commit | May 2024 | active | +| Open pull requests | 79 (October 2026) | 0, the fixes are merged | +| Go support | `go 1.10`, untested | Go 1.24 and newer, tested | +| API | | identical, checked by `apidiff` | + +## Quick start -sqlx is a library which provides a set of extensions on go's standard -`database/sql` library. The sqlx versions of `sql.DB`, `sql.TX`, `sql.Stmt`, -et al. all leave the underlying interfaces untouched, so that their interfaces -are a superset on the standard ones. This makes it relatively painless to -integrate existing codebases using database/sql with sqlx. + go get github.com/secondwindoss/sqlx@v1.4.1 + +sqlx requires Go 1.24 or newer. -Major additional concepts are: +> [!NOTE] +> Coming from `github.com/jmoiron/sqlx`? Only the import path changes. See +> [Migrating from jmoiron/sqlx](#migrating-from-jmoironsqlx). -* Marshal rows into structs (with embedded struct support), maps, and slices -* Named parameter support including prepared statements -* `Get` and `Select` to go quickly from query to struct/slice +```go +package main -In addition to the [API documentation](https://pkg.go.dev/github.com/secondwindoss/sqlx), -there is also upstream's [user guide](https://jmoiron.github.io/sqlx/) that -explains how to use `database/sql` along with sqlx. +import ( + "log" -`sqlx.In` always expands with `?` placeholders. Even on PostgreSQL, write -`IN (?)` (not `IN ($1)`), then `db.Rebind` the query before running it. + _ "github.com/lib/pq" + "github.com/secondwindoss/sqlx" +) -## About this fork +type Person struct { + ID int `db:"id"` + FirstName string `db:"first_name"` + Email string // no tag: maps to the column "email" +} -This is a maintained fork of [jmoiron/sqlx](https://github.com/jmoiron/sqlx). -Upstream's last release is v1.4.0 (April 2024); since then bug fixes have sat -unmerged as pull requests with no maintainer activity. The fork keeps the full -upstream history, the MIT license and the `sqlx` package name, and ships those -fixes under the module path `github.com/secondwindoss/sqlx`. +func main() { + // Connect opens the pool and pings it. Use sqlx.Open for sql.Open semantics. + db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable") + if err != nil { + log.Fatalln(err) + } + + // Named parameters come from the struct's db tags. + _, err = db.NamedExec(`INSERT INTO person (first_name, email) VALUES (:first_name, :email)`, + &Person{FirstName: "Jane", Email: "jane@example.com"}) + if err != nil { + log.Fatalln(err) + } + + // One row into a struct. + var jane Person + if err := db.Get(&jane, "SELECT * FROM person WHERE first_name = $1", "Jane"); err != nil { + log.Fatalln(err) + } + + // Many rows into a slice. + var people []Person + if err := db.Select(&people, "SELECT * FROM person ORDER BY id"); err != nil { + log.Fatalln(err) + } + log.Printf("%+v, %d people", jane, len(people)) +} +``` -The first fork release, v1.4.1, keeps every exported identifier of upstream -v1.4.0 (CI checks this with `apidiff`), adds `Tx.NamedQueryContext`, requires -Go 1.24 and fixes the bugs that sat in upstream pull requests. Three documented -behaviours change: `::` is a cast and no longer an escape for `:`, `??` is a -literal `?`, and `In` expands an empty slice to `NULL` instead of returning an -error. [CHANGELOG.md](CHANGELOG.md) lists every change with the upstream pull -request and author it comes from. +## Migrating from jmoiron/sqlx -## Migrating from github.com/jmoiron/sqlx +Rewrite the import path, then update the dependency. -Only the import path changes. Rewrite it in your module, then update the -dependency: +macOS: grep -rl 'github.com/jmoiron/sqlx' --include='*.go' . | xargs sed -i '' 's#github.com/jmoiron/sqlx#github.com/secondwindoss/sqlx#g' go get github.com/secondwindoss/sqlx@v1.4.1 go mod tidy -On Linux drop the `''` after `sed -i`. Tags up to v1.4.0 are upstream's and -declare the upstream module path, so v1.4.1 is the first version that resolves -under the new path. +Linux: + + grep -rl 'github.com/jmoiron/sqlx' --include='*.go' . | xargs sed -i 's#github.com/jmoiron/sqlx#github.com/secondwindoss/sqlx#g' + go get github.com/secondwindoss/sqlx@v1.4.1 + go mod tidy + +Tags up to v1.4.0 are upstream's and declare the upstream module path, so +v1.4.1 is the first version that resolves under the new path. A `replace github.com/jmoiron/sqlx => github.com/secondwindoss/sqlx v1.4.1` directive does not work: the fork imports its own `reflectx` package under the new path, and Go refuses to use one module under two paths. Rewrite the imports instead. -## Recent Changes +> [!IMPORTANT] +> Four documented behaviours changed in v1.4.1. Each one fixes a long-standing +> upstream issue, but check your queries for them: +> +> - `::` is a PostgreSQL cast and passes through untouched. The old escape that +> turned `::` into `:` is gone, so a query that wrote `::::` now writes `::`. +> - `??` is a literal `?` in `In` and `Rebind`, so the PostgreSQL JSONB +> operators `??`, `??|` and `??&` can be written as pgJDBC and squirrel do. +> - `In` expands an empty or nil slice to `NULL` instead of returning an error. +> `x IN (NULL)` and `x NOT IN (NULL)` both match no row. Code that used the +> error as an empty-list guard must check the length itself. +> - A parameter name cannot start with a digit, so `:1` is text. -1.4.1: +## Features -* named queries, `In` and `Rebind` skip string literals, quoted identifiers and comments; `::` casts work as written -* `In` expands an empty slice to `NULL`; `??` is a literal `?` -* `Tx.NamedQueryContext`; batch inserts without a column list; pointer arguments to named queries -* statements prepared on a `Conn` keep its mapper; `Tx.Stmtx` keeps `unsafe`; `NextResultSet` resets the field cache -* requires Go 1.24; see [CHANGELOG.md](CHANGELOG.md) for every change and its upstream credit +**Scan into structs, with embedded structs.** Columns map to fields through +the `db` tag, or the lowercased field name when there is no tag. -1.3.0: +```go +type Address struct { + City string + Country string +} -* `sqlx.DB.Connx(context.Context) *sqlx.Conn` -* `sqlx.BindDriver(driverName, bindType)` -* support for `[]map[string]interface{}` to do "batch" insertions -* allocation & perf improvements for `sqlx.In` +type Person struct { + FirstName string `db:"first_name"` + Email string + Address // embedded: city and country come from the same row +} -DB.Connx returns an `sqlx.Conn`, which is an `sql.Conn`-alike consistent with -sqlx's wrapping of other types. +var p Person +err := db.Get(&p, "SELECT first_name, email, city, country FROM person WHERE id = $1", 1) -`BindDriver` allows users to control the bindvars that sqlx will use for drivers, -and add new drivers at runtime. This results in a very slight performance hit -when resolving the driver into a bind type (~40ns per call), but it allows users -to specify what bindtype their driver uses even when sqlx has not been updated -to know about it by default. +var people []Person +err = db.Select(&people, "SELECT first_name, email, city, country FROM person") +``` -### Backwards Compatibility +**Named queries** take a struct, a map, or a pointer to either. Prepared named +statements keep the parameter order for you. -Compatibility with the most recent two versions of Go is a requirement for any -new changes. Compatibility beyond that is not guaranteed. +```go +_, err := db.NamedExec(`INSERT INTO person (first_name, email) VALUES (:first_name, :email)`, p) -Versioning is done with Go modules. Breaking changes (eg. removing deprecated API) -will get major version number bumps. +rows, err := db.NamedQuery(`SELECT * FROM person WHERE first_name = :first`, + map[string]any{"first": "Jane"}) +defer rows.Close() -## install +stmt, err := db.PrepareNamed(`SELECT * FROM person WHERE email = :email`) +err = stmt.Get(&p, map[string]any{"email": "jane@example.com"}) +``` - go get github.com/secondwindoss/sqlx@v1.4.1 +**`In` and `Rebind`** expand a slice into a placeholder list and translate `?` +to the placeholder style of your driver. `In` always takes `?`, even on +PostgreSQL; `Rebind` turns it into `$1`. -sqlx requires Go 1.24 or newer. +```go +ids := []int{4, 8, 15} +query, args, err := sqlx.In("SELECT * FROM person WHERE id IN (?)", ids) +// query: SELECT * FROM person WHERE id IN (?, ?, ?) + +query = db.Rebind(query) // $1, $2, $3 on PostgreSQL; ? stays ? on MySQL and SQLite +err = db.Select(&people, query, args...) +``` -## issues +**Batch inserts** expand one `VALUES` group per element of a slice of structs +or maps. -Row headers can be ambiguous (`SELECT 1 AS a, 2 AS a`), and the result of -`Columns()` does not fully qualify column names in queries like: +```go +people := []Person{ + {FirstName: "Ardie", Email: "asavea@ab.co.nz"}, + {FirstName: "Ngani", Email: "nlaumape@ab.co.nz"}, +} +_, err := db.NamedExec(`INSERT INTO person (first_name, email) VALUES (:first_name, :email)`, people) +``` + +**Transactions and prepared statements** have the same extensions as `DB`. + +```go +tx := db.MustBegin() +tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Singapore", 65) +tx.NamedExec(`INSERT INTO place (country, telcode) VALUES (:country, :telcode)`, + Place{Country: "Hong Kong", TelCode: 852}) +if err := tx.Commit(); err != nil { + log.Fatalln(err) +} + +stmt, err := db.Preparex("SELECT * FROM place WHERE telcode = $1") +var place Place +err = stmt.Get(&place, 65) +``` + +**Row by row, maps and slices** when a struct is the wrong shape. + +```go +rows, err := db.Queryx("SELECT * FROM place") +for rows.Next() { + var place Place + if err := rows.StructScan(&place); err != nil { + log.Fatalln(err) + } +} + +row := map[string]any{} +err = db.QueryRowx("SELECT * FROM place WHERE telcode = $1", 65).MapScan(row) +``` + +Every method has a `Context` variant: `GetContext`, `SelectContext`, +`NamedExecContext`, `NamedQueryContext` and so on. The +[API reference](https://pkg.go.dev/github.com/secondwindoss/sqlx) lists them +all. + +## What v1.4.1 fixes + +| Before | Now | Upstream | +|-------------------------------------------------------------------------|------------------------------------------------------------|--------------------------------| +| A `?` or `:` inside a string literal or a comment became a placeholder | A SQL scanner skips literals, quoted identifiers, comments | [#984], [#151], [#768], [#474] | +| `now()::date` in a named query broke the cast | `::` is a cast and passes through | [#428], [#650], [#956] | +| PostgreSQL `?` JSONB operators could not be used with `In` or `Rebind` | `??` is a literal `?` | [#628] | +| `In` with an empty slice returned an error | Expands to `NULL`, matches no row | [#945] | +| `In` panicked on a nil pointer that implements `driver.Valuer` | Treated as `NULL` | [#953] | +| Batch insert failed without a column list, in a `FROM`, or on a new line | All three forms expand | [#962] | +| Named queries rejected a pointer to a slice or a map | Accepted | [#805] | +| A statement prepared on a `Conn` lost the `Conn`'s mapper | Kept | [#993] | +| `Tx.Stmtx` dropped the transaction's `unsafe` flag | Kept | [#979] | +| `Rows.NextResultSet` panicked when the next set had other columns | Field cache reset | [#858] | +| `ConnectContext` leaked the pool when the ping failed | Closes it, like `Connect` | [#561] | +| No `Tx.NamedQueryContext` | Added | [#724] | + +[CHANGELOG.md](CHANGELOG.md) lists every change with the fork pull request, +the upstream pull request and its author. + +## Compatibility + +**Go.** The two most recent Go releases are supported, as in the +[Go release policy](https://go.dev/doc/devel/release#policy). CI runs the race +tests on Go 1.24, 1.25, oldstable and stable. + +**Databases.** CI tests every change against PostgreSQL 16, MySQL 8 and +SQLite. Any `database/sql` driver works; sqlx only needs to know its +placeholder style. + +| Placeholder | Drivers | +|-------------|---------------------------------------------------------------------------| +| `$1` | `postgres`, `pgx`, `cockroach`, `pq-timeouts`, `cloudsqlpostgres`, `nrpostgres`, `ql` | +| `?` | `mysql`, `sqlite3`, `nrmysql`, `nrsqlite3` | +| `:name` | `oci8`, `ora`, `goracle`, `godror` | +| `@p1` | `sqlserver`, `azuresql` | + +Register any other driver at startup with `sqlx.BindDriver("mydriver", sqlx.DOLLAR)`. + +## Known limitations + +Row headers can be ambiguous (`SELECT 1 AS a, 2 AS a`), and `Columns()` does +not qualify column names in queries like: ```sql SELECT a.id, a.name, b.id, b.name FROM foos AS a JOIN foos AS b ON a.parent = b.id; ``` -making a struct or map destination ambiguous. Use `AS` in your queries -to give columns distinct names, `rows.Scan` to scan them manually, or -`SliceScan` to get a slice of results. +making a struct or map destination ambiguous. Use `AS` to give columns +distinct names, `rows.Scan` to scan them manually, or `SliceScan` to get a +slice of results. -## usage +## Documentation -Below is an example which shows some common use cases for sqlx. Check -[sqlx_test.go](https://github.com/secondwindoss/sqlx/blob/master/sqlx_test.go) for more -usage. +- [API reference](https://pkg.go.dev/github.com/secondwindoss/sqlx) on pkg.go.dev. +- Upstream's [user guide](https://jmoiron.github.io/sqlx/) explains how to use + `database/sql` together with sqlx. Everything in it applies to the fork + under the new import path. +- [CHANGELOG.md](CHANGELOG.md), [CONTRIBUTING.md](CONTRIBUTING.md) and + [SECURITY.md](SECURITY.md). +## Project status and versioning + +The fork follows [semantic versioning](https://semver.org). The v1 line keeps +the upstream API: `apidiff` runs against the v1.4.0 tag on every pull request +and fails on any incompatible change. A breaking change, such as removing a +deprecated API, gets a major version bump. + +Upstream fixes are merged with their original commits, so each author keeps +the credit in the history and in the changelog. Bug reports and pull requests +are welcome in this repository; see [CONTRIBUTING.md](CONTRIBUTING.md). + +## Credits and license + +sqlx was created by [Jason Moiron](https://github.com/jmoiron) in 2013 and +maintained upstream until 2024. This fork keeps the full upstream history and +has been maintained by [secondwindoss](https://github.com/secondwindoss) since +2026. Licensed under the [MIT License](LICENSE). + +## Full example + +
+The complete walkthrough from the upstream README, updated for the fork ```go package main @@ -258,3 +453,23 @@ func main() { VALUES (:first_name, :last_name, :email)`, personMaps) } ``` + +
+ +[#151]: https://github.com/jmoiron/sqlx/pull/151 +[#428]: https://github.com/jmoiron/sqlx/issues/428 +[#474]: https://github.com/jmoiron/sqlx/pull/474 +[#561]: https://github.com/jmoiron/sqlx/pull/561 +[#628]: https://github.com/jmoiron/sqlx/issues/628 +[#650]: https://github.com/jmoiron/sqlx/issues/650 +[#724]: https://github.com/jmoiron/sqlx/pull/724 +[#768]: https://github.com/jmoiron/sqlx/pull/768 +[#805]: https://github.com/jmoiron/sqlx/pull/805 +[#858]: https://github.com/jmoiron/sqlx/pull/858 +[#945]: https://github.com/jmoiron/sqlx/pull/945 +[#953]: https://github.com/jmoiron/sqlx/pull/953 +[#956]: https://github.com/jmoiron/sqlx/issues/956 +[#962]: https://github.com/jmoiron/sqlx/pull/962 +[#979]: https://github.com/jmoiron/sqlx/pull/979 +[#984]: https://github.com/jmoiron/sqlx/pull/984 +[#993]: https://github.com/jmoiron/sqlx/pull/993 From f23d7d4d01b98ee3dec2aa7cee9fa141b1ae67d9 Mon Sep 17 00:00:00 2001 From: August Vi Date: Sun, 11 Oct 2026 15:38:46 -0700 Subject: [PATCH 2/3] Mention the fork and the migration steps in the package doc comment. --- doc.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc.go b/doc.go index b801041..49b91ae 100644 --- a/doc.go +++ b/doc.go @@ -1,5 +1,9 @@ // Package sqlx provides general purpose extensions to database/sql. // +// This is the secondwindoss fork of github.com/jmoiron/sqlx. It keeps the API +// of upstream v1.4.0 and only the import path differs; the README has the +// migration steps and CHANGELOG.md lists what each release fixes. +// // It is intended to seamlessly wrap database/sql and provide convenience // methods which are useful in the development of database driven applications. // None of the underlying database/sql methods are changed. Instead all extended From 180d1b596e72dc173fbd62fd8f8d69a11f717dcb Mon Sep 17 00:00:00 2001 From: August Vi Date: Sun, 11 Oct 2026 15:41:29 -0700 Subject: [PATCH 3/3] Add the sqlx wordmark to the README header. --- .github/logo.png | Bin 0 -> 14171 bytes .github/logo.svg | 6 ++++++ README.md | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .github/logo.png create mode 100644 .github/logo.svg diff --git a/.github/logo.png b/.github/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa9741caf5e3f418b165755ef82c61077c3aed2d GIT binary patch literal 14171 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 pL0$$bR<>k|L~ literal 0 HcmV?d00001 diff --git a/.github/logo.svg b/.github/logo.svg new file mode 100644 index 0000000..58c4c76 --- /dev/null +++ b/.github/logo.svg @@ -0,0 +1,6 @@ + + + sqlx + :name + $1 ? + diff --git a/README.md b/README.md index 20497ad..5f32b52 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# sqlx +# sqlx **The maintained fork of [jmoiron/sqlx](https://github.com/jmoiron/sqlx). Same API, same package name, with the fixes upstream never merged.**