migrate

package
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package migrate provides internal utilities for database schema migrations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsBoolColumn added in v1.1.1

func IsBoolColumn(t reflect.Type) bool

IsBoolColumn reports whether t maps to a boolean column. It unwraps a pointer (*bool) and the sql.Null[bool] / quark.Nullable[bool] wrapper the same way SQLTypeWithOpts resolves the column's SQL type, so the default-normalization decision stays consistent with the emitted column type. Callers use it to gate NormalizeBoolDefault.

func NormalizeBoolDefault added in v1.1.1

func NormalizeBoolDefault(dialectName, def string) string

NormalizeBoolDefault rewrites a boolean column's `default:"..."` literal to the form the target dialect accepts in a DDL DEFAULT clause.

Quark passes a column default through to DDL verbatim, but a boolean default has NO single literal portable across the six engines: PostgreSQL's BOOLEAN requires TRUE/FALSE and rejects 1/0 (SQLSTATE 42804), while MSSQL's BIT and Oracle's NUMBER(1) require 1/0 and reject TRUE/FALSE. This recognizes the documented bool literals 1/0/true/false (case-insensitive) and emits the dialect-appropriate one (TRUE/FALSE for PostgreSQL, 1/0 for the rest).

Input must be one of 1/0/true/false (case-insensitive); any other string — a function call, a quoted literal, a non-bool value — is returned UNCHANGED, so non-boolean columns and custom expressions are unaffected. Callers gate this on IsBoolColumn; validating the default tag itself is the caller's job.

func PKColumnSQL added in v1.1.2

func PKColumnSQL(dialectName string, class PKClass, fallback string) string

PKColumnSQL returns the full column-type fragment for a single-column primary key of the given class. `fallback` is the bare type to use for PKOther; it is ignored for the other classes.

func RegisterTypeMapper added in v0.3.0

func RegisterTypeMapper(t reflect.Type, m TypeMapper)

RegisterTypeMapper registers a custom Go-type → SQL-type mapping. The public API in package quark forwards to this; the registry lives here because internal/migrate.SQLType is the only consumer and we want the lookup to stay close to the lookup site.

Pointer types are stripped before registration: registering for time.Duration also covers *time.Duration. Re-registering the same type overwrites the previous mapper.

func SQLType

func SQLType(dialectName string, t reflect.Type, isPK bool) string

When isPK is true the column DDL includes the PRIMARY KEY constraint. The exact type depends on the Go field kind:

  • int / int64 → dialect-native auto-increment (SERIAL, AUTO_INCREMENT, IDENTITY…)
  • string → VARCHAR(36) PRIMARY KEY — UUID-friendly; no auto-increment
  • anything else → its natural SQL type + PRIMARY KEY (no auto-increment)

func SQLTypeWithOpts added in v0.3.0

func SQLTypeWithOpts(dialectName string, t reflect.Type, opts TypeOptions) string

SQLTypeWithOpts is the extended form of SQLType that propagates the field's sizing hints to the type mapper. It is the preferred entry point for the migrate / sync layers; SQLType remains as a convenience wrapper for callers that don't (yet) have TypeOptions.

Types

type PKClass added in v1.1.2

type PKClass int

SQLType maps Go types to SQL types for the given dialect name.

PKClass classifies a single-column primary key for DDL rendering. Two callers funnel into PKColumnSQL so the PRIMARY KEY fragments live in exactly one place: the migrator (which classifies from the model's reflect.Kind inside SQLType) and ApplyPlan's CREATE TABLE executor (which classifies from the neutral type STRING via ClassifyPKType — the Go type is gone by then).

const (
	// PKOther appends a plain PRIMARY KEY to the column's own type
	// (composite-key members never get here — they render as a
	// table-level constraint).
	PKOther PKClass = iota
	// PKInteger renders the dialect's auto-increment integer PK.
	PKInteger
	// PKString renders the dialect's fixed-width string PK (UUID/ULID).
	PKString
)

func ClassifyPKType added in v1.1.2

func ClassifyPKType(bareType string) PKClass

ClassifyPKType maps a bare column-type string (catalog- or migrator-emitted) to its PKClass. Integer-family types get the auto-increment treatment — mirroring the reflect-side rule "integer PK → auto-increment" so a table created from a Plan matches the one SQLType would emit for the same model. Everything else renders as `<own type> PRIMARY KEY`; notably a string column keeps its declared type (TEXT/VARCHAR(n)) instead of being coerced to the reflect-side VARCHAR(36) — PKString is reachable only from the reflect path.

Bare `NUMBER` (no precision) is classified as integer on purpose: Oracle's catalog reports identity PK columns as precision-less NUMBER (the same asymmetry typesEqual's oracleBareNumberMatch handles on the diff side), so a Plan built from introspection of a Migrate-created table re-renders the identity clause instead of silently dropping it. A hand-made non-identity bare-NUMBER PK would be coerced — accepted trade-off, mirroring the diff layer's "the catalog only emits bare NUMBER for identity columns" assumption.

type TypeMapper added in v0.3.0

type TypeMapper func(dialect string, opts TypeOptions) string

TypeMapper produces a dialect-specific SQL type for a Go type. The caller supplies the dialect name (lower-case: "postgres", "mysql", ...) and the sizing hints from the field's tag. Implementations should fall back to sensible defaults if Size/Precision/Scale are zero.

func LookupTypeMapper added in v0.3.0

func LookupTypeMapper(t reflect.Type) TypeMapper

LookupTypeMapper returns the registered mapper for t (pointer stripped). Returns nil if no mapping is registered.

type TypeOptions added in v0.3.0

type TypeOptions struct {
	Size      int
	Precision int
	Scale     int
	IsPK      bool
}

TypeOptions carry the SQL-type sizing hints parsed from a struct's db tag, e.g. db:"name,size=512" or db:"price,precision=18,scale=4". A zero value means "use the dialect default".

Jump to

Keyboard shortcuts

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