Help us shape the future of Go! Take the 2026 Go Developer Survey

schema

package
v0.26.1 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

Native schema artifacts

EnsureTable remains a non-destructive, existence-based provisioning helper. Extract, Apply, and ApplySQL handle explicit same-dialect schema artifacts. They do not infer migrations or drop existing objects.

artifact, err := schema.Extract(ctx, sourceDB, schema.ExtractOptions{
    Tables: []string{"orders"}, // decoded literal names, not SQL paths
    IncludeDependencies: true,
})
if err != nil { return err }
result, err := schema.Apply(ctx, targetDB, artifact, schema.ApplyOptions{Atomic: true})

Tables is required. Constraints and indexes are in the default table scope; views and triggers are opt-in. IncludeDependencies includes referenced tables; otherwise an unselected foreign-key target is an error. Artifacts contain native ordered statements, object records, dialect/driver/schema, omissions, and SHA-256 of artifact.SQL(). Apply verifies a supplied checksum before executing SQL. An incomplete artifact requires explicit AllowPartial during extraction and again during application. Query failures remain errors with AllowPartial. No data rows are extracted. IncludeSequenceState separately requests current counters; identity/automatic-ID definitions are preserved by default.

Implemented extraction scope

Dialect Implementation and verification Explicit limits
SQLite Stored sqlite_schema table/index/view/trigger definitions. Executable roundtrip tests cover generated/default values, identities, numeric precision, ordered composite keys, foreign keys, indexes, quoted names, view/trigger behavior, and counters. Main schema only. Virtual tables/extensions are omitted with an error. Views include all source views; view/trigger dependencies conservatively require all user tables. IncludeDependencies permits that expansion. Missing view/trigger dependencies are checked by preparing EXPLAIN programs.
PostgreSQL 14+ Native catalog types, expressions, constraints and indexes; ordinary heap tables; owned serial/identity sequences and options; FK closure with a separate ALTER phase, including cycles. Live PostgreSQL 16 tests replay definitions and counters and exercise defaults and constraints. Inheritance, partitioning, row security, extensions/custom types, explicit collations, custom storage/compression/tablespaces/replica identity, shared/unowned sequences, and view/trigger extraction are unsupported. Foreign keys and owned sequences must stay in the selected schema. Extraction uses a read-only transaction and a local pg_catalog search_path.
MySQL Native SHOW CREATE TABLE plus foreign-key dependency discovery. Live MySQL 8 tests replay definitions and counters and exercise defaults and constraints. Cyclic foreign keys, cross-schema dependencies, views and triggers are unsupported. Current AUTO_INCREMENT table state is removed unless requested.
BigQuery Native INFORMATION_SCHEMA.TABLES.ddl preserves nested STRUCT/ARRAY definitions and native table options. Query-contract tests preserve returned DDL exactly. Always incomplete until index/FK dependency closure is certified; AllowPartial is required. Only native base-table DDL is exported. No live BigQuery certification.

Native SQL preserves its namespace semantics. PostgreSQL target schemas and BigQuery datasets must already exist. There is no schema remapping or cross-vendor conversion. Native statements are authoritative; the optional nested Field descriptor does not flatten BigQuery fields or reconstruct DDL from flat columns. The extractor expects a quiescent source. Grants, owners, routines, extensions, application functions, comments, and full-database backup/recreation are outside its requested table scope. PostgreSQL checks the connected server's server_version_num before reading its 14+ catalogs; a registry dialect's capability baseline is not its server version.

Execution

ApplySQL parses the complete script before execution. The script reader supports quoted strings/identifiers, comments, PostgreSQL dollar-quoted bodies and SQLite trigger blocks. Client DELIMITER/GO/backslash/dot commands, standalone executable MySQL comments, COPY streaming, lexical-setting changes and unquoted procedural blocks are rejected with a line number. PostgreSQL lexical rules assume standard_conforming_strings=on; use E strings for escaped quotes. MySQL scripts assume default string-escape rules. Sessions must use these lexical settings. Use one complete SQL statement per Artifact.Statements entry.

All statements use one pinned connection. Atomic uses an owned DDL transaction on SQLite/PostgreSQL. A supplied Tx is caller-owned and is never committed or rolled back; it cannot be combined with Atomic. MySQL/BigQuery transactional DDL requests are rejected. PostgreSQL sequence state and authored function effects retain their server-defined nontransactional behavior. On failure, Executed counts successful Exec calls, including any later rolled back. RolledBack reports an owned rollback; it makes no claim that a caller transaction has committed.

The optional live tests create and drop two uniquely named databases using an explicit admin DSN. Run only against an isolated server:

SQLX_SCHEMA_POSTGRES_DSN='postgres://user:password@localhost:5432/postgres?sslmode=disable' GOWORK=off go test ./io/schema -run TestLivePostgreSQL
SQLX_SCHEMA_MYSQL_DSN='user:password@tcp(localhost:3306)/mysql' GOWORK=off go test ./io/schema -run TestLiveMySQL

Documentation

Overview

Package schema provisions tables and extracts/applies explicit native schema artifacts.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = errors.New("schema feature unsupported")

ErrUnsupported identifies a dialect or requested schema feature without a faithful native extractor. AllowPartial returns its omissions in the artifact.

Functions

func SplitSQL added in v0.26.1

func SplitSQL(script string, dialect string) ([]string, error)

SplitSQL reads SQL, including quoted identifiers/strings, comments, PostgreSQL dollar quotes, and SQLite trigger BEGIN/END bodies. It rejects client commands (DELIMITER, GO, backslash commands), COPY FROM STDIN and unquoted procedural blocks outside SQLite triggers. PostgreSQL strings assume standard_conforming_strings is on; use E'...' for backslash escapes. MySQL strings use its default escape rules. Script settings that change lexical rules require explicit statements.

Types

type ApplyOptions added in v0.26.1

type ApplyOptions struct {
	Dialect      *info.Dialect
	Tx           *sql.Tx
	Atomic       bool
	AllowPartial bool
}

ApplyOptions controls DDL execution. A supplied Tx remains caller-owned and is never committed or rolled back. Atomic requests an owned DDL transaction and cannot be combined with Tx. SQLite and PostgreSQL support this option; MySQL and BigQuery DDL do not. Without either option all statements share one pinned connection and successful statements remain applied on a later failure. PostgreSQL sequence state and side effects of authored functions retain the server's nontransactional behavior even inside a transaction.

type ApplyResult added in v0.26.1

type ApplyResult struct {
	Executed          int
	Atomic            bool
	RolledBack        bool
	CallerTransaction bool
}

ApplyResult accounts for successful Exec calls, including calls subsequently rolled back. Executed does not claim that a caller-owned transaction committed. Atomic is true when statements ran inside an owned or caller transaction.

func Apply added in v0.26.1

func Apply(ctx context.Context, db *sql.DB, artifact *Artifact, opts ApplyOptions) (*ApplyResult, error)

Apply executes an artifact as authored, failing on existing objects or other SQL errors. It does not infer migrations, disable constraints, or reset tables.

func ApplySQL added in v0.26.1

func ApplySQL(ctx context.Context, db *sql.DB, script string, opts ApplyOptions) (*ApplyResult, error)

ApplySQL parses the entire script before executing its ordered statements.

type Artifact added in v0.26.1

type Artifact struct {
	Dialect    string
	Driver     string
	Schema     string
	Tables     []string
	Statements []string
	Objects    []Object
	Complete   bool
	Omissions  []Omission
	Checksum   string
}

Artifact is a same-dialect schema, not a migration or a database backup. Statements are complete native SQL statements in execution order. Checksum is SHA-256 of SQL(), including its final newline. Counters are opt-in and separate from identity definitions. Schema remapping is deliberately unsupported.

func Extract added in v0.26.1

func Extract(ctx context.Context, db *sql.DB, opts ExtractOptions) (*Artifact, error)

Extract returns native DDL for explicitly selected tables. On an unsupported feature it returns an incomplete artifact and an error unless AllowPartial. Database query errors are always errors, even with AllowPartial.

func (*Artifact) SQL added in v0.26.1

func (a *Artifact) SQL() string

SQL renders a deterministic script. Native statements may contain semicolons.

type ExtractOptions added in v0.26.1

type ExtractOptions struct {
	Dialect              *info.Dialect
	Schema               string
	Tables               []string
	IncludeDependencies  bool
	IncludeViews         bool
	IncludeTriggers      bool
	IncludeSequenceState bool
	AllowPartial         bool
}

ExtractOptions selects decoded, literal table names in one schema. A dot in a table name is part of that name. Constraints and indexes are always included. Dependencies are rejected unless IncludeDependencies is set. Views and triggers are opt-in. SQLite includes all views when requested; view/trigger dependencies conservatively require all user tables in the selected schema. Routines, grants, extensions and data are outside scope. Extraction requires a quiescent source; it does not lock concurrent DDL.

type Field added in v0.26.1

type Field struct {
	Name   string
	Type   string
	Mode   string
	Fields []Field `json:",omitempty"`
}

Field can describe nested native fields without flattening RECORD/STRUCTs. Native statements remain authoritative; extractors need not populate Fields.

type Object added in v0.26.1

type Object struct {
	Kind   string
	Name   string
	Table  string  `json:",omitempty"`
	Fields []Field `json:",omitempty"`
}

Object records one extracted object in execution order.

type Omission added in v0.26.1

type Omission struct {
	Object  string
	Feature string
	Reason  string
}

Omission describes an explicitly incomplete portion of the requested scope.

type Service

type Service struct {
	DB      *sql.DB
	Dialect *info.Dialect
}

Service provisions on the caller's native database. It does not own its lifetime, cache schema results, or begin a transaction (DDL may auto-commit).

func (*Service) EnsureTable

func (s *Service) EnsureTable(ctx context.Context, table Table) error

EnsureTable preserves an accessible existing table. Failed probes are followed by CREATE IF NOT EXISTS and another probe, never ALTER or DROP. A concurrent creator may win even when the vendor reports a catalog conflict on CREATE.

type Table

type Table struct {
	Name    string
	Dataset string
	Columns []io.Column
}

Table describes mapped columns and a parsed table destination. No raw DDL, default expressions, automatic IDs, migrations or destructive operations.

func (Table) CreateSQL

func (t Table) CreateSQL(dialect *info.Dialect) (string, error)

CreateSQL renders a create-if-absent statement using the native dialect.

Jump to

Keyboard shortcuts

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