Documentation
¶
Overview ¶
Package meta is the database schema metadata model: the flat, value-only abstraction of tables and columns that sqlkit's SQL generators consume. The decl package builds it from in-code catalogs and the introspection introspects a live database into it (for the initial bootstrap); the codegen generator takes it from there, and the model renders its own DDL (see ddl.go). Default and check expressions are carried as dialect-agnostic sql.Expression AST nodes; the dialect is supplied to the generators at call time, not stored on the model.
Everything is a value type with no back-references, so a catalog may be split across packages: each exposes the []Table it owns and the generators run over the concatenation.
Index ¶
- Variables
- type Check
- type Column
- type Engine
- type Enum
- type Extension
- type ForeignKey
- type GoType
- type GoTyped
- type Grant
- type IdentityMap
- type Index
- type MaterializedView
- type Metadata
- type ReferentialAction
- type Schema
- type Sequence
- type Table
- func (t Table) Column(name string) (Column, bool)
- func (t Table) CommentStatements() []sql.Statement
- func (t Table) CreateSQL(d sql.Dialect) (string, error)
- func (t Table) CreateStatement() sql.CreateTableStmt
- func (t Table) DropSQL(d sql.Dialect) string
- func (t Table) DropStatement() sql.DropTableStmt
- func (t Table) Key() TableKey
- func (t Table) PrimaryKeyColumns() []string
- func (t Table) SQLTable() sql.Table
- type TableKey
- type Type
Constants ¶
This section is empty.
Variables ¶
var ErrTableConflict = errors.New("meta: conflicting tables with the same name but different structure")
ErrTableConflict reports two tables that share a schema-qualified name but have a different structure (checksum) within one IdentityMap. It signals schema drift between independently built or generated tables of the same name.
Functions ¶
This section is empty.
Types ¶
type Check ¶
type Check struct {
Name string
Expression sql.Expression
}
Check is a CHECK constraint with its bare boolean expression (no CHECK keyword or outer parentheses). The DDL generator compiles Expression for the target dialect; the introspection supplies it as a sql.Raw of the introspected clause.
type Column ¶
type Column struct {
Name string
Type Type
Nullable bool
HasDefault bool
// DefaultExpr is the default's SQL expression when known (catalogs declare
// it with Default(sql.Raw("now()"))); it is nil when HasDefault is set
// without one, e.g. by the introspection. The DDL generator renders integer
// primary keys that have a default but no expression as serial/auto-increment
// columns, and compiles the expression for the target dialect otherwise.
DefaultExpr sql.Expression
PrimaryKey bool
Comment string
}
Column is a database column. Type is portable; generators resolve it to an engine type name for the target dialect.
type Engine ¶
type Engine struct {
Name string
// Length is the declared type length, e.g. the N of varchar(N) or char(N);
// 0 when not applicable.
Length int
// Precision and Scale describe a numeric/decimal type, e.g. (10, 2) of
// decimal(10, 2); 0 when not applicable.
Precision int
Scale int
// Array reports that the column is a one-dimensional array of the named
// element type (PostgreSQL only). The Name/Length/Precision/Scale describe the
// element; the DDL renderer appends "[]" and the code generator maps the
// column to a Go slice of the element's type.
Array bool
}
Engine is a column type resolved for a specific dialect: the engine type name plus any length/precision modifiers.
type Enum ¶
Enum is an enumerated type (PostgreSQL CREATE TYPE ... AS ENUM). Values are the labels, in order.
func (Enum) CreateStatement ¶
func (e Enum) CreateStatement() sql.CreateEnumStmt
CreateStatement builds the CREATE TYPE ... AS ENUM DDL node.
func (Enum) DropStatement ¶
func (e Enum) DropStatement() sql.DropTypeStmt
DropStatement builds the DROP TYPE IF EXISTS DDL node.
func (Enum) Equal ¶
Equal reports whether two enum types are identical (schema, name, and ordered labels), used by the diff engine to decide whether a type must be recreated.
func (Enum) QualifiedName ¶
QualifiedName returns the type name with an optional schema prefix.
type Extension ¶
Extension is a database extension (PostgreSQL CREATE EXTENSION). Schema, when set, is the WITH SCHEMA target the extension's objects are installed into; the extension name itself is never schema-qualified.
func (Extension) CreateStatement ¶
func (e Extension) CreateStatement() sql.CreateExtensionStmt
CreateStatement builds the CREATE EXTENSION IF NOT EXISTS DDL node, so creating the schema from scratch is idempotent.
func (Extension) DropStatement ¶
func (e Extension) DropStatement() sql.DropExtensionStmt
DropStatement builds the DROP EXTENSION IF EXISTS DDL node.
type ForeignKey ¶
type ForeignKey struct {
Name string
Columns []string
RefSchema Schema
RefTable string
RefColumns []string
OnDelete ReferentialAction
OnUpdate ReferentialAction
}
ForeignKey describes a foreign-key constraint: the local Columns reference RefColumns of RefTable (in RefSchema). OnDelete/OnUpdate carry the referential actions; an empty action is the engine default and renders nothing.
func (ForeignKey) AddStatement ¶
func (fk ForeignKey) AddStatement(table Table) sql.AlterTableStmt
AddStatement builds the ALTER TABLE ... ADD CONSTRAINT DDL node that adds the foreign key to its table.
func (ForeignKey) DropStatement ¶
func (fk ForeignKey) DropStatement(table Table) sql.DropForeignKeyStmt
DropStatement builds the DDL node that drops the foreign key from its table.
type GoTyped ¶
type GoTyped interface {
// GoType returns the Go type pinned for the dialect ("postgres" or "mysql");
// ok is false when no type is pinned (for that dialect), so the mapper falls
// back to its tables.
GoType(dialect string) (GoType, bool)
}
GoTyped is an optional interface a meta.Type may implement to pin the Go type it maps to, letting the schema fix the SQL→Go mapping at the source instead of relying on the code generator's built-in type tables. codegen's DefaultTypeMapper honors it (after its explicit Overrides, so a codegen-side override still wins). The decl DSL's DataType implements it via DataType.Go; the introspection's single-dialect types do not, so introspected schemas keep using the generator's tables.
type Grant ¶
type Grant struct {
Privileges []string
ObjectType string
Objects []string
Grantees []string
WithGrantOption bool
}
Grant is a privilege grant (GRANT ... ON ... TO ...). An empty Privileges list means ALL PRIVILEGES; an empty ObjectType defaults to TABLE. CreateSQL emits the GRANT and DropSQL the matching REVOKE.
func (Grant) CreateStatement ¶
CreateStatement builds the GRANT DDL node.
func (Grant) DropStatement ¶
func (g Grant) DropStatement() sql.RevokeStmt
DropStatement builds the REVOKE DDL node that undoes the grant.
type IdentityMap ¶
type IdentityMap struct {
// contains filtered or unexported fields
}
IdentityMap indexes tables by TableKey. It is built from a Metadata — the source of truth assembled from a decl catalog — and is the bridge a Unit of Work uses to validate table bindings against the catalog: a binding's schema, name, and checksum form a TableKey that must resolve here.
func (*IdentityMap) Add ¶
func (im *IdentityMap) Add(t Table) error
Add registers a table, folding a repeat of the same identity and reporting ErrTableConflict on a same-name, different-structure clash.
func (*IdentityMap) KeyForName ¶
func (im *IdentityMap) KeyForName(schema, name string) (TableKey, bool)
KeyForName returns the registered key for a schema-qualified name, if any.
func (*IdentityMap) Len ¶
func (im *IdentityMap) Len() int
Len reports how many distinct tables are registered.
type Index ¶
Index is a secondary index over Columns (the primary key index is not listed; it is implied by Column.PrimaryKey). Unique indexes cover both explicit unique indexes and the indexes backing UNIQUE constraints.
func (Index) CreateStatement ¶
func (ix Index) CreateStatement(table Table) sql.CreateIndexStmt
CreateStatement builds the CREATE INDEX DDL node for the index on its table.
func (Index) DropStatement ¶
func (ix Index) DropStatement(table Table) sql.DropIndexStmt
DropStatement builds the DROP INDEX DDL node for the index on its table.
type MaterializedView ¶
type MaterializedView struct {
Schema string
Name string
Query sql.Query
Columns []string
WithNoData bool
}
MaterializedView is a materialized view (PostgreSQL CREATE MATERIALIZED VIEW). Query is the view body — a sql.Query that compiles to plain SQL with no bind values. Columns, when set, names the view's columns explicitly; WithNoData creates it unpopulated.
func (MaterializedView) CreateStatement ¶
func (v MaterializedView) CreateStatement() sql.CreateMaterializedViewStmt
CreateStatement builds the CREATE MATERIALIZED VIEW DDL node.
func (MaterializedView) DropStatement ¶
func (v MaterializedView) DropStatement() sql.DropMaterializedViewStmt
DropStatement builds the DROP MATERIALIZED VIEW IF EXISTS DDL node.
func (MaterializedView) QualifiedName ¶
func (v MaterializedView) QualifiedName() string
QualifiedName returns the view name with an optional schema prefix.
type Metadata ¶
type Metadata struct {
Tables []Table
// Extensions, Enums, and Sequences are the non-table objects the schema
// declares (PostgreSQL). CreateSQL emits them around the tables in dependency
// order — extensions and enums before the tables that use them, sequences too,
// and DropSQL in reverse.
Extensions []Extension
Enums []Enum
Sequences []Sequence
// MaterializedViews and Grants are emitted after the tables (a view reads
// them, a grant targets them) and dropped before them.
MaterializedViews []MaterializedView
Grants []Grant
// ManagedSchemas are schemas put under migration management (CREATE/DROP
// SCHEMA) independently of any table — for example a schema that hosts only an
// enum, sequence, or materialized view. Schemas() folds them in alongside the
// schemas derived from the tables, so CreateSQL creates them before the objects
// that live in them. A schema that also hosts a table need not be repeated here.
ManagedSchemas []Schema
}
Metadata is a resolved set of tables — the dialect-agnostic value that a decl catalog builds into and that the codegen generator and the DDL renderer consume. It is the meta-level hand-off type: decl.Catalog.Build returns one, and the generators take it (plus the target dialect) from there.
func (Metadata) CreateSQL ¶
CreateSQL returns the SQL that creates the whole schema for dialect d (it does not touch a database): CREATE EXTENSION statements first, then a CREATE SCHEMA IF NOT EXISTS for each distinct schema marked for creation (Schema.Create) — so the tables that live in them never reference a missing schema — then the enum types and sequences the tables may use, then CREATE TABLE statements with primary keys and CHECK constraints, then CREATE INDEX statements, then ALTER TABLE statements for foreign keys (emitted after all tables so declaration order never matters), then comments. Schemas not marked Create (including the default schema) are assumed to already exist and are left alone. Catalogs built with the decl package and schemas read by the introspection both feed it through the same model.
The statements are built as sql-package DDL nodes (the DDL side of the SQL DSL) and compiled through the dialect, so meta, the migrate diff engine, and hand-written migrations share one rendering path.
Default expressions render only when the model carries them (Column.DefaultExpr, declared as decl.Default(sql.Raw("now()"))), compiled for the dialect; an integer primary key with a default but no expression renders as a serial (PostgreSQL) or AUTO_INCREMENT (MySQL) column. It returns an error if a column has no type on the dialect or a default/check expression cannot be compiled.
func (Metadata) DropSQL ¶
DropSQL returns the SQL that tears down everything CreateSQL creates, for dialect d (it does not touch a database): it drops the foreign keys first (so table drop order never matters), then drops the tables, which also drops their indexes, and finally a DROP SCHEMA IF EXISTS for each distinct schema marked for creation (Schema.Create), after its tables so the schema is empty by then. Schemas that CreateSQL leaves alone (the default schema and any not marked Create) are not dropped. It is the inverse of CreateSQL — run it before regenerating the schema. On MySQL, where a schema is a database, dropping it drops the database.
func (Metadata) Identities ¶
func (m Metadata) Identities() (*IdentityMap, error)
Identities builds an IdentityMap from the metadata. It returns ErrTableConflict when two tables share a schema-qualified name but differ in structure; tables that repeat with the same identity are folded together.
func (Metadata) Schemas ¶
Schemas returns the distinct schemas of the tables and the ManagedSchemas, in first-seen order (table schemas first). When the same schema name appears more than once with differing Create flags (e.g. one table marks it for creation and another does not, or it is also a ManagedSchema), the result reports Create=true: the schema is managed if any occurrence asks for it.
type ReferentialAction ¶
type ReferentialAction string
ReferentialAction is a foreign-key ON DELETE / ON UPDATE action. The empty value means none was declared (the engine default, NO ACTION) and renders nothing; the named values render their clause.
const ( NoAction ReferentialAction = "NO ACTION" Restrict ReferentialAction = "RESTRICT" Cascade ReferentialAction = "CASCADE" SetNull ReferentialAction = "SET NULL" SetDefault ReferentialAction = "SET DEFAULT" )
The referential actions a foreign key may take on delete/update. NoAction is the explicit form of the default; the empty ReferentialAction renders nothing.
type Schema ¶
Schema identifies the schema (PostgreSQL schema / MySQL database) a table belongs to. It is a small value, not a container: construct meta.Schema{Name: "public"} wherever one is needed. The zero value is the unnamed default schema, which generates unqualified names.
Create marks the schema for migration management: when set (and the schema is named), Metadata.CreateSQL emits a CREATE SCHEMA for it and DropSQL a DROP SCHEMA. It defaults to false, so sqlkit never creates a schema it was not told to — in particular the default schema, which is assumed to already exist.
func (Schema) CreateStatement ¶
func (s Schema) CreateStatement() sql.CreateSchemaStmt
CreateStatement builds the CREATE SCHEMA IF NOT EXISTS DDL node for the schema. The unnamed default schema (empty Name) has no statement to build — CreateSQL skips it, leaving its tables unqualified.
func (Schema) DropStatement ¶
func (s Schema) DropStatement() sql.DropSchemaStmt
DropStatement builds the DROP SCHEMA IF EXISTS DDL node for the schema.
type Sequence ¶
type Sequence struct {
Schema string
Name string
Increment *int64
Start *int64
MinValue *int64
MaxValue *int64
Cache *int64
Cycle *bool
OwnedBy string
}
Sequence is a database sequence (PostgreSQL CREATE SEQUENCE). The numeric options are pointers so an unset option takes the engine default rather than rendering a zero; OwnedBy is "" (unset), "NONE", or "table.column".
func (Sequence) CreateStatement ¶
func (s Sequence) CreateStatement() sql.CreateSequenceStmt
CreateStatement builds the CREATE SEQUENCE DDL node, applying only the options the model carries.
func (Sequence) DropStatement ¶
func (s Sequence) DropStatement() sql.DropSequenceStmt
DropStatement builds the DROP SEQUENCE IF EXISTS DDL node.
func (Sequence) Equal ¶
Equal reports whether two sequences are identical (schema, name, and every option), used by the diff engine to decide whether a sequence must be recreated.
func (Sequence) QualifiedName ¶
QualifiedName returns the sequence name with an optional schema prefix.
type Table ¶
type Table struct {
Schema Schema
Name string
Comment string
Columns []Column
ForeignKeys []ForeignKey
Indexes []Index
Checks []Check
}
Table is a database table. Schema is the schema it belongs to.
func (Table) CommentStatements ¶
CommentStatements builds the standalone comment DDL nodes for the table and its columns (PostgreSQL COMMENT ON ...). On dialects that comment inline they render empty.
func (Table) CreateSQL ¶
CreateSQL returns the CREATE TABLE statement for the table on dialect d. It errors if a column has no type on the dialect.
func (Table) CreateStatement ¶
func (t Table) CreateStatement() sql.CreateTableStmt
CreateStatement builds the CREATE TABLE DDL node for the table, including its primary key, CHECK constraints, and comment. It is dialect-independent — the column types resolve when it is compiled with ToSQL — so it can be used directly in a migration's Up list (schema.Users.CreateStatement()).
func (Table) DropStatement ¶
func (t Table) DropStatement() sql.DropTableStmt
DropStatement builds the DROP TABLE DDL node for the table.
func (Table) Key ¶
Key computes the table's TableKey. The checksum is a SHA-256 over a canonical, length-framed encoding of the table's structure: schema and name; each column's name, nullability, default flag, primary-key flag, resolved engine type, and default expression; then indexes, foreign keys (including their ON DELETE / ON UPDATE referential actions), and checks. Every string is length-prefixed and every list is count-prefixed so that no regrouping of fields can collide. The encoding reads only value fields, so it is identical for any two Table values describing the same structure.
func (Table) PrimaryKeyColumns ¶
PrimaryKeyColumns returns the names of the table's primary-key columns, in column order.
type TableKey ¶
type TableKey struct {
Schema string
Name string
Checksum string // hex-encoded SHA-256 of the canonical structural encoding
}
TableKey is a stable identity for a table: its schema-qualified name plus a checksum over its structure (columns, primary key, indexes, foreign keys, checks). Two Table values with the same structure produce the same key, even when assembled by independent packages, so consumers — notably the uow package's Unit of Work — can reconcile bindings of the same physical table. The same name with a different structure yields a different checksum, surfacing schema drift instead of silently merging incompatible tables.
func (TableKey) QualifiedName ¶
QualifiedName returns the table name with an optional schema prefix.
type Type ¶
type Type interface {
// Engine resolves the type for the dialect ("postgres" or "mysql"); ok is
// false when the type has no representation on it.
Engine(dialect string) (Engine, bool)
}
Type is a portable column type. It commits to an engine type name only when a generator picks a dialect (Engine), so the model stores no dialect itself. The decl DSL supplies portable types that resolve on both dialects; the introspection supplies single-dialect ones (see Of).
func Of ¶
Of returns a Type known only on the given dialect — what the introspection produces from one introspected engine type, and a convenient way to build a meta.Column by hand for a single target dialect.
func OfArray ¶
OfArray is Of for a one-dimensional array column whose elements are the named engine type (PostgreSQL only): the resolved Engine carries Array=true, so the DDL renderer appends "[]" and the code generator maps the column to a Go slice of the element's type. It is what the introspection produces from an array column.