migration

package
v1.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package migration implements Fort's offline, encrypted SQLite/Postgres migration evidence. It deliberately does not apply semantic v1-to-v2 mappings: unresolved choices are reported and block an import.

Index

Constants

View Source
const (
	ArchiveFormatVersion = 1
	ArchiveKeyBytes      = 32
	MaximumArchiveBytes  = 512 << 20
)

Variables

View Source
var (
	ErrArchiveInvalid        = errors.New("migration archive is invalid")
	ErrArchiveAuthentication = errors.New("migration archive authentication failed")
	ErrArchiveIntegrity      = errors.New("migration archive integrity failed")
	ErrDatabaseNotQuiescent  = errors.New("migration source database is not quiescent")
	ErrUnresolvedMappings    = errors.New("migration has unresolved mappings")
)

Functions

func SealArchive

func SealArchive(archive Archive, key []byte, random io.Reader) ([]byte, error)

Types

type Archive

type Archive struct {
	FormatVersion      int          `json:"format_version"`
	SourceEngine       SourceEngine `json:"source_engine"`
	SchemaVersion      string       `json:"schema_version"`
	SourceDatabaseHash string       `json:"source_database_hash"`
	Tables             []Table      `json:"tables"`
	TableCount         int          `json:"table_count"`
	RowCount           int64        `json:"row_count"`
	ManifestMAC        string       `json:"manifest_mac"`
}

func NewArchive

func NewArchive(engine SourceEngine, schemaVersion, sourceDatabaseHash string, tables []Table, key []byte) (Archive, error)

NewArchive freezes stable HMAC evidence over each logical record, table, and the complete manifest. The evidence remains inside the encrypted file.

func OpenArchive

func OpenArchive(encoded, key []byte) (Archive, error)

func SnapshotPostgres

func SnapshotPostgres(ctx context.Context, databaseURL, accountID string, key []byte) (Archive, error)

SnapshotPostgres exports one account through a direct migration-operator connection. The session is repeatable-read and read-only; it never uses the runtime Store and cannot become a write path for a client or worker.

func SnapshotSQLite

func SnapshotSQLite(ctx context.Context, path string, key []byte) (Archive, error)

SnapshotSQLite opens an already-frozen SQLite backup read-only. It refuses active work, WAL sidecars, integrity failures, and any file change observed while the snapshot transaction is open.

type Column

type Column struct {
	Name               string `json:"name"`
	SourceType         string `json:"source_type"`
	NotNull            bool   `json:"not_null,omitempty"`
	PrimaryKeyPosition int    `json:"primary_key_position,omitempty"`
	Identity           bool   `json:"identity,omitempty"`
}

type ImportPlan

type ImportPlan struct {
	SourceEngine  SourceEngine           `json:"source_engine"`
	SchemaVersion string                 `json:"schema_version"`
	ManifestMAC   string                 `json:"manifest_mac"`
	TotalRows     int64                  `json:"total_rows"`
	Counts        map[MappingClass]int64 `json:"counts"`
	Tables        []TableMapping         `json:"tables"`
	Rows          []RowMapping           `json:"rows"`
	Resolved      bool                   `json:"resolved"`
}

func PlanPostgresImport

func PlanPostgresImport(archive Archive) ImportPlan

func (ImportPlan) RequireResolved

func (report ImportPlan) RequireResolved() error

type MappingClass

type MappingClass string
const (
	MappingReady               MappingClass = "ready"
	MappingNeedsExplicitChoice MappingClass = "needs_explicit_choice"
	MappingLegacyRetained      MappingClass = "legacy_retained"
	MappingIncompatible        MappingClass = "incompatible"
)

type Row

type Row struct {
	Values []Value `json:"values"`
	Digest string  `json:"digest"`
}

type RowMapping

type RowMapping struct {
	SourceTable  string       `json:"source_table"`
	TargetTable  string       `json:"target_table,omitempty"`
	RecordDigest string       `json:"record_digest"`
	Class        MappingClass `json:"class"`
	Reason       string       `json:"reason"`
}

type SourceEngine

type SourceEngine string
const (
	SourceSQLite   SourceEngine = "sqlite"
	SourcePostgres SourceEngine = "postgres"
)

type Table

type Table struct {
	Name            string                     `json:"name"`
	Columns         []Column                   `json:"columns"`
	Dependencies    []string                   `json:"dependencies,omitempty"`
	Rows            []Row                      `json:"rows"`
	Count           int64                      `json:"count"`
	SchemaDigest    string                     `json:"schema_digest"`
	Digest          string                     `json:"digest"`
	IdentityMaxima  map[string]string          `json:"identity_maxima,omitempty"`
	TimestampBounds map[string]TimestampBounds `json:"timestamp_bounds,omitempty"`
}

type TableMapping

type TableMapping struct {
	SourceTable string       `json:"source_table"`
	TargetTable string       `json:"target_table,omitempty"`
	Count       int64        `json:"count"`
	Digest      string       `json:"digest"`
	Class       MappingClass `json:"class"`
	Reason      string       `json:"reason"`
}

type TableVerification

type TableVerification struct {
	LogicalTable string `json:"logical_table"`
	SourceTable  string `json:"source_table"`
	TargetTable  string `json:"target_table"`
	SourceCount  int64  `json:"source_count"`
	TargetCount  int64  `json:"target_count"`
	SourceDigest string `json:"source_digest"`
	TargetDigest string `json:"target_digest"`
	Matched      bool   `json:"matched"`
	Reason       string `json:"reason,omitempty"`
}

type TimestampBounds

type TimestampBounds struct {
	Minimum string `json:"minimum"`
	Maximum string `json:"maximum"`
}

type Value

type Value struct {
	Kind ValueKind `json:"kind"`
	Text string    `json:"text,omitempty"`
}

Value is a lossless, engine-independent database scalar. Bytes use canonical raw-URL base64; JSON is canonical compact JSON.

type ValueKind

type ValueKind string
const (
	ValueNull      ValueKind = "null"
	ValueBoolean   ValueKind = "boolean"
	ValueInteger   ValueKind = "integer"
	ValueDecimal   ValueKind = "decimal"
	ValueText      ValueKind = "text"
	ValueBytes     ValueKind = "bytes"
	ValueTimestamp ValueKind = "timestamp"
	ValueJSON      ValueKind = "json"
)

type VerificationReport

type VerificationReport struct {
	SourceManifestMAC string              `json:"source_manifest_mac"`
	TargetManifestMAC string              `json:"target_manifest_mac"`
	Tables            []TableVerification `json:"tables"`
	Verified          bool                `json:"verified"`
}

func VerifyMigration

func VerifyMigration(source, target Archive, key []byte) VerificationReport

Jump to

Keyboard shortcuts

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