GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing portablesql.github.io — portablesql — Portable SQL toolkit for Go Why portablesql?A small ORM and query builder that keeps your SQL portable across engines. Multi-DatabaseMySQL and MariaDB, PostgreSQL and CockroachDB, SQLite. Placeholders, upserts, LIMIT/OFFSET, LIKE and date arithmetic are rendered per engine, so the same code runs on all of them. Zero BloatEach driver is its own Go module that registers itself on import. Import psql-sqlite and you will not download pgx or the MySQL driver. Struct BindingMap structs to tables with Query BuilderFluent SELECT, INSERT, UPDATE and DELETE with joins, subqueries, ON CONFLICT and Transactions & Relations
And MoreLifecycle hooks, soft delete with Quick StartImport a driver, connect with a DSN, and work with your own structs. Requires Go 1.24 or later (1.25 for psql-pgsql and psql-sqlite).
main.go
package main import ( "context" "fmt" "log" "github.com/portablesql/psql" _ "github.com/portablesql/psql-sqlite" // or psql-mysql / psql-pgsql ) type User struct { psql.Name `sql:"users"` ID uint64 `sql:",key=PRIMARY"` Username string `sql:",type=VARCHAR,size=128"` Email string `sql:",type=VARCHAR,size=255,key=UNIQUE:email"` } func main() { be, err := psql.New(":memory:") // engine detected from the DSN if err != nil { log.Fatal(err) } ctx := be.Plug(context.Background()) // Insert: the table is created (or migrated) on first use err = psql.Insert(ctx, &User{ID: 1, Username: "alice", Email: "[email protected]"}) if psql.IsDuplicate(err) { log.Println("already registered") } // Load one record, change it, write back only the changed columns alice, err := psql.Get[User](ctx, map[string]any{"Email": "[email protected]"}) if err != nil { log.Fatal(err) } alice.Username = "alice.smith" err = psql.Update(ctx, alice) // Transactions (nested ones become savepoints) err = psql.Tx(ctx, func(ctx context.Context) error { return psql.Insert(ctx, &User{ID: 2, Username: "bob", Email: "[email protected]"}) }) // Iterate over matches (Go 1.23 range-over-func) it, err := psql.Iter[User](ctx, map[string]any{"Username": &psql.Like{Like: "a%"}}, psql.Sort(psql.S("Username", "ASC"))) for u := range it { fmt.Println(u.Username) } // Query builder: renders ? or $1 placeholders depending on the engine query, args, err := psql.B().Select("Username").From("users"). Where(psql.Gt(psql.F("ID"), 1)).Limit(0, 10).RenderArgs(ctx) fmt.Println(query, args, err) }
On SQLite this prints PackagesInstall the core plus the driver you need. Drivers register themselves on import and
psql
core · v0.5.8
Struct binding, query builder, transactions, associations, hooks and the engine abstraction. go get github.com/portablesql/psql
psql-mysql
driver · v0.5.0
MySQL and MariaDB via go-sql-driver/mysql (pure Go). DSN: go get github.com/portablesql/psql-mysql
psql-pgsql
driver · v0.5.0
PostgreSQL and CockroachDB via pgx (pgxpool). DSN: go get github.com/portablesql/psql-pgsql
psql-sqlite
driver · v0.5.0
SQLite via modernc.org/sqlite (pure Go, no CGO). DSN: go get github.com/portablesql/psql-sqlite |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |