Documentation
¶
Overview ¶
Package grizzle provides declarative, in-process database schema automigration for Go.
Grizzle synchronizes PostgreSQL and SQLite database schemas directly from standard schema.sql DDL definitions on application startup, eliminating sequence file collisions, manual migration versioning, and external CLI/Docker runtime dependencies.
Core Concepts ¶
- Declarative Schema: Write standard SQL DDL (schema.sql) as the single source of truth.
- In-Process Execution: Runs natively within your Go binary without needing external CLI binaries.
- Shadow Sandbox: Replays and validates desired schema state inside a temporary shadow schema or SQLite in-memory sandbox.
- Deterministic Diff: Pure schema comparison detecting missing tables, columns, indexes, constraints, and types.
- Safe Execution: Dedicated advisory locking, multi-node contention retry, hazard gating, and transactional execution.
- Zero-Downtime Operations: Safe non-transactional enum expansions (PostgreSQL ALTER TYPE ... ADD VALUE) and concurrent index generation.
Subpackages & Modules ¶
- griztest: Testing primitives (MustSync, MustPlan, Reset) for effortless test database setup and teardown.
- otelgrizzle: Optional OpenTelemetry tracing integration (github.com/muandane/grizzle/otelgrizzle).
Basic Usage ¶
db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = grizzle.Sync(ctx, db, grizzle.Options{
SchemaSQL: schemaSQL,
})
if err != nil {
log.Fatalf("migration failed: %v", err)
}
Index ¶
- Constants
- Variables
- func Apply(ctx context.Context, db *sql.DB, p *Plan, opts ApplyOpts) error
- func BuildIdempotentInsert(table string, columns []string, conflictTarget string, updateColumns ...string) string
- func Check(ctx context.Context, db *sql.DB, opts Options) error
- func Dump(ctx context.Context, db *sql.DB, opts DumpOptions) (string, error)
- func GenerateLockID(dbName, schemaName string) int64
- func IsReady(ctx context.Context, db *sql.DB, opts ...Option) (bool, error)
- func LintFormatGitHub(w io.Writer, diags []LintDiagnostic) error
- func LintFormatJSON(w io.Writer, diags []LintDiagnostic) error
- func LintFormatText(w io.Writer, diags []LintDiagnostic) error
- func LintHasErrors(diags []LintDiagnostic) bool
- func Seed(ctx context.Context, db *sql.DB, seedSQL string, opts ...Option) error
- func SeedHash(seedSQL string) string
- func Sync(ctx context.Context, db *sql.DB, opts Options) error
- type ApplyOpts
- type BackfillFunc
- type BaselineOptions
- type ChangeType
- type CheckConstraintIR
- type ColumnIR
- type CompositeAttributeIR
- type CompositeTypeIR
- type DependencyRef
- type DestructiveViolationError
- type Dialect
- type DriftError
- type DropPolicy
- type DryRunResult
- type DumpOptions
- type EnumIR
- type ExportArtifact
- type ExportFormat
- type ExtensionIR
- type ForeignKeyIR
- type GeneratedColumn
- type Hazard
- type HazardCode
- type HazardError
- type HazardLevel
- type HistoryEntry
- type HistoryOptions
- type HookContext
- type IndexIR
- type LintDiagnostic
- type LintRule
- type LintSeverity
- type LockConflict
- type LockContentionError
- type Metrics
- type Option
- func WithAcceptHazards(hazards ...plan.HazardCode) Option
- func WithAfterStep(fn StepHook) Option
- func WithAfterSync(fn SyncHook) Option
- func WithAllowDrop(allow bool) Option
- func WithAllowResumePartial(allow bool) Option
- func WithBackfill(fn BackfillFunc) Option
- func WithBeforeStep(fn StepHook) Option
- func WithBeforeSync(fn SyncHook) Option
- func WithDevDatabaseURL(url string) Option
- func WithDialect(d Dialect) Option
- func WithDryRun() Option
- func WithDryRunLockTimeout(d time.Duration) Option
- func WithExcludeTables(tables ...string) Option
- func WithExecuteHooksInDryRun() Option
- func WithExpandContract(expand bool) Option
- func WithExpectedHash(hash string) Option
- func WithFailOnContention(fail bool) Option
- func WithIncludeTables(tables ...string) Option
- func WithLockNamespace(ns string) Option
- func WithLockTimeout(d time.Duration) Option
- func WithLogger(l *slog.Logger) Option
- func WithMaxRetries(n int) Option
- func WithMetrics(m Metrics) Option
- func WithNonConcurrentIndexes(disabled bool) Option
- func WithRandFloat(fn func() float64) Option
- func WithRenames(renames map[string]string) Option
- func WithSQLiteAttach(attach map[string]string) Option
- func WithSQLiteRebuildBatching(threshold, batchSize int) Option
- func WithSeedForce(force bool) Option
- func WithSeedSQL(seedSQL string) Option
- func WithStatementTimeout(d time.Duration) Option
- func WithStrictScope(strict bool) Option
- func WithTargetSchema(schema string) Option
- func WithTargetSchemaPattern(pattern string) Option
- func WithTargetSchemas(schemas ...string) Option
- func WithTracer(t Tracer) Option
- type Options
- type PartitionKey
- type PartitionOf
- type PartitionStrategy
- type Plan
- type PlanDocument
- type PolicyIR
- type PrimaryKeyIR
- type RangeTypeIR
- type RepairOptions
- type RoutineIR
- type SchemaIR
- type ScopeDocument
- type SequenceIR
- type Span
- type StatusReport
- type Step
- type StepHook
- type SyncHook
- type TableIR
- type Tracer
- type TriggerIR
- type UnmanagedKind
- type UnmanagedObject
- type ViewIR
Examples ¶
Constants ¶
const ( // PartitionStrategyRange indicates range-based partitioning. PartitionStrategyRange = schema.PartitionStrategyRange // PartitionStrategyList indicates list-based partitioning. PartitionStrategyList = schema.PartitionStrategyList // PartitionStrategyHash indicates hash-based partitioning. PartitionStrategyHash = schema.PartitionStrategyHash )
PartitionStrategy constants
const ( ChangeCreateEnum = plan.ChangeCreateEnum ChangeAlterEnum = plan.ChangeAlterEnum ChangeRenameEnumValue = plan.ChangeRenameEnumValue ChangeDropEnumValue = plan.ChangeDropEnumValue ChangeCreateTable = plan.ChangeCreateTable ChangeDropTable = plan.ChangeDropTable ChangeAddColumn = plan.ChangeAddColumn ChangeDropColumn = plan.ChangeDropColumn ChangeAlterColumn = plan.ChangeAlterColumn ChangeCreateIndex = plan.ChangeCreateIndex ChangeDropIndex = plan.ChangeDropIndex ChangeAddFK = plan.ChangeAddFK ChangeDropFK = plan.ChangeDropFK ChangeAddCheck = plan.ChangeAddCheck ChangeDropCheck = plan.ChangeDropCheck ChangeValidateConstraint = plan.ChangeValidateConstraint ChangeRenameColumn = plan.ChangeRenameColumn ChangeAttachPartition = plan.ChangeAttachPartition ChangeDetachPartition = plan.ChangeDetachPartition ChangeCreateExtension = plan.ChangeCreateExtension ChangeDropExtension = plan.ChangeDropExtension ChangeEnableRLS = plan.ChangeEnableRLS ChangeDisableRLS = plan.ChangeDisableRLS ChangeForceRLS = plan.ChangeForceRLS ChangeNoForceRLS = plan.ChangeNoForceRLS ChangeCreatePolicy = plan.ChangeCreatePolicy ChangeAlterPolicy = plan.ChangeAlterPolicy ChangeDropPolicy = plan.ChangeDropPolicy ChangeCreateFunction = plan.ChangeCreateFunction ChangeDropFunction = plan.ChangeDropFunction ChangeCreateTrigger = plan.ChangeCreateTrigger ChangeDropTrigger = plan.ChangeDropTrigger ChangeCreateView = plan.ChangeCreateView ChangeDropView = plan.ChangeDropView ChangeRefreshMatView = plan.ChangeRefreshMatView ChangeCreateRangeType = plan.ChangeCreateRangeType ChangeDropRangeType = plan.ChangeDropRangeType ChangeDropRangeRetype = plan.ChangeDropRangeRetype ChangeCreateCompositeType = plan.ChangeCreateCompositeType ChangeAlterCompositeType = plan.ChangeAlterCompositeType ChangeDropCompositeType = plan.ChangeDropCompositeType ChangeDropCompositeRetype = plan.ChangeDropCompositeRetype ChangeCreateSequence = plan.ChangeCreateSequence ChangeAlterSequence = plan.ChangeAlterSequence ChangeDropSequence = plan.ChangeDropSequence )
ChangeType constants
const ( HazardDropTable = plan.HazardDropTable HazardDropColumn = plan.HazardDropColumn HazardDropEnumValue = plan.HazardDropEnumValue HazardTypeNarrow = plan.HazardTypeNarrow HazardNotNullNoDefault = plan.HazardNotNullNoDefault HazardIndexBuild = plan.HazardIndexBuild HazardDropIndex = plan.HazardDropIndex HazardDropFK = plan.HazardDropFK HazardDropCheck = plan.HazardDropCheck HazardCheckValidateScan = plan.HazardCheckValidateScan HazardRenameAmbiguous = plan.HazardRenameAmbiguous HazardUnmanagedDependency = plan.HazardUnmanagedDependency HazardGeneratedRewrite = plan.HazardGeneratedRewrite HazardPartitionAttachScan = plan.HazardPartitionAttachScan HazardPartitionPendingDetach = plan.HazardPartitionPendingDetach HazardExtensionPrivilege = plan.HazardExtensionPrivilege HazardDropExtension = plan.HazardDropExtension HazardRLSEnable = plan.HazardRLSEnable HazardDropPolicy = plan.HazardDropPolicy HazardDropFunction = plan.HazardDropFunction HazardSecurityDefiner = plan.HazardSecurityDefiner HazardDropTrigger = plan.HazardDropTrigger HazardDropView = plan.HazardDropView HazardDropDomain = plan.HazardDropDomain HazardDropRangeType = plan.HazardDropRangeType HazardDropCompositeType = plan.HazardDropCompositeType HazardDropSequence = plan.HazardDropSequence )
HazardCode constants
const ( // UnmanagedView indicates a standard SQL VIEW. UnmanagedView = schema.UnmanagedView // UnmanagedMaterialized indicates a MATERIALIZED VIEW. UnmanagedMaterialized = schema.UnmanagedMaterialized // UnmanagedTrigger indicates a database trigger attached to a table. UnmanagedTrigger = schema.UnmanagedTrigger // UnmanagedFunction indicates a stored procedure or function. UnmanagedFunction = schema.UnmanagedFunction // UnmanagedSequence indicates an unmanaged database sequence. UnmanagedSequence = schema.UnmanagedSequence // UnmanagedEnum indicates an unmanaged custom enum type. UnmanagedEnum = schema.UnmanagedEnum // UnmanagedDomain indicates an unmanaged domain type. UnmanagedDomain = schema.UnmanagedDomain )
const ( HazardLevelCritical = plan.HazardLevelCritical HazardLevelWarning = plan.HazardLevelWarning HazardLevelNotice = plan.HazardLevelNotice )
HazardLevel constants
const ( // ExportFormatSQL targets raw SQL files with transaction markers. ExportFormatSQL = export.FormatSQL // ExportFormatGoose targets Goose-compatible migration files. ExportFormatGoose = export.FormatGoose // ExportFormatAtlas targets Atlas-compatible migration files. ExportFormatAtlas = export.FormatAtlas // ExportFormatMigrate targets golang-migrate compatible (.up.sql / .down.sql) migration files. ExportFormatMigrate = export.FormatMigrate // ExportFormatGolangMigrate is an alias for ExportFormatMigrate. ExportFormatGolangMigrate = export.FormatGolangMigrate )
const ( // LintSeverityError marks a structural anti-pattern that must be fixed. LintSeverityError = lint.SeverityError // LintSeverityWarning marks a recommendation that may be ignored deliberately. LintSeverityWarning = lint.SeverityWarning // LintSeverityInfo marks a stylistic suggestion with no correctness impact. LintSeverityInfo = lint.SeverityInfo )
Variables ¶
var ( // ErrEmptySchema is returned when the provided SchemaSQL string is empty or contains only whitespace. ErrEmptySchema = plan.ErrEmptySchema // ErrDestructiveBlocked is returned when a destructive operation (such as DROP TABLE or DROP COLUMN) // is rejected by the configured drop safety policy. ErrDestructiveBlocked = plan.ErrDestructiveBlocked // ErrLockAcquisition is returned when acquiring the database advisory lock fails or times out. ErrLockAcquisition = plan.ErrLockAcquisition // ErrCompilationFailed is returned when the user's schema.sql fails to compile/execute inside the shadow schema. ErrCompilationFailed = plan.ErrCompilationFailed // ErrExecutionFailed is returned when applying the planned DDL migration steps to the target schema fails. ErrExecutionFailed = plan.ErrExecutionFailed // ErrInspectionFailed is returned when inspecting the schema metadata fails. ErrInspectionFailed = plan.ErrInspectionFailed // ErrUnsupportedDialect is returned when an unrecognized database driver or dialect is provided. ErrUnsupportedDialect = plan.ErrUnsupportedDialect // ErrHazardBlocked is returned when a migration plan contains critical hazards not explicitly accepted in AcceptHazards. ErrHazardBlocked = plan.ErrHazardBlocked // ErrPlanDrift is returned when the approved plan hash differs from the recomputed plan hash after lock acquisition. ErrPlanDrift = plan.ErrPlanDrift // ErrDrift is returned by Check when the live database schema differs from the desired schema. ErrDrift = plan.ErrDrift // ErrLockTimeout is returned when an advisory lock cannot be acquired within the configured lock timeout. ErrLockTimeout = plan.ErrLockTimeout // ErrLockContention is returned when conflicting locks are held on target tables during pre-flight check. ErrLockContention = plan.ErrLockContention // ErrInvalidOptions is returned when provided Options fail validation. ErrInvalidOptions = plan.ErrInvalidOptions // ErrNoMatchingSchemas is returned when TargetSchemaPattern matches zero schemas. ErrNoMatchingSchemas = plan.ErrNoMatchingSchemas // ErrStrictScope is returned when StrictScope is enabled but no IncludeTables are specified. ErrStrictScope = plan.ErrStrictScope // ErrPartitionConversion is returned when attempting to convert a regular table to a partitioned table or vice versa in-place. ErrPartitionConversion = plan.ErrPartitionConversion // ErrUnsupportedMultiSchema is returned when CompileSchema cannot compile // multiple PostgreSQL schemas in one shadow (SQLite multi-schema uses ATTACH). ErrUnsupportedMultiSchema = plan.ErrUnsupportedMultiSchema // ErrPartitionKeyNotInUnique is returned when a primary key or unique constraint on a partitioned table does not include all partition key columns. ErrPartitionKeyNotInUnique = plan.ErrPartitionKeyNotInUnique // ErrAfterSyncFailed is returned when the AfterSync hook fails after the migration steps have already committed. ErrAfterSyncFailed = plan.ErrAfterSyncFailed // ErrSeedFailed is returned when seed SQL execution fails; the seed // transaction is rolled back and the schema is left intact. ErrSeedFailed = plan.ErrSeedFailed // ErrHistoryRecord is returned when the migration succeeded but the // grizzle_history record could not be written (non-fatal; detect with // errors.Is). ErrHistoryRecord = plan.ErrHistoryRecord // ErrPriorFailureBlocked is returned by Sync when the latest recorded migration // in grizzle_history is in a 'partial' or 'failed' state and AllowResumePartial is false. ErrPriorFailureBlocked = plan.ErrPriorFailureBlocked // ErrNoFailedMigration is returned by Repair when no partial or failed migration was found to resolve. ErrNoFailedMigration = plan.ErrNoFailedMigration // ErrBaselineDrift is returned by Baseline when the live database differs from desired schema and Force is false. ErrBaselineDrift = plan.ErrBaselineDrift // ErrTransactionPooling is returned when transaction-mode pooling (e.g., PgBouncer) // prevents session-level advisory lock acquisition. ErrTransactionPooling = plan.ErrTransactionPooling )
Functions ¶
func Apply ¶
Apply applies an approved migration plan to the database. If ExpectedHash is provided and the plan recomputed post-lock differs, Apply aborts with ErrPlanDrift.
func BuildIdempotentInsert ¶
func BuildIdempotentInsert(table string, columns []string, conflictTarget string, updateColumns ...string) string
BuildIdempotentInsert builds a canonical idempotent INSERT statement skeleton with conflict handling for seed data.
Formats: INSERT INTO "table" ("col1", "col2") VALUES ... ON CONFLICT ...
- If conflictTarget == "": appends ON CONFLICT DO NOTHING;
- If conflictTarget != "" and len(updateColumns) == 0: appends ON CONFLICT (<conflictTarget>) DO NOTHING;
- If conflictTarget != "" and len(updateColumns) > 0: appends ON CONFLICT (<conflictTarget>) DO UPDATE SET <col> = EXCLUDED.<col>, ...;
Standard Idempotent Seed Patterns:
Unconditional ignore (blank conflictTarget): Useful when unique constraints or primary keys should silently prevent duplicates without needing specific target specification. Example: BuildIdempotentInsert("roles", []string{"name"}, "") // Output: INSERT INTO "roles" ("name") VALUES ... ON CONFLICT DO NOTHING;
Targeted ignore (conflictTarget specified, no updateColumns): Ignores conflict on a specific key or unique constraint. Example: BuildIdempotentInsert("users", []string{"id", "email"}, "id") // Output: INSERT INTO "users" ("id", "email") VALUES ... ON CONFLICT (id) DO NOTHING;
Upsert / update on conflict (conflictTarget and updateColumns specified): Updates specified mutable columns from EXCLUDED values on conflict. Example: BuildIdempotentInsert("users", []string{"id", "name", "email"}, "id", "name", "email") // Output: INSERT INTO "users" ("id", "name", "email") VALUES ... ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, email = EXCLUDED.email;
func Check ¶
Check inspects the live database and returns ErrDrift (wrapped in DriftError) if the schema differs from the desired schema specified in opts.SchemaSQL. It is strictly read-only, never modifies the database, and never auto-fixes drift.
func GenerateLockID ¶
GenerateLockID produces a deterministic 64-bit integer lock ID from db and schema names.
func IsReady ¶ added in v0.2.0
IsReady checks whether the database is ready for application traffic by inspecting the latest migration state in grizzle_history. It reads migration state only with zero side effects (no DDL, no table creation) and without acquiring any advisory locks.
It returns:
- (true, nil) if the latest migration record has status "applied" or "baseline".
- (false, nil) if grizzle_history does not exist, is empty, or the latest record has a non-ready status ("partial", "failed", "in_progress").
- (false, err) if database connectivity or the query fails.
func LintFormatGitHub ¶
func LintFormatGitHub(w io.Writer, diags []LintDiagnostic) error
LintFormatGitHub renders diagnostics as GitHub Actions annotations.
func LintFormatJSON ¶
func LintFormatJSON(w io.Writer, diags []LintDiagnostic) error
LintFormatJSON renders diagnostics as a JSON array.
func LintFormatText ¶
func LintFormatText(w io.Writer, diags []LintDiagnostic) error
LintFormatText renders diagnostics as human-readable text.
func LintHasErrors ¶
func LintHasErrors(diags []LintDiagnostic) bool
LintHasErrors reports whether any diagnostic has severity ERROR.
func Seed ¶
Seed executes idempotent seed SQL against the database. The seed runs in a single transaction: either the whole script commits with an 'applied' grizzle_history record keyed by the seed's content hash, or nothing persists. If the same seed hash was already applied and force is false, the seed is skipped. Forced re-runs execute the script again, so seed scripts should tolerate re-execution (IF NOT EXISTS, ON CONFLICT...).
Dialect and target schema are taken from opts (auto-detected when unset).
func SeedHash ¶
SeedHash returns the deterministic sha256 identity of a seed script. Leading and trailing whitespace is ignored so reformatted-but-identical seeds do not re-run.
func Sync ¶
Sync synchronizes the target database schema to match the desired state in opts.SchemaSQL.
Example ¶
package main
import (
"context"
"database/sql"
"fmt"
"log"
"github.com/muandane/grizzle"
_ "modernc.org/sqlite"
)
func main() {
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
log.Fatalf("failed to open database: %v", err)
}
defer func() { _ = db.Close() }()
schema := `
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL
);`
err = grizzle.Sync(context.Background(), db, grizzle.Options{
Dialect: grizzle.DialectSQLite,
SchemaSQL: schema,
})
if err != nil {
log.Fatalf("sync failed: %v", err)
}
var count int
_ = db.QueryRow("SELECT count(*) FROM users;").Scan(&count)
fmt.Printf("Users table exists with row count: %d\n", count)
}
Output: Users table exists with row count: 0
Types ¶
type ApplyOpts ¶
type ApplyOpts struct {
// ExpectedHash is the approved plan hash. If non-empty, Apply recomputes the plan after
// acquiring the lock and verifies the recomputed hash matches ExpectedHash.
// If it does not match, Apply aborts with ErrPlanDrift.
ExpectedHash string
// AcceptHazards specifies explicitly accepted critical hazards.
AcceptHazards []HazardCode
// Backfill hook function run outside the DDL lock window in batches during staged expand migration.
Backfill BackfillFunc
// BeforeSync runs once before any migration steps or locks are executed.
BeforeSync SyncHook
// AfterSync runs once after all migration steps and history recording succeed.
AfterSync SyncHook
// BeforeStep executes immediately prior to executing each plan step.
BeforeStep StepHook
// AfterStep executes immediately following the successful execution of each plan step.
AfterStep StepHook
// SQLiteRebuildThreshold defines the row count threshold above which SQLite table rebuilds
// chunk data copying by keyset. Defaults to 100000.
SQLiteRebuildThreshold int
// SQLiteRebuildBatchSize defines the chunk size when copying data in batches during SQLite table rebuilds.
// Defaults to 10000.
SQLiteRebuildBatchSize int
// SQLiteAttach maps ATTACH DATABASE schema names to filesystem paths for
// multi-schema SQLite Apply. Not carried in the plan artifact.
SQLiteAttach map[string]string
// LockNamespace specifies the application namespace string used for PostgreSQL advisory locking (defaults to "grizzle").
LockNamespace string
// DevDatabaseURL optionally specifies an external database connection URL
// used for shadow schema compilation during plan verification.
DevDatabaseURL string
// FailOnContention gates DDL execution on PostgreSQL: if concurrent sessions hold conflicting
// locks on target tables, retry with backoff up to LockTimeout; if contention persists, abort
// with ErrLockContention instead of proceeding. When false (default), lock contention is advisory
// and logs a warning before proceeding.
FailOnContention bool
// Logger receives structured migration logs during Apply (defaults to no logging).
// The plan artifact cannot carry a logger, so it is supplied here.
Logger *slog.Logger
// Tracer specifies an optional tracer for observing plan application.
Tracer Tracer
// Metrics specifies an optional metrics recorder for observing plan application.
Metrics Metrics
}
ApplyOpts configures verification and execution parameters when applying an approved Plan.
type BackfillFunc ¶
BackfillFunc defines the hook function signature for batch backfilling columns outside the DDL lock window.
type BaselineOptions ¶
type BaselineOptions struct {
TargetSchema string
Note string
Force bool // If true, record baseline even if unapplied changes exist
DevDatabaseURL string
}
BaselineOptions configures baselining an existing database.
type ChangeType ¶
type ChangeType = plan.ChangeType
ChangeType describes the classification of a schema change.
type CheckConstraintIR ¶
type CheckConstraintIR = schema.CheckConstraint
CheckConstraintIR represents the intermediate representation of a CHECK constraint.
type CompositeAttributeIR ¶
type CompositeAttributeIR = schema.CompositeAttribute
CompositeAttributeIR represents the intermediate representation of an attribute in a composite type.
type CompositeTypeIR ¶
type CompositeTypeIR = schema.CompositeType
CompositeTypeIR represents the intermediate representation of a composite type.
type DependencyRef ¶
type DependencyRef = schema.DependencyRef
DependencyRef represents a reference to a table or column that an unmanaged object depends on.
type DestructiveViolationError ¶
type DestructiveViolationError = plan.DestructiveViolationError
DestructiveViolationError reports all destructive steps that were rejected by the active safety policy.
type DriftError ¶
type DriftError = plan.DriftError
DriftError reports unapplied differences between the live schema and the desired schema.
type DropPolicy ¶
type DropPolicy = plan.DropPolicy
DropPolicy defines the safety behavior for destructive drops.
type DryRunResult ¶
type DryRunResult = exec.DryRunResult
DryRunResult reports the outcome of a live dry-run verification.
func DryRunVerify ¶
DryRunVerify executes a live dry-run rollback against the target database: the planned DDL runs against real data inside transactions that are unconditionally rolled back, so constraints, casts, and check expressions are verified without persisting any change. Non-transactional steps (CREATE INDEX CONCURRENTLY, ALTER TYPE ... ADD VALUE, DETACH PARTITION CONCURRENTLY) are skipped and reported in DryRunResult.UnverifiedNonTx. No records are written to grizzle_history, and hooks do not run unless opts.ExecuteHooksInDryRun is set.
func DryRunVerifyPlan ¶
func DryRunVerifyPlan(ctx context.Context, db *sql.DB, p *Plan, opts ApplyOpts) (*DryRunResult, error)
DryRunVerifyPlan performs a live dry-run of an approved plan artifact. It verifies the artifact hash against ExpectedHash, honors every plan-carried intent field (target schemas, scope, policy, execution semantics), and checks that a re-diff of the live database against the artifact's SchemaSQL still produces the same plan hash — so a tampered or drifted artifact cannot silently verify a different migration. Runtime-only options (logger, tracer, hazards, lock namespace) come from opts.
type DumpOptions ¶
type DumpOptions struct {
TargetSchema string
}
DumpOptions configures schema reverse-engineering / dumping.
type ExportArtifact ¶
ExportArtifact represents a generated migration file ready to be saved.
func Export ¶
func Export(p *Plan, format ExportFormat, version string, timestamp ...time.Time) ([]ExportArtifact, error)
Export serializes the given plan into migration files for the requested tool format.
type ExportFormat ¶
ExportFormat defines supported target formats for migration export.
type ExtensionIR ¶
ExtensionIR represents the intermediate representation of a PostgreSQL extension.
type ForeignKeyIR ¶
type ForeignKeyIR = schema.ForeignKey
ForeignKeyIR represents the intermediate representation of a foreign key relationship.
type GeneratedColumn ¶
type GeneratedColumn = schema.GeneratedColumn
GeneratedColumn describes a computed or generated column.
type HazardCode ¶
type HazardCode = plan.HazardCode
HazardCode identifies the specific type of migration hazard detected.
type HazardError ¶
type HazardError = plan.HazardError
HazardError reports all critical hazards that were not explicitly accepted.
type HazardLevel ¶
type HazardLevel = plan.HazardLevel
HazardLevel indicates the severity of potential data loss or downtime.
type HistoryEntry ¶
type HistoryEntry struct {
ID int64 `json:"id"`
PlanHash string `json:"plan_hash"`
Status string `json:"status"` // applied, partial, failed, baseline, resolved
FailedStep int `json:"failed_step,omitempty"`
Error string `json:"error,omitempty"`
AppliedAt time.Time `json:"applied_at"`
DurationMs int64 `json:"duration_ms"`
AppliedBy string `json:"applied_by"`
StepsJSON string `json:"steps,omitempty"`
SeedHash string `json:"seed_hash,omitempty"`
}
HistoryEntry represents a single migration history record from grizzle_history.
func Baseline ¶
func Baseline(ctx context.Context, db *sql.DB, schemaSQL string, opts BaselineOptions) (*HistoryEntry, error)
Baseline marks an existing database as synchronized with the desired schema, inserting a baseline record into grizzle_history without executing DDL. If the database differs from desired schema and opts.Force is false, Baseline returns ErrBaselineDrift.
func ListHistory ¶
func ListHistory(ctx context.Context, db *sql.DB, opts HistoryOptions) ([]HistoryEntry, error)
ListHistory returns migration history entries recorded in grizzle_history.
func Repair ¶
func Repair(ctx context.Context, db *sql.DB, opts RepairOptions) (*HistoryEntry, error)
Repair resolves the latest partial or failed migration in grizzle_history, marking it as 'resolved' with an optional operator note. It returns ErrNoFailedMigration if there are no partial or failed migrations.
type HistoryOptions ¶
HistoryOptions configures retrieval of history records.
type HookContext ¶
type HookContext = exec.HookContext
HookContext provides invocation context and database access for a step hook. DBTX is bound to the executor of the pending step: a *sql.Tx for transactional groups or a *sql.Conn for non-transactional steps.
type LintDiagnostic ¶
type LintDiagnostic = lint.Diagnostic
LintDiagnostic is a single static lint finding against a schema element.
func LintSchema ¶
func LintSchema(s *SchemaIR, rules ...LintRule) []LintDiagnostic
LintSchema runs rules (defaulting to DefaultLintRules) against the compiled schema IR and returns deterministically sorted diagnostics.
func LintSeed ¶
func LintSeed(seedSQL string) []LintDiagnostic
LintSeed inspects seed SQL statements for idempotency and safety issues (such as bare INSERTs without conflict guards, TRUNCATE, or unconditional DELETE) and returns deterministically sorted diagnostics.
type LintRule ¶
LintRule is a pure check executed against the desired schema IR.
func DefaultLintRules ¶
func DefaultLintRules() []LintRule
DefaultLintRules returns the built-in lint rule set (L001..L013).
func FilterLintRules ¶ added in v0.2.0
FilterLintRules excludes rules whose IDs match any entry in disabledIDs.
func LintRulesForProfile ¶ added in v0.2.0
LintRulesForProfile returns the lint rules corresponding to a profile name ("standard", "strict", "all"). An empty name defaults to "standard".
type LintSeverity ¶
LintSeverity indicates how strongly a lint diagnostic should block a release.
type LockConflict ¶ added in v0.2.0
type LockConflict = plan.LockConflict
LockConflict describes a concurrent database session holding a lock on a target table.
type LockContentionError ¶ added in v0.2.0
type LockContentionError = plan.LockContentionError
LockContentionError contains details about conflicting lock holders detected during pre-flight check.
type Metrics ¶ added in v0.2.0
Metrics defines the interface for recording Grizzle operational metrics.
type Option ¶
type Option func(*Options)
Option represents a functional option for configuring Options.
func WithAcceptHazards ¶
func WithAcceptHazards(hazards ...plan.HazardCode) Option
WithAcceptHazards configures explicitly accepted critical hazard codes.
func WithAfterStep ¶
WithAfterStep registers a hook that runs immediately after each successful plan step.
func WithAfterSync ¶
WithAfterSync registers a hook that runs once after all migration steps and history recording succeed.
func WithAllowDrop ¶
WithAllowDrop sets the general drop permission.
func WithAllowResumePartial ¶
WithAllowResumePartial allows Sync to resume after a prior failed or partial migration.
func WithBackfill ¶
func WithBackfill(fn BackfillFunc) Option
WithBackfill configures the batch backfill hook function for staged expand migrations. The CLI also installs a hook via --backfill / --backfill-file; a library Backfill wins when both are configured by the caller.
func WithBeforeStep ¶
WithBeforeStep registers a hook that runs immediately prior to each plan step.
func WithBeforeSync ¶
WithBeforeSync registers a hook that runs once before any migration steps or locks are executed.
func WithDevDatabaseURL ¶ added in v0.2.0
WithDevDatabaseURL sets the external database URL used for shadow-schema compilation. When non-empty, the always-rolled-back shadow transaction runs against this database instead of the target database.
Use when the target database user lacks CREATE SCHEMA privilege. Without this option a privilege failure during shadow setup returns a clear error naming --dev-url / Options.DevDatabaseURL as the fix.
PostgreSQL only; ignored on SQLite.
func WithDryRun ¶
func WithDryRun() Option
WithDryRun enables dry-run mode: the planned SQL is validated against the live database without executing it.
func WithDryRunLockTimeout ¶
WithDryRunLockTimeout sets the lock wait bound for live dry-run verification.
func WithExcludeTables ¶
WithExcludeTables sets excluded tables and glob patterns.
func WithExecuteHooksInDryRun ¶
func WithExecuteHooksInDryRun() Option
WithExecuteHooksInDryRun allows BeforeStep/AfterStep hooks to run during live dry-run verification.
func WithExpandContract ¶
WithExpandContract enables or disables staged expand-and-contract zero-downtime migrations.
func WithExpectedHash ¶
WithExpectedHash specifies the approved plan hash to verify post-lock during Sync.
func WithFailOnContention ¶ added in v0.2.0
WithFailOnContention configures whether lock contention pre-flight gates migration execution. When true, conflicting locks on target tables trigger backoff retries up to LockTimeout, and abort with ErrLockContention if contention does not clear.
func WithIncludeTables ¶
WithIncludeTables sets included tables.
func WithLockNamespace ¶
WithLockNamespace sets the application namespace string for PostgreSQL advisory locks.
func WithLockTimeout ¶
WithLockTimeout sets the maximum duration to wait for acquiring locks.
func WithMaxRetries ¶
WithMaxRetries sets the maximum retry attempts upon lock timeout conflict (SQLSTATE 55P03).
func WithMetrics ¶ added in v0.2.0
WithMetrics sets the metrics recorder.
func WithNonConcurrentIndexes ¶
WithNonConcurrentIndexes controls whether PostgreSQL index creation should run inside the transaction.
func WithRandFloat ¶
WithRandFloat sets a custom random float function for deterministic backoff jitter in tests.
func WithRenames ¶
WithRenames sets the explicit column rename mapping. Keys are `table.old` or `old`; values are the new column name.
func WithSQLiteAttach ¶
WithSQLiteAttach sets the SQLite ATTACH DATABASE map (schema name → path).
func WithSQLiteRebuildBatching ¶
WithSQLiteRebuildBatching sets the threshold and batch size for chunked keyset copying during SQLite rebuilds.
func WithSeedForce ¶
WithSeedForce re-runs the seed even when the same seed hash was already applied.
func WithSeedSQL ¶
WithSeedSQL attaches idempotent seed SQL executed after a successful sync.
func WithStatementTimeout ¶
WithStatementTimeout sets the maximum duration for any single migration DDL statement.
func WithStrictScope ¶
WithStrictScope enables strict scoping mode requiring non-empty IncludeTables.
func WithTargetSchema ¶
WithTargetSchema sets the target schema. Deprecated: Use WithTargetSchemas for multi-schema support.
func WithTargetSchemaPattern ¶ added in v0.2.0
WithTargetSchemaPattern sets a LIKE-style pattern to discover target PostgreSQL schemas dynamically from pg_namespace (e.g. "tenant_%").
func WithTargetSchemas ¶
WithTargetSchemas sets the target schemas to manage.
type Options ¶
type Options struct {
// Dialect explicitly defines the database engine (DialectPostgres or DialectSQLite).
Dialect Dialect
// SchemaSQL contains the complete desired state. PostgreSQL role and
// catalog statements may share this file; they bypass shadow compilation
// and are merged with the optional side-channel files.
SchemaSQL string
// TargetSchema is the schema to manage (defaults to "public" for Postgres, "main" for SQLite).
// Deprecated: Use TargetSchemas for multi-schema support.
TargetSchema string
// TargetSchemas specifies the database schemas to manage (defaults to [TargetSchema] or ["public"] for Postgres).
// For SQLite, entries other than "main" are ATTACH DATABASE schema names listed in SQLiteAttach.
TargetSchemas []string
// TargetSchemaPattern specifies a LIKE-style pattern to discover target PostgreSQL schemas
// dynamically from pg_namespace (e.g. "tenant_%"). Discovered schemas are sorted deterministically,
// exclude system schemas, and are populated into TargetSchemas.
TargetSchemaPattern string
// SQLiteAttach maps ATTACH DATABASE schema names to filesystem paths.
// Every TargetSchemas entry other than "main" must appear here; "main" is
// the primary database already open and must not be listed. Unknown keys,
// empty paths, and duplicate names are rejected. PostgreSQL ignores this field.
SQLiteAttach map[string]string
// ShadowSchema is the temporary schema name used for validation (defaults to "_grizzle_shadow").
ShadowSchema string
// AllowDrop permits all destructive operations when set to true.
// Defaults to false for zero data loss.
AllowDrop bool
// AllowRevoke permits privilege revocation when a grant in RolesSQL is
// removed (access loss). Has no granular override; REVOKE_PRIVILEGE
// (CRITICAL) still requires AcceptHazards.
AllowRevoke bool
// AllowDropRole permits dropping a managed role that left RolesSQL.
// Has no granular override; DROP_ROLE (CRITICAL) still requires
// AcceptHazards.
AllowDropRole bool
// AllowDropPublication permits dropping a managed publication that
// left CatalogSQL. Has no granular override; DROP_PUBLICATION
// (CRITICAL) still requires AcceptHazards.
AllowDropPublication bool
// AllowDropEventTrigger permits dropping a managed event trigger that
// left CatalogSQL. Has no granular override; DROP_EVENT_TRIGGER
// (CRITICAL) still requires AcceptHazards.
AllowDropEventTrigger bool
// AllowDropSubscription permits dropping a managed subscription that
// left CatalogSQL. Has no granular override; DROP_SUBSCRIPTION
// (CRITICAL) still requires AcceptHazards. Remote slots are kept
// (DISABLE + SET slot_name = NONE before DROP).
AllowDropSubscription bool
// AllowDropReplicationSlot permits dropping a standalone logical
// replication slot via explicit SELECT pg_drop_replication_slot.
// Live-only slots are never swept. DROP_REPLICATION_SLOT (CRITICAL)
// still requires AcceptHazards. Active slots (active_pid IS NOT NULL)
// are refused.
AllowDropReplicationSlot bool
// Granular drop overrides (nil inherits from AllowDrop):
AllowDropTable *bool
AllowDropColumn *bool
AllowDropIndex *bool
AllowDropFK *bool
AllowDropCheck *bool
AllowDropExtension *bool
AllowDropFunction *bool
AllowDropPolicy *bool
AllowDropTrigger *bool
AllowDropView *bool
AllowDropDomain *bool
AllowDropType *bool
AllowDropRangeType *bool
AllowDropCompositeType *bool
AllowDropSequence *bool
// ExcludeTables defines table names or glob patterns (e.g. "spatial_ref_sys", "asynq_*")
// that Grizzle will never manage, alter, or drop.
ExcludeTables []string
// IncludeTables limits Grizzle's management scope to only the specified tables or patterns.
IncludeTables []string
// StrictScope requires IncludeTables to be non-empty. When true and IncludeTables is empty,
// operations fail immediately with ErrStrictScope.
// Strongly recommended for production environments to avoid accidental alterations or drops
// of untracked tables.
StrictScope bool
// AcceptHazards lists critical hazard codes that are explicitly approved to execute.
// Critical hazards not present in this list will cause Apply to fail with ErrHazardBlocked.
AcceptHazards []plan.HazardCode
// NonConcurrentIndexes opts out of emitting CONCURRENTLY for PostgreSQL index creation/drops.
// When true, index operations are created inside the transaction.
NonConcurrentIndexes bool
// LockNamespace specifies the application namespace string used for PostgreSQL advisory locking (defaults to "grizzle").
LockNamespace string
// LockID is an optional explicit 64-bit integer used for the PostgreSQL advisory lock (pg_advisory_xact_lock).
// If 0, Grizzle derives 2-int per-schema advisory locks using (hash32(LockNamespace), hash32(schema)).
LockID int64
// LockTimeout specifies the maximum time to wait when acquiring locks (defaults to 5s).
LockTimeout time.Duration
// StatementTimeout specifies the maximum execution time for any single DDL statement (defaults to 5m).
StatementTimeout time.Duration
// MaxRetries specifies the number of retry attempts upon lock timeout (SQLSTATE 55P03, defaults to 3).
MaxRetries int
// RandFloat provides an optional random source func returning in [0.0, 1.0) for deterministic jitter in tests.
RandFloat func() float64
// Renames maps old column names to new column names (e.g. "users.old_col": "new_col" or "old_col": "new_col")
// to explicitly disambiguate column renames instead of treating them as DROP + ADD.
// Keys are `table.old` or `old`; values are the new column name.
Renames map[string]string
// ExpandContract enables staged expand-and-contract zero-downtime migrations (ZDM).
// In expand mode, renamed or modified columns are added alongside existing columns,
// delaying destructive drops to a later, separately approved plan.
ExpandContract bool
// Backfill hook function run outside the DDL lock window in batches during staged expand migration.
// The CLI installs a hook via --backfill / --backfill-file when --expand-contract is set; a library
// Backfill still wins when both are configured by the caller.
Backfill BackfillFunc
// BeforeSync runs once before any migration steps or locks are executed.
// If it returns an error, the migration aborts before any DDL runs and no
// history record is written.
BeforeSync SyncHook
// AfterSync runs once after all migration steps and history recording succeed.
// If it returns an error, the DDL has already committed; the error is
// wrapped with ErrAfterSyncFailed.
AfterSync SyncHook
// BeforeStep executes immediately prior to executing each plan step.
// If it returns an error, the pending step is not executed; in a
// transactional group the transaction is rolled back and history records
// the failure with error "before_step hook: ...".
BeforeStep StepHook
// AfterStep executes immediately following the successful execution of each
// plan step. If it returns an error in a transactional group, the
// transaction is rolled back (reverting the step); in a non-transactional
// group the step has already committed and history records "partial".
AfterStep StepHook
// DryRun returns the planned SQL statements without executing them on the live database.
DryRun bool
// DryRunLockTimeout bounds how long live dry-run verification waits on
// table locks before failing fast (defaults to 2s).
DryRunLockTimeout time.Duration
// ExecuteHooksInDryRun allows BeforeStep/AfterStep hooks to run during
// live dry-run verification. Defaults to false to avoid accidental
// external side effects (webhooks, message publishing, etc.).
ExecuteHooksInDryRun bool
// SeedSQL contains idempotent data-seed SQL executed after a successful
// sync (Sync DDL → AfterSync → Seed). The seed runs in a single
// transaction and is skipped when the same seed (by content hash) was
// already applied, unless SeedForce is set.
SeedSQL string
// SeedForce re-runs the seed even when the same seed hash was already
// applied.
SeedForce bool
// RolesSQL optionally supplies desired roles and privilege grants
// alongside SchemaSQL. Duplicate role/grant identities in this explicit
// side-channel override entries extracted from SchemaSQL. Role statements
// are never shadow-compiled, and schema DDL is not valid here. Managed
// attributes include LOGIN/NOLOGIN, PASSWORD, VALID UNTIL, CONNECTION
// LIMIT, INHERIT, CREATEDB, CREATEROLE, and ALTER ROLE SET/RESET.
// SUPERUSER/REPLICATION/BYPASSRLS are refused. Passwords are compared by
// server-side hash equality and never written into Step.SQL or plan JSON.
// PostgreSQL only — ignored on SQLite.
RolesSQL string
// CatalogSQL optionally supplies desired cluster-catalog objects alongside
// SchemaSQL. Duplicate publication/event-trigger names in this explicit
// side-channel override entries extracted from SchemaSQL. Catalog
// statements are never shadow-compiled or run inside the shadow
// transaction, and schema DDL is not valid here. Drops are narrow — only
// marker-stamped (grizzle-managed) objects are considered. Event triggers
// reference functions that must exist in SchemaSQL or as live objects.
// PostgreSQL only — rejected on SQLite.
CatalogSQL string
// SQLiteRebuildThreshold defines the row count threshold above which SQLite table rebuilds
// chunk data copying by keyset to prevent journal memory exhaustion.
// Defaults to 100000. Set to 0 to disable batching.
SQLiteRebuildThreshold int
// SQLiteRebuildBatchSize defines the chunk size when copying data in batches during SQLite table rebuilds.
// Defaults to 10000.
SQLiteRebuildBatchSize int
// AllowResumePartial permits Sync to resume execution after a prior run
// ended in "partial" or "failed" status. Defaults to false (fail closed).
AllowResumePartial bool
// ExpectedHash specifies an approved plan hash. When non-empty, Sync
// verifies the post-lock live plan hash against this value and aborts
// with ErrPlanDrift if they differ.
ExpectedHash string
// DevDatabaseURL is an optional PostgreSQL connection string used
// exclusively for shadow-schema compilation (the always-rolled-back
// transaction that validates SchemaSQL). When non-empty the shadow
// transaction runs against this external database and never touches the
// target database. Live catalog introspection always uses the target DB.
//
// Use DevDatabaseURL when the target database user lacks CREATE SCHEMA
// privilege. Without it, a privilege failure during shadow setup is
// returned as an error that names this field and --dev-url as the fix.
//
// PostgreSQL only; ignored on SQLite.
DevDatabaseURL string
// FailOnContention gates DDL execution on PostgreSQL: if concurrent sessions hold conflicting
// locks on target tables, retry with backoff up to LockTimeout; if contention persists, abort
// with ErrLockContention instead of proceeding. When false (default), lock contention is advisory
// and logs a warning before proceeding.
//
// NOTE: Pre-flight lock inspection is inherently racy: concurrent transactions may acquire
// locks between the pre-flight check and subsequent DDL execution. Always configure LockTimeout
// alongside FailOnContention to bound wait duration if a race occurs.
FailOnContention bool
// Logger accepts a structured logger (*slog.Logger) for migration events.
Logger *slog.Logger
// Tracer specifies an optional tracer (OpenTelemetry or custom) for observing migrations.
Tracer Tracer
// Metrics specifies an optional metrics recorder (OpenTelemetry or custom) for observing migrations.
Metrics Metrics
}
Options configures the schema synchronization process.
func Development ¶
Development returns an Options preset optimized for local development and CI testing: permits destructive operations, executes index creation synchronously (NonConcurrentIndexes=true), and allows partial migration resumption.
func Production ¶
Production returns an Options preset configured with strict safety defaults: zero-data-loss policy (AllowDrop=false, AllowRevoke=false), online index builds (NonConcurrentIndexes=false), and fail-closed prior-failure gating.
func (*Options) Validate ¶
Validate is the canonical pure validation entry point for Options. It checks SchemaSQL, strict scope, dialect value, target/shadow identifiers, timeout and retry bounds, SQLite rebuild parameters, and multi-schema SQLite rejection. Dialect-specific checks are skipped while Dialect is DialectAuto (prepareOptions detects the dialect then re-validates). Defaults are applied by prepareOptions after Validate succeeds — Validate never mutates Options.
type PartitionKey ¶
type PartitionKey = schema.PartitionKey
PartitionKey defines how a partitioned table is divided.
type PartitionOf ¶
type PartitionOf = schema.PartitionOf
PartitionOf defines the relationship of a partition table to its parent partitioned table.
type PartitionStrategy ¶
type PartitionStrategy = schema.PartitionStrategy
PartitionStrategy represents the partitioning method used by a partitioned table.
type Plan ¶
Plan is the complete migration plan containing sequenced steps, policy, and hashes.
func ParsePlanJSON ¶
ParsePlanJSON parses a serialized plan JSON string or bytes into a *Plan, returning the recorded plan hash.
func PlanDiff ¶
PlanDiff inspects the live database and computes the planned migration steps without applying them.
Example ¶
package main
import (
"context"
"database/sql"
"fmt"
"log"
"github.com/muandane/grizzle"
_ "modernc.org/sqlite"
)
func main() {
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
log.Fatalf("failed to open database: %v", err)
}
defer func() { _ = db.Close() }()
schema := `
CREATE TABLE products (
id INTEGER PRIMARY KEY,
sku TEXT NOT NULL UNIQUE,
price INTEGER NOT NULL DEFAULT 0
);`
plan, err := grizzle.PlanDiff(context.Background(), db, grizzle.Options{
Dialect: grizzle.DialectSQLite,
SchemaSQL: schema,
})
if err != nil {
log.Fatalf("plan diff failed: %v", err)
}
fmt.Printf("Plan steps to execute: %d\n", len(plan.Steps))
}
Output: Plan steps to execute: 1
type PlanDocument ¶
PlanDocument represents a complete, serialized migration plan artifact including hash, hazards, scope, and options digest.
type PrimaryKeyIR ¶
type PrimaryKeyIR = schema.PrimaryKey
PrimaryKeyIR represents the intermediate representation of a table primary key.
type RangeTypeIR ¶
RangeTypeIR represents the intermediate representation of a range type.
type RepairOptions ¶
RepairOptions configures repairing failed/partial migration history.
type SchemaIR ¶
SchemaIR represents the database-agnostic schema intermediate representation.
func CompileSchema ¶
CompileSchema compiles opts.SchemaSQL into the desired SchemaIR without diffing or executing anything. For PostgreSQL the compilation happens in the shadow schema inside an always-rolled-back transaction (requires a connection to the target database); for SQLite it happens in an in-memory database, making it fully offline.
type ScopeDocument ¶
type ScopeDocument = plan.ScopeDocument
ScopeDocument represents the scope section of a plan document.
type SequenceIR ¶
SequenceIR represents the intermediate representation of a database sequence generator.
type StatusReport ¶
type StatusReport struct {
Dialect string `json:"dialect"`
TargetSchema string `json:"target_schema,omitempty"`
InSync bool `json:"in_sync"`
PendingSteps int `json:"pending_steps"`
AppliedCount int `json:"applied_count"`
PartialCount int `json:"partial_count"`
FailedCount int `json:"failed_count"`
Latest *HistoryEntry `json:"latest,omitempty"`
}
StatusReport details the current synchronization status between desired schema and the live database.
type StepHook ¶
StepHook executes custom imperative code immediately before or after each plan step. Hooks must be idempotent: if a later step fails and the migration is retried or resumed after partial execution, hooks may be invoked again.
type SyncHook ¶
SyncHook executes custom imperative code once before or after the entire synchronization. It receives a dedicated connection (not a transaction) because the execution may contain non-transactional statements.
type UnmanagedKind ¶
type UnmanagedKind = schema.UnmanagedKind
UnmanagedKind represents the category of an unmanaged database object.
type UnmanagedObject ¶
type UnmanagedObject = schema.UnmanagedObject
UnmanagedObject represents an unmanaged database object detected during introspection.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
grizzle
command
Package main implements the grizzle CLI.
|
Package main implements the grizzle CLI. |
|
examples
|
|
|
expand-contract
command
Package main demonstrates zero-downtime expand/contract migrations with Grizzle: a column rename executed in two separately-approved stages with a backfill between them.
|
Package main demonstrates zero-downtime expand/contract migrations with Grizzle: a column rename executed in two separately-approved stages with a backfill between them. |
|
full-catalog
command
Package main demonstrates Grizzle's full managed surface: extensions, domains, tables with RLS + policies, COMMENT ON, functions, procedures, triggers, and (materialized) views — all declared in one schema.sql and synced in-process on boot.
|
Package main demonstrates Grizzle's full managed surface: extensions, domains, tables with RLS + policies, COMMENT ON, functions, procedures, triggers, and (materialized) views — all declared in one schema.sql and synced in-process on boot. |
|
postgres-pgxpool
command
|
|
|
postgres-stdlib
command
|
|
|
roles-grants
command
Package main demonstrates RolesSQL side-channel privilege sync: schema objects live in schema.sql; CREATE ROLE / GRANT statements live in roles.sql.
|
Package main demonstrates RolesSQL side-channel privilege sync: schema objects live in schema.sql; CREATE ROLE / GRANT statements live in roles.sql. |
|
sqlc-workflow
command
|
|
|
sqlc-workflow/db
Package db provides type-safe database queries.
|
Package db provides type-safe database queries. |
|
sqlite-embedded
command
|
|
|
Package griztest provides testing utilities and ergonomic primitives for testing applications powered by Grizzle schema migrations.
|
Package griztest provides testing utilities and ergonomic primitives for testing applications powered by Grizzle schema migrations. |
|
internal
|
|
|
config
Package config manages grizzle.yaml and grizzle.json configuration files.
|
Package config manages grizzle.yaml and grizzle.json configuration files. |
|
dialect
Package dialect defines the interface for database-specific introspection, DDL rendering, and transactional locking behaviors.
|
Package dialect defines the interface for database-specific introspection, DDL rendering, and transactional locking behaviors. |
|
dialect/postgres
Package postgres implements PostgreSQL-specific introspection, DDL rendering, advisory locking, and shadow schema compilation.
|
Package postgres implements PostgreSQL-specific introspection, DDL rendering, advisory locking, and shadow schema compilation. |
|
dialect/sqlite
Package sqlite implements SQLite-specific schema introspection, in-memory shadow validation, and the 12-step table rebuild engine.
|
Package sqlite implements SQLite-specific schema introspection, in-memory shadow validation, and the 12-step table rebuild engine. |
|
diff
Package diff performs pure relational comparison between live and desired database schemas.
|
Package diff performs pure relational comparison between live and desired database schemas. |
|
exec
Package exec coordinates statement execution, transactional locking, and safety policy enforcement.
|
Package exec coordinates statement execution, transactional locking, and safety policy enforcement. |
|
history
Package history manages migration history records and schema drift tracking.
|
Package history manages migration history records and schema drift tracking. |
|
lint
Package lint provides static, database-free linting of a desired schema IR.
|
Package lint provides static, database-free linting of a desired schema IR. |
|
plan
Package plan models migration steps, execution plans, safety policies, and hazard detection.
|
Package plan models migration steps, execution plans, safety policies, and hazard detection. |
|
schema
Package schema defines the pure, engine-agnostic relational schema representation (Table, Column, Index, Constraint, Schema) and normalization logic.
|
Package schema defines the pure, engine-agnostic relational schema representation (Table, Column, Index, Constraint, Schema) and normalization logic. |
|
scope
Package scope handles table filtering and unmanaged-table boundaries (PostGIS, background queues, and user-specified include/exclude patterns).
|
Package scope handles table filtering and unmanaged-table boundaries (PostGIS, background queues, and user-specified include/exclude patterns). |
|
testutil
Package testutil provides shared test infrastructure for integration tests.
|
Package testutil provides shared test infrastructure for integration tests. |
|
otelgrizzle
module
|