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 ¶
- type Dialect
- type Execer
- type MySQL
- func (MySQL) CaseInsensitiveLike(col, placeholder string) string
- func (MySQL) Distinct(a, b string) string
- func (m MySQL) InsertID(ctx context.Context, ex Execer, query string, args ...any) (int64, error)
- func (MySQL) JSONText(col string) string
- func (MySQL) Lock(ctx context.Context, ex Execer, key string) (func(), error)
- func (MySQL) MigrationDir() string
- func (MySQL) Name() string
- func (MySQL) Quote(ident string) string
- func (MySQL) Rewrite(query string, args []any) (string, []any)
- func (MySQL) SplitStatements(script string) []string
- type Postgres
- func (Postgres) CaseInsensitiveLike(col, placeholder string) string
- func (Postgres) Distinct(a, b string) string
- func (Postgres) InsertID(ctx context.Context, ex Execer, query string, args ...any) (int64, error)
- func (Postgres) JSONText(col string) string
- func (Postgres) Lock(ctx context.Context, ex Execer, key string) (func(), error)
- func (Postgres) MigrationDir() string
- func (Postgres) Name() string
- func (Postgres) Quote(ident string) string
- func (Postgres) Rewrite(query string, args []any) (string, []any)
- func (Postgres) SplitStatements(script string) []string
- type Result
- type Row
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.
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 ¶
CaseInsensitiveLike is a plain LIKE: the default collations on both engines compare case-insensitively.
func (MySQL) Distinct ¶
Distinct uses the NULL-safe equality operator negated, since neither engine has IS DISTINCT FROM.
func (MySQL) InsertID ¶
InsertID uses LastInsertId, since neither engine supports RETURNING on every insert shape the CMS needs.
func (MySQL) JSONText ¶
JSONText returns the column as-is. MySQL's JSON and MariaDB's LONGTEXT alias both compare as text without a cast.
func (MySQL) Lock ¶
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) Quote ¶
Quote wraps an identifier in backticks. MySQL only accepts double quotes as identifier quoting under ANSI_QUOTES, which is not the default.
func (MySQL) SplitStatements ¶
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 ¶
CaseInsensitiveLike uses ILIKE, which Postgres provides directly.
func (Postgres) InsertID ¶
InsertID appends RETURNING id and reads the generated key back, because the Postgres driver does not implement LastInsertId.
func (Postgres) Lock ¶
Lock takes a session-level advisory lock. The key is hashed to the int64 pg_advisory_lock wants.
func (Postgres) MigrationDir ¶
func (Postgres) SplitStatements ¶
SplitStatements returns the script whole: Postgres executes a multi-statement string in one round trip, inside the caller's transaction.