meta

package
v0.0.0-...-6f40dae Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 9 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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.

func (Column) ColumnDef

func (c Column) ColumnDef() sql.ColumnDef

ColumnDef builds the dialect-independent sql.ColumnDef for the column — the building block of CREATE TABLE and ALTER TABLE ADD COLUMN. The portable type resolves when the statement is compiled for a 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

type Enum struct {
	Schema string
	Name   string
	Values []string
}

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

func (e Enum) Equal(o Enum) bool

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

func (e Enum) QualifiedName() string

QualifiedName returns the type name with an optional schema prefix.

type Extension

type Extension struct {
	Name   string
	Schema string
}

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 GoType

type GoType struct {
	ImportPath string
	Name       string
	Pointer    bool
}

GoType describes a generated Go type and the import it needs, if any.

func (GoType) String

func (t GoType) String() string

String renders the type as it appears in Go source.

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

func (g Grant) CreateStatement() sql.GrantStmt

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.

func (Grant) Equal

func (g Grant) Equal(o Grant) bool

Equal reports whether two grants are identical.

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.

func (*IdentityMap) Lookup

func (im *IdentityMap) Lookup(key TableKey) (Table, bool)

Lookup returns the table registered under key.

type Index

type Index struct {
	Name    string
	Columns []string
	Unique  bool
}

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) CreateSQL

func (ix Index) CreateSQL(table Table, d sql.Dialect) string

CreateSQL returns the CREATE INDEX statement for the index on its table.

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) DropSQL

func (ix Index) DropSQL(table Table, d sql.Dialect) string

DropSQL returns the DROP INDEX statement 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

func (md Metadata) CreateSQL(d sql.Dialect) (string, error)

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

func (md Metadata) DropSQL(d sql.Dialect) string

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

func (m Metadata) Schemas() []Schema

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

type Schema struct {
	Name   string
	Create bool
}

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

func (s Sequence) Equal(o Sequence) bool

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

func (s Sequence) QualifiedName() string

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) Column

func (t Table) Column(name string) (Column, bool)

Column returns the named column, or false when the table has none.

func (Table) CommentStatements

func (t Table) CommentStatements() []sql.Statement

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

func (t Table) CreateSQL(d sql.Dialect) (string, error)

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) DropSQL

func (t Table) DropSQL(d sql.Dialect) string

DropSQL returns the DROP TABLE statement for the table on dialect d.

func (Table) DropStatement

func (t Table) DropStatement() sql.DropTableStmt

DropStatement builds the DROP TABLE DDL node for the table.

func (Table) Key

func (t Table) Key() TableKey

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

func (t Table) PrimaryKeyColumns() []string

PrimaryKeyColumns returns the names of the table's primary-key columns, in column order.

func (Table) SQLTable

func (t Table) SQLTable() sql.Table

SQLTable returns the sql-package table reference for the table.

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

func (k TableKey) QualifiedName() string

QualifiedName returns the table name with an optional schema prefix.

func (TableKey) String

func (k TableKey) String() string

String renders the key as "schema.name#<short-checksum>" for diagnostics.

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

func Of(dialect, name string, length, precision, scale int) Type

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

func OfArray(dialect, name string, length, precision, scale int) Type

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.

Jump to

Keyboard shortcuts

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