migration

package
v2.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package migration is the registration face of the framework's migration system: an app claims an app code and registers functions under it. What runs those functions - reading sys_migration, ordering entries, running each inside a transaction, and the `migrate` / `migrate status` commands - stays in the host, which reads this package's Registry through Snapshot rather than through a shared private field. See the package's PRD (006, F9) for why the split lands there: registration and execution share no state once Snapshot returns a copy, and only registration is something a third-party app - which cannot reach into the host's process - needs to call.

Index

Constants

View Source
const FrameworkAppCode = "core"

FrameworkAppCode is the name the host's `migrate status` prints for migrations that belong to the framework rather than to an app, and the name --app accepts to select them. The stored app code for those is the empty string; this is only the spelling humans use. It is reserved - ForApp rejects it - so that every group heading the host prints is also a value its --app flag understands.

Variables

This section is empty.

Functions

func GetFilename

func GetFilename(s string) string

GetFilename extracts a migration's version from its file name: the leading 13 digits, which is the millisecond-timestamp convention every migration file name follows.

The prefix has to be checked, not just sliced. Every caller is an init(), and a name that carries no timestamp would otherwise register under a key that is not a version at all - sys_migration would record it, ordering against real versions would be meaningless, and nothing would ever say so. Length alone is not enough of a check either: "add_orders.go" is exactly 13 characters, so it passed a bounds check and became its own version. Panic with the offending name, so the author sees which file to rename.

func NormalizeAppCode

func NormalizeAppCode(code string) string

NormalizeAppCode applies the same rule ForApp does, so a code typed on the command line matches one written in an init().

func SetVersion

func SetVersion(k string, f func(db *gorm.DB, version string) error)

SetVersion is the package-level entry point for a migration owned by the framework itself, under the empty app code - the path go-admin's own cmd/migrate/migration/version files use.

func Snapshot

func Snapshot() map[string]Entry

Snapshot returns a copy of every migration registered in the process-wide registry, exactly as Registry.Snapshot does. This is what the host's execution engine reads.

Types

type AppMigrationFunc

type AppMigrationFunc func(db *gorm.DB, version, appCode string) error

AppMigrationFunc is what an app registers through ForApp. It receives appCode explicitly because the migration - not the framework - writes its own completion row, normally as the last statement inside its own transaction. That is what makes "the schema change and the record of it commit together" true, and the framework cannot insert the row on the migration's behalf without giving that up. Handing the code to the function is what stops an app's migrations from silently recording themselves as the framework's.

type AppRegistrar

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

AppRegistrar is a per-app view over a Registry.

func ForApp

func ForApp(code string) *AppRegistrar

ForApp is the package-level entry point an application's init() calls: migration.ForApp("crm").SetVersion(...). It is the same call an app makes against its own *Registry in a unit test, now reaching the registry the host's execution engine actually reads.

func (*AppRegistrar) AppCode

func (a *AppRegistrar) AppCode() string

AppCode reports the code this registrar files migrations under, after normalisation.

func (*AppRegistrar) SetVersion

func (a *AppRegistrar) SetVersion(k string, f AppMigrationFunc)

SetVersion registers an app-owned migration under k, which is the bare timestamp taken from the file name exactly as framework migrations use.

What reaches sys_migration.version is the namespaced form; the version string handed to f is that same namespaced string, so a migration that writes its own completion row keyed on version records the key the registry will look for next time.

type Entry

type Entry struct {
	AppCode string
	Fn      func(db *gorm.DB, version string) error
}

Entry is one registered migration as the host's execution engine sees it.

type Registry

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

Registry is the registration face only: it never touches a database. Reading sys_migration, ordering, and running the transaction is the host's execution engine, which reads this registry through Snapshot.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty registry. The host keeps one package-level instance; tests construct their own to stay isolated from each other.

func (*Registry) ForApp

func (r *Registry) ForApp(code string) *AppRegistrar

ForApp returns a registrar that records migrations under code.

The code is lower-cased: sys_migration.version sorts as ASCII, so mixed case would order MyApp before crm for no reason a reader could guess, and the two spellings would group as two different apps in `migrate status`.

An empty or reserved code panics rather than falling back to the framework. Registration happens in init(), so this fires the first time the binary runs anywhere, which is the point: an app whose migrations quietly file themselves under the framework is exactly the class of silent failure this work exists to remove. Framework migrations call Registry.SetVersion directly.

func (*Registry) SetVersion

func (r *Registry) SetVersion(k string, f func(db *gorm.DB, version string) error)

SetVersion registers a migration owned by the framework itself, under the empty app code.

func (*Registry) Snapshot

func (r *Registry) Snapshot() map[string]Entry

Snapshot returns a copy of every registered entry, keyed exactly as sys_migration.version is. This is the only way the host's execution engine reads the registry: a copy, not the live map, so ordering, filtering, and iterating it can happen without holding the registry's lock across a database call.

Jump to

Keyboard shortcuts

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