migrate

package
v0.6.7 Latest Latest
Warning

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

Go to latest
Published: Jul 1, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package migrate generates SQLite migration SQL from a diff result. SQLite's ALTER TABLE is limited: only ADD COLUMN and RENAME are supported. Removed columns and type changes require a table-rebuild pattern.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EstimateRebuildLock

func EstimateRebuildLock(rows int64, indexes int) time.Duration

EstimateRebuildLock estimates the SQLite exclusive write-lock duration for a table rebuild. SQLite locks the entire database file for DDL — WAL mode does not help. Cost scales with rows copied plus re-creating every index.

Returns 0 for an empty table (instant) and -1 when the row count is unknown.

func New

func New(dir, name, body string) (string, error)

New creates the next migration file in dir with the given name and SQL body (which may be empty). It returns the created path.

func Restore

func Restore(dbPath, backupPath string) error

Restore overwrites dbPath with the contents of backupPath, removing stale WAL/SHM sidecars. The caller is responsible for verifying the backup's integrity first (e.g. via health.Inspect).

func SplitStatements

func SplitStatements(sqlText string) []string

SplitStatements splits SQL text into individual statements. It respects single/double-quoted strings and "--" line comments, and skips comment-only or empty fragments.

Types

type AppliedRecord

type AppliedRecord struct {
	Version   string `json:"version"`
	Name      string `json:"name"`
	Checksum  string `json:"checksum"`
	AppliedAt string `json:"applied_at"`
}

AppliedRecord is a row from the tracking table.

type ApplyOptions

type ApplyOptions struct {
	DryRun    bool   // execute inside a transaction, then roll back
	BackupDir string // where to write the pre-migration backup ("" = alongside the DB)
	NoBackup  bool   // skip backup (dry-run never backs up)
}

ApplyOptions controls how a migration is executed.

type ApplyResult

type ApplyResult struct {
	Executed   int    // statements executed
	BackupPath string // "" when no backup was taken
	Duration   time.Duration
	DryRun     bool
	Restored   bool // true when the backup was restored after a failure
}

ApplyResult reports what happened during Apply.

func Apply

func Apply(dbPath, sqlText string, opts ApplyOptions) (*ApplyResult, error)

Apply runs migration SQL against a local SQLite database.

Safety sequence:

  1. Pre-flight integrity check — refuse to migrate a corrupt database
  2. Backup via VACUUM INTO (unless dry-run or disabled)
  3. Execute all statements inside a single transaction
  4. Post-flight: PRAGMA foreign_key_check + integrity check inside the transaction
  5. Commit — or roll back on any failure; restore the backup if commit itself failed

type Migration

type Migration struct {
	Statements []Statement
	Warnings   []string // summary of destructive operations
}

func Generate

func Generate(d *diff.Result, newSchema *schema.Schema) *Migration

Generate produces migration SQL for the given diff result. It handles all schema changes, annotating destructive operations with warnings.

func (*Migration) HasWarnings

func (m *Migration) HasWarnings() bool

func (*Migration) SQL

func (m *Migration) SQL() string

type MigrationFile

type MigrationFile struct {
	Version  string `json:"version"` // zero-padded sequence, e.g. "0003"
	Name     string `json:"name"`    // human slug
	Path     string `json:"-"`
	Checksum string `json:"checksum"` // sha256 of file contents
}

MigrationFile is one file in the migrations directory.

func LoadDir

func LoadDir(dir string) ([]MigrationFile, error)

LoadDir reads and version-sorts the migration files in dir. A missing directory is treated as empty.

type OpKind

type OpKind int

OpKind classifies the blast radius of a migration operation.

const (
	OpSafe        OpKind = iota // ADD COLUMN, CREATE TABLE, CREATE/DROP INDEX — instant, no exclusive lock
	OpRisky                     // TABLE REBUILD without data loss — EXCLUSIVE write-lock for the rebuild duration
	OpDestructive               // DROP TABLE / DROP COLUMN / NOT-NULL-without-default — data loss or a guaranteed failure
)

func MaxKind

func MaxKind(ops []Operation) OpKind

MaxKind returns the highest severity among the operations (OpSafe for none).

func ParseOpKind

func ParseOpKind(s string) (OpKind, error)

ParseOpKind maps a severity name ("safe"/"risky"/"destructive") to an OpKind.

func (OpKind) Icon

func (k OpKind) Icon() string

func (OpKind) Label

func (k OpKind) Label() string

Label returns the lowercase severity name, used by the CI gate (--fail-on).

type Operation

type Operation struct {
	Table    string
	Kind     OpKind
	Icon     string // ✓ / ⚠ / ✗
	Headline string // one-line summary
	Detail   string // lock estimate, row count, or advice
	Rows     int64  // rows affected; -1 when unavailable
	LockMs   int64  // estimated exclusive write-lock in ms (rebuilds only); 0 otherwise
}

Operation describes one migration operation with its measured blast radius.

func AnalyzeAll

func AnalyzeAll(d *diff.Result, oldPath string) ([]Operation, error)

AnalyzeAll returns a full operation report — safe, risky, and destructive — for every table touched by the diff. This is the primary blast-radius API.

type Statement

type Statement struct {
	SQL     string
	Comment string // explains what the statement does or why
	Warning string // set when destructive or lossy
}

type Status

type Status struct {
	Applied []AppliedRecord `json:"applied"`
	Pending []MigrationFile `json:"pending"`
	// Drifted lists versions whose file checksum no longer matches what was
	// applied — the migration history itself changed.
	Drifted []string `json:"drifted,omitempty"`
}

Status compares the migrations directory against what a database has applied.

func GetStatus

func GetStatus(dbPath, dir string) (*Status, error)

GetStatus returns applied vs pending migrations for a database.

type UpResult

type UpResult struct {
	Applied []string `json:"applied"` // versions applied in this run
}

UpResult reports the outcome of applying pending migrations.

func Up

func Up(dbPath, dir string, opts ApplyOptions) (*UpResult, error)

Up applies every pending migration in order, each through the safe Apply pipeline (backup, single transaction, FK + integrity verification, rollback), recording it in the tracking table. It stops at the first failure. A checksum mismatch on an already-applied migration aborts before doing anything.

Jump to

Keyboard shortcuts

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