Skip to content

Backends

LiteORM ships four backends. The query and orm front-ends are portable across all of them; what differs is how you open each one, its DSN shape, and which optional SQL capabilities it advertises. Each backend lives in its own liteorm.org/dialect/... package and returns a *liteorm.DB carrying the matching dialect.

The SQLite backend wraps the pure-Go driver gosqlite.org — no cgo. Open applies a production pragma preset (WAL, a busy timeout, foreign keys on).

import "liteorm.org/dialect/sqlite"
db, err := sqlite.Open("app.db") // path, or ":memory:"
db, err := sqlite.OpenEncrypted("secret.db", key) // 32-byte key, Adiantum at rest
db, err := sqlite.OpenConfig(cfg) // full gosqlite.Config: custom VFS, pragmas, pooling

The DSN is a filesystem path (or :memory:). SQLite is the only backend with the advanced search and changeset extensions — see SQLite search and SQLite changesets.

At-rest encryption. sqlite.OpenEncrypted opens an encrypted database using the default Adiantum cipher with a 32-byte key; the on-disk file is ciphertext and reopens only with the same key. Encryption refuses :memory: and is mutually exclusive with a custom VFS; the recommended pragma preset still applies.

key := make([]byte, 32) // supply real 32-byte key material
db, err := sqlite.OpenEncrypted("secret.db", key)

The Postgres backend runs over the native pgx/v5 API (pgxpool), giving the binary protocol scan path and native fast paths.

import "liteorm.org/dialect/postgres"
db, err := postgres.Open(ctx, "postgres://user:pass@host:5432/dbname?sslmode=disable")

The DSN is a libpq connection string or URL, as accepted by pgx. See Postgres features for LISTEN/NOTIFY, JSONB, arrays, and bulk insert.

The MySQL backend runs over go-sql-driver/mysql via database/sql.

import "liteorm.org/dialect/mysql"
db, err := mysql.Open(ctx, "user:pass@tcp(host:3306)/dbname?parseTime=true")

The DSN is the go-sql-driver/mysql format. Open pings the database before returning.

The MSSQL backend targets SQL Server.

import "liteorm.org/dialect/mssql"
db, err := mssql.Open(ctx, "sqlserver://user:pass@host:1433?database=dbname")

Each dialect advertises optional capabilities as feature flags the query builder consults. The table below summarizes what each backend supports.

CapabilitySQLitePostgresMySQLMSSQL
Upsert clauseON CONFLICTON CONFLICTON DUPLICATE KEYMERGE
Insert/update outputRETURNINGRETURNINGOUTPUT
LastInsertIdyes— (use RETURNING)yes— (use OUTPUT)
Common table expressionsyesyesyesyes
Native JSON columnyesyesyes
JSONB containment (@>, <@)yes
Array column + operatorsyes
Identity / autoincrementAUTOINCREMENTSERIAL/IDENTITYAUTO_INCREMENTIDENTITY
OFFSET/FETCH pagination— (LIMIT/OFFSET)— (LIMIT/OFFSET)— (LIMIT/OFFSET)yes
Row locking (FOR UPDATE/SHARE, SKIP LOCKED)yesyes
DISTINCT ONyes
INTERSECT / EXCEPTyesyesyes
LATERAL joinyes
UPDATE … FROMyesyesyes
LISTEN/NOTIFYyes

A few notes on reading this table:

  • Upsert — every backend supports an upsert, but the SQL differs: ON CONFLICT ... DO UPDATE (SQLite, Postgres), ON DUPLICATE KEY UPDATE (MySQL), MERGE (MSSQL). The query builder emits the right one.
  • OutputRETURNING (SQLite, Postgres) and OUTPUT (MSSQL) let an insert or update return rows; MySQL has neither and uses LastInsertId for generated keys.
  • JSON vs JSONB — a native JSON column (FeatJSON) is broader than the JSONB containment operators (FeatJSONB): SQLite and MySQL have JSON types but not the @> / <@ operators, which are Postgres-only.
  • Row lockingFOR UPDATE/FOR SHARE (with optional SKIP LOCKED/NOWAIT) on Postgres and MySQL 8+; SQLite has no row locks and MSSQL uses table hints instead, so neither advertises it.
  • INTERSECT / EXCEPT — SQLite, Postgres, and MSSQL; left off MySQL (supported only since 8.0.31). LATERAL and DISTINCT ON are Postgres-only; UPDATE … FROM is everywhere except MySQL (which uses UPDATE … JOIN).
  • LISTEN/NOTIFY — Postgres-only; see Postgres features.