migration

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package migration is the ORM's schema migrations, Django's: Go files orm makemigrations writes into the program (migrations/NNNN_name.go, a package of their own), each registering a Migration of operations from its init. orm.Migrate applies the registered migrations at start up, orm migrate on demand, forwards or back.

import m "github.com/vuka-lang/orm/migration"

func init() {
	m.Register(m.Migration{
		Name:         "0002_users_email",
		Dependencies: []string{"0001_initial"},
		Operations: []m.Operation{
			m.AddField{Table: "users", Name: "email", Field: m.Varchar(255).Unique().Null()},
		},
	})
}

The schema a database has is the replay of its migrations: no snapshot file is kept, and makemigrations compares the replay with the models the program declares.

Index

Constants

View Source
const (
	Cascade  = "cascade"
	SetNull  = "set_null"
	Restrict = "restrict"
)

The actions of OnDelete.

View Source
const Noop = "-- nothing to undo"

Noop is a RunSQL's ReverseSQL that does nothing.

Variables

This section is empty.

Functions

func Describe

func Describe(op Operation) string

Describe is what op does, for people: "add field users.email".

func Leaves

func Leaves(ordered []Migration, db string) []string

Leaves is the names of db's migrations none of its others depends on: what the next one depends on.

func Register

func Register(mg Migration)

Register adds a migration to the program's: a migrations package calls it from each file's init. A second migration of one database and name panics.

func Source

func Source(pkg string, mg Migration, notes []string) ([]byte, error)

Source is the Go file registering mg in package pkg, as orm makemigrations writes it: notes[i] ("" for none) is a comment above operation i.

Types

type AddConstraint

type AddConstraint struct {
	Table      string
	Constraint Constraint
}

AddConstraint adds a unique or check constraint to a table.

type AddField

type AddField struct {
	Table, Name string
	Field       Field
}

AddField adds a column to a table.

type AddIndex

type AddIndex struct {
	Table string
	Index Index
}

AddIndex makes a declared index.

type AlterField

type AlterField struct {
	Table, Name string
	Field       Field
}

AlterField changes a column's definition: its type, nullability, default, key, foreign key, generated expression.

type AlterModelTable

type AlterModelTable = RenameModel

AlterModelTable is RenameModel, by Django's name for changing a model's table: here a model is its table.

type Constraint

type Constraint = schema.Constraint

Constraint is a table's unique constraint (Unique) or check constraint (Check).

func Check

func Check(name, expr string) Constraint

Check is a check constraint: rows must satisfy expr, SQL.

func Unique

func Unique(name string, columns ...string) Constraint

Unique is a unique constraint over columns, Django's unique_together.

type CreateExtension

type CreateExtension struct{ Name string }

CreateExtension installs a Postgres extension ("vector", "pg_trgm"); other databases have none, and it does nothing there.

type CreateFunction

type CreateFunction struct {
	Name            string
	Params, Returns Dialects
	Body            Dialects
	Language        string
	Volatile        bool // the result may differ for the same arguments: not IMMUTABLE / DETERMINISTIC
}

CreateFunction creates a function written in SQL on Postgres and MySQL, for an orm.Func to call; unapplying it drops it. SQLite runs no functions written in SQL — register a Go one with orm/sqlite's Func — and a dialect whose Body is empty gets nothing. Params and Returns are spelt as each database spells them; Body is Postgres's function body in Language (sql when empty: a SELECT or an expression's RETURN) and MySQL's routine body (RETURN …, or BEGIN … END, run whole).

m.CreateFunction{
	Name:    "initials",
	Params:  m.Dialects{Postgres: "s text", MySQL: "s VARCHAR(255)"},
	Returns: m.Dialects{Postgres: "text", MySQL: "VARCHAR(255)"},
	Body:    m.Dialects{Postgres: "SELECT upper(left(s, 1))", MySQL: "RETURN UPPER(LEFT(s, 1))"},
}

type CreateModel

type CreateModel struct {
	Table       string
	Fields      []NamedField
	Constraints []Constraint
	Indexes     []Index
}

CreateModel creates a table.

type DeleteModel

type DeleteModel struct{ Table string }

DeleteModel drops a table.

type Dialects

type Dialects = schema.Dialects

Dialects is SQL written for each dialect: "" where a dialect has none.

type Field

type Field struct {
	// contains filtered or unexported fields
}

Field is a column's definition: a kind (BigAuto, Varchar, Time, …) and what its methods add.

func Auto

func Auto() Field

func BigAuto

func BigAuto() Field

The kinds of column.

func BigInt

func BigInt() Field

func Bool

func Bool() Field

func Bytes

func Bytes() Field

func Custom

func Custom() Field

func Date added in v0.5.0

func Date() Field

func Float

func Float() Field

func Float32

func Float32() Field

func Int

func Int() Field

func JSON

func JSON() Field

func SmallInt added in v0.5.0

func SmallInt() Field

func TSVector

func TSVector() Field

func Text

func Text() Field

func Time

func Time() Field

func UUID added in v0.5.0

func UUID() Field

func Varchar

func Varchar(size int) Field

func Vector

func Vector(dims int) Field

Vector is a pgvector column of dims dimensions (0: any).

func (Field) Auto added in v0.5.0

func (f Field) Auto() Field

Auto makes an integer key one the database counts.

func (Field) Collation added in v0.5.0

func (f Field) Collation(name string) Field

Collation is a text column's collation.

func (Field) Comment added in v0.5.0

func (f Field) Comment(s string) Field

Comment is the column's comment (Postgres, MySQL).

func (Field) Default

func (f Field) Default(v any) Field

Default is the value rows written without the column take, and rows that exist when it is added: a string, number, bool or nil.

func (Field) DefaultSQL

func (f Field) DefaultSQL(expr string) Field

DefaultSQL is Default as an SQL expression of your own.

func (Field) FK

func (f Field) FK(table, ref string) Field

FK makes the column a foreign key to table's column ref.

func (Field) Generated

func (f Field) Generated(expr Dialects) Field

Generated makes the column a stored generated column, computed by the expression of each dialect.

func (Field) Index

func (f Field) Index() Field

Index indexes the column.

func (Field) Null

func (f Field) Null() Field

Null lets the column hold NULL.

func (Field) OnDelete

func (f Field) OnDelete(action string) Field

OnDelete is what deleting the row a foreign key refers to does: one of Cascade, SetNull, Restrict.

func (Field) PK

func (f Field) PK() Field

PK makes the column (one of) the primary key.

func (Field) Precision added in v0.5.0

func (f Field) Precision(n int) Field

Precision is a timestamp's fractional digits, 1 to 6.

func (Field) Type

func (f Field) Type(sql string) Field

Type is the column's database type, over its kind's.

func (Field) Types added in v0.5.0

func (f Field) Types(t Dialects) Field

Types is the column's type on each dialect, over its kind's: a field type's ColumnType.

func (Field) Unique

func (f Field) Unique() Field

Unique makes the column unique.

func (Field) Unsigned added in v0.5.0

func (f Field) Unsigned() Field

Unsigned makes an integer column UNSIGNED on MySQL.

type Index

type Index = schema.Index

Index is an index a model declares (GIN, HNSW, IVFFlat, FULLTEXT, a SearchVector's), as the statement making it on each dialect: none where it has no SQL (SQLite makes none of them).

type Migration

type Migration struct {
	Name string // NNNN_words, unique within its database
	DB   string // the database's name (orm.AddDatabase); "" the default
	// Dependencies is the migrations applied before it: names of its
	// database's, or "<db>:<name>" of another's (":<name>" the default's).
	Dependencies []string
	Operations   []Operation
}

Migration is one step of a database's schema: its operations, applied in order, after the migrations it depends on.

func Find

func Find(ordered []Migration, db, name string) (Migration, error)

Find is db's migration among ordered whose name is name, or starts with it (0002 for 0002_users_email) when one does.

func Of

func Of(ordered []Migration, db string) []Migration

Of is the migrations of database db among ordered, in their order.

func Order

func Order(list []Migration) ([]Migration, error)

Order is list ordered as Ordered orders the registered migrations.

func Ordered

func Ordered() ([]Migration, error)

Ordered is every registered migration, each after its dependencies (by database and name where none orders them).

func (Migration) Apply

func (mg Migration) Apply(s *State) error

Apply plays mg's operations on s.

func (Migration) Backwards

func (mg Migration) Backwards(dialect string, s *State) ([]Step, error)

Backwards is the steps unapplying mg on dialect, s the state its database was in before mg (left as it is): its operations' reverses, last first.

func (Migration) Forwards

func (mg Migration) Forwards(dialect string, s *State) ([]Step, error)

Forwards is the steps applying mg on dialect, from the state s its database is in; s is left as mg leaves it.

type NamedField

type NamedField struct {
	Name  string
	Field Field
}

NamedField is a column of CreateModel: its name and Field.

func F

func F(name string, f Field) NamedField

F is the column name defined by f.

type Operation

type Operation interface {
	// contains filtered or unexported methods
}

Operation is a change of the schema: what it does to the state, and the SQL doing it, forwards and back.

func Diff

func Diff(from, to *State, ask func(question string) bool) ([]Operation, []string)

Diff is the operations taking a database from the state from (its migrations replayed) to to (the models the program declares), and a note beside each that needs a person ("" for none). A table or column gone where one alike appeared may have been renamed: ask is asked (Did you rename users.mail to users.email?) and on yes the operation is a rename, else a removal and an addition. A column's default is the model's where it declares one, else the migrations' is kept (the value an AddField gave the rows that existed); a table's check constraints are the migrations' alone.

type RemoveConstraint

type RemoveConstraint struct{ Table, Name string }

RemoveConstraint drops a unique or check constraint of a table.

type RemoveField

type RemoveField struct{ Table, Name string }

RemoveField drops a column of a table, and its data.

type RemoveIndex

type RemoveIndex struct{ Table, Name string }

RemoveIndex drops a declared index.

type RenameField

type RenameField struct{ Table, Old, New string }

RenameField renames a column, its data kept.

type RenameModel

type RenameModel struct{ Old, New string }

RenameModel renames a table, its rows kept: the constraints and indexes keep their names, the foreign keys referring to it follow.

type RunGo

type RunGo struct {
	Forward, Backward func(ctx context.Context, tx Tx) error
}

RunGo runs Go code, a data migration, in the migration's transaction: tx runs SQL in it, and the ORM's queries on ctx do too. Backward undoes it; nil, the migration can't be unapplied. It sees the database as the operations before it leave it, so query it in SQL, or with models that match that schema.

type RunSQL

type RunSQL struct {
	SQL, ReverseSQL string
	Dialect         string
}

RunSQL runs SQL of your own (statements ending with semicolons), on every dialect or on Dialect's alone. ReverseSQL undoes it: empty, the migration can't be unapplied; Noop, there is nothing to undo.

type State

type State struct {
	// contains filtered or unexported fields
}

State is a database's schema as its migrations leave it: its tables and extensions.

func NewState

func NewState(tables []schema.Table, exts []string) *State

NewState is a state of tables and extensions.

func Replay

func Replay(ordered []Migration, db string) (*State, error)

Replay is the state of database db after the migrations of it among ordered.

func (*State) Clone

func (s *State) Clone() *State

Clone is a copy of s.

func (*State) Tables

func (s *State) Tables() []schema.Table

Tables is the state's tables.

type Step

type Step struct {
	SQL string
	Go  func(ctx context.Context, tx Tx) error
}

Step is a statement (or several, a RunSQL's) applying an operation, or Go code a RunGo runs. A step with both runs its Go, and shows its SQL.

type Tx

type Tx interface {
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

Tx is where a RunGo runs: the migration's transaction (MySQL, which can't roll DDL back, its connection).

Jump to

Keyboard shortcuts

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