dialect

package
v1.1.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: MPL-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package dialect isolates the SQL differences between the database engines the CMS supports.

Stores write Postgres-flavoured SQL — $1 placeholders, ON CONFLICT ... DO UPDATE, RETURNING — because it is the more expressive of the two dialects and reads the same as the schema. A Dialect translates that canonical form on its way to the driver, so nothing above this package needs to know which engine it is talking to.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Dialect

type Dialect interface {
	// Name identifies the engine, e.g. "postgres" or "mysql".
	Name() string

	// Rewrite translates a canonical statement and its arguments into the
	// form this engine accepts. It is applied to every statement on its way
	// to the driver, so it must be safe on SQL that needs no translation.
	Rewrite(query string, args []any) (string, []any)

	// InsertID runs an INSERT that has no RETURNING clause and reports the
	// generated primary key. Postgres appends RETURNING id and reads the
	// result; MySQL uses LastInsertId, which Postgres does not support.
	InsertID(ctx context.Context, ex Execer, query string, args ...any) (int64, error)

	// CaseInsensitiveLike renders a case-insensitive LIKE comparison of col
	// against an already-rendered placeholder.
	CaseInsensitiveLike(col, placeholder string) string

	// JSONText renders a JSON column as text, for the comparisons that treat
	// a JSON value as an opaque string.
	JSONText(col string) string

	// Quote escapes an identifier that collides with a reserved word —
	// cms_settings.key, which MySQL reserves. The two engines disagree on
	// the quoting character, so there is no shared spelling.
	Quote(ident string) string

	// Distinct renders a NULL-safe inequality between two columns —
	// Postgres's IS DISTINCT FROM, which MySQL and MariaDB lack.
	Distinct(a, b string) string

	// SplitStatements splits a migration file into individually executable
	// statements. Postgres can take a whole file at once; MySQL's driver
	// rejects multiple statements per Exec.
	SplitStatements(script string) []string

	// Lock takes an advisory lock serializing concurrent migration runs, and
	// returns the function that releases it.
	Lock(ctx context.Context, ex Execer, key string) (unlock func(), err error)

	// MigrationDir is the subdirectory of migrations/sql holding this
	// engine's schema.
	MigrationDir() string
}

Dialect translates canonical (Postgres-flavoured) SQL for one engine.

func For

func For(name string) Dialect

For returns the Dialect named by name, or nil when it is unknown.

type Execer

type Execer interface {
	ExecContext(ctx context.Context, query string, args ...any) (Result, error)
	QueryRowContext(ctx context.Context, query string, args ...any) Row
}

Execer is the subset of a database handle the dialect helpers need. Both *sql.DB and *sql.Tx satisfy it, so an insert works the same inside and outside a transaction.

type MySQL

type MySQL struct{}

MySQL is the dialect for MySQL 8.0.31+ and MariaDB 10.6+.

The 8.0.31 floor comes from EXCEPT, which the change-detection query in content/block.go uses and which MySQL only gained in that release. MariaDB has had it since 10.3.

func (MySQL) CaseInsensitiveLike

func (MySQL) CaseInsensitiveLike(col, placeholder string) string

CaseInsensitiveLike is a plain LIKE: the default collations on both engines compare case-insensitively.

func (MySQL) Distinct

func (MySQL) Distinct(a, b string) string

Distinct uses the NULL-safe equality operator negated, since neither engine has IS DISTINCT FROM.

func (MySQL) InsertID

func (m MySQL) InsertID(ctx context.Context, ex Execer, query string, args ...any) (int64, error)

InsertID uses LastInsertId, since neither engine supports RETURNING on every insert shape the CMS needs.

func (MySQL) JSONText

func (MySQL) JSONText(col string) string

JSONText returns the column as-is. MySQL's JSON and MariaDB's LONGTEXT alias both compare as text without a cast.

func (MySQL) Lock

func (MySQL) Lock(ctx context.Context, ex Execer, key string) (func(), error)

Lock takes a named advisory lock with GET_LOCK. The timeout is generous: it only has to outlast another instance applying the same migrations.

func (MySQL) MigrationDir

func (MySQL) MigrationDir() string

func (MySQL) Name

func (MySQL) Name() string

func (MySQL) Quote

func (MySQL) Quote(ident string) string

Quote wraps an identifier in backticks. MySQL only accepts double quotes as identifier quoting under ANSI_QUOTES, which is not the default.

func (MySQL) Rewrite

func (MySQL) Rewrite(query string, args []any) (string, []any)

Rewrite translates placeholders and upserts; see rewrite.

func (MySQL) SplitStatements

func (MySQL) SplitStatements(script string) []string

SplitStatements breaks a migration into single statements, which the driver requires unless multiStatements is enabled — and that conflicts with prepared statements.

type Postgres

type Postgres struct{}

Postgres is the canonical dialect: the SQL stores write is already Postgres SQL, so nearly every method here is the identity.

func (Postgres) CaseInsensitiveLike

func (Postgres) CaseInsensitiveLike(col, placeholder string) string

CaseInsensitiveLike uses ILIKE, which Postgres provides directly.

func (Postgres) Distinct

func (Postgres) Distinct(a, b string) string

Distinct uses IS DISTINCT FROM.

func (Postgres) InsertID

func (Postgres) InsertID(ctx context.Context, ex Execer, query string, args ...any) (int64, error)

InsertID appends RETURNING id and reads the generated key back, because the Postgres driver does not implement LastInsertId.

func (Postgres) JSONText

func (Postgres) JSONText(col string) string

JSONText casts jsonb to text.

func (Postgres) Lock

func (Postgres) Lock(ctx context.Context, ex Execer, key string) (func(), error)

Lock takes a session-level advisory lock. The key is hashed to the int64 pg_advisory_lock wants.

func (Postgres) MigrationDir

func (Postgres) MigrationDir() string

func (Postgres) Name

func (Postgres) Name() string

func (Postgres) Quote

func (Postgres) Quote(ident string) string

Quote wraps an identifier in double quotes, the SQL standard spelling.

func (Postgres) Rewrite

func (Postgres) Rewrite(query string, args []any) (string, []any)

Rewrite returns the statement untouched — canonical SQL is Postgres SQL.

func (Postgres) SplitStatements

func (Postgres) SplitStatements(script string) []string

SplitStatements returns the script whole: Postgres executes a multi-statement string in one round trip, inside the caller's transaction.

type Result

type Result interface {
	LastInsertId() (int64, error)
	RowsAffected() (int64, error)
}

Result is the subset of sql.Result the helpers use.

type Row

type Row interface {
	Scan(dest ...any) error
}

Row is the subset of *sql.Row the helpers use.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL