schema

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: 6 Imported by: 0

Documentation

Overview

Package schema provides struct reflection and model metadata caching for Quark ORM. It parses Go struct tags (db, pk, rel, join) and caches the result using sync.Map to ensure O(1) lookups after the first access per model type.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ColumnFromDBTag added in v0.3.0

func ColumnFromDBTag(tag string) string

ColumnFromDBTag returns just the column-name portion of a db tag, stripping any sizing options (e.g. "name,size=512" → "name"). Tags without a comma are returned unchanged. Used by hot paths in package quark that read the raw struct tag and need to feed identifiers to the SQL guard.

func Pluralize

func Pluralize(s string) string

Pluralize applies simple English pluralization rules.

func ToSnakeCase

func ToSnakeCase(s string) string

ToSnakeCase converts CamelCase to snake_case, intelligently handling acronyms.

Types

type FieldMeta

type FieldMeta struct {
	Index     int
	Column    string // value of the db:"" tag (without options)
	Kind      reflect.Kind
	Type      reflect.Type
	IsPK      bool
	OldColumn string // for renames
	NotNull   bool   // from tag: quark:"not_null" or nullable:"false"
	Default   string // from tag: default:"value"
	Unique    bool   // from tag: quark:"unique"

	// SQL-type sizing options parsed from the db tag, e.g.
	//   db:"name,size=512"
	//   db:"price,precision=18,scale=4"
	// A zero value means "use the dialect default for the Go type". The
	// migrate layer applies these to VARCHAR/CHAR sizing and DECIMAL
	// precision/scale; custom type mappers can read them via TypeOptions.
	Size      int
	Precision int
	Scale     int

	// IsVersion marks the field as the optimistic-locking version column.
	// Set by quark:"version". When present, Update / UpdateFields /
	// Tracked.Save include "version = version + 1" in SET and
	// "AND version = ?" in WHERE; a zero rows-affected on the response
	// surfaces ErrStaleEntity. Only one field per model may carry this tag.
	IsVersion bool

	// TZName is the raw IANA timezone string from quark:"tz=Europe/Madrid",
	// or "" when the field has no tz tag. TZ is the parsed *time.Location.
	// Parsing happens eagerly in computeModelMeta (no lazy load): an
	// invalid name leaves both zero-valued and records ModelMeta.TZError.
	// When TZ is non-nil the bind path converts the field's time.Time to
	// UTC for the wire and the scan path applies .In(TZ) in memory.
	// Applies to time.Time, *time.Time and Nullable[time.Time] fields;
	// ignored for non-time Go types.
	TZName string
	TZ     *time.Location
}

FieldMeta holds metadata about a single struct field.

type ModelMeta

type ModelMeta struct {
	Table          string
	PK             PKMeta
	HasPK          bool
	CompositePK    []PKMeta // populated when two or more fields carry pk:"true"
	HasCompositePK bool     // true when len(CompositePK) > 1
	Fields         []FieldMeta
	FieldByCol     map[string]*FieldMeta    // lookup by db column name
	Relations      map[string]*RelationMeta // lookup by field name

	// VersionFieldIndex is the FieldMeta index of the optimistic-locking
	// version column, or -1 when the model does not have one. Cached at
	// schema-compute time so the hot Update / Save paths don't have to
	// re-scan Fields.
	VersionFieldIndex int

	// HasTZ is true when at least one field carries a valid quark:"tz=..."
	// tag. The hot bind / scan paths read this flag first so models that
	// don't use per-column timezones pay nothing — no FieldByCol lookup,
	// no type switch.
	HasTZ bool

	// TZError holds the first timezone-parsing failure encountered while
	// computing this model's metadata, or nil. computeModelMeta cannot
	// return an error (the public GetModelMeta API doesn't expose one),
	// so an invalid quark:"tz=..." value is recorded here and surfaced
	// fail-fast by Client.RegisterModel / Client.Migrate, which wrap it
	// in quark.ErrInvalidTimezone.
	TZError error
}

ModelMeta holds cached metadata about a model struct. Computed once per type and stored in a global registry.

func GetModelMeta

func GetModelMeta[T any]() *ModelMeta

GetModelMeta returns the cached metadata for model type T. If not cached, it computes and stores it.

func GetModelMetaByType

func GetModelMetaByType(t reflect.Type) *ModelMeta

GetModelMetaByType returns the cached metadata for a reflect.Type.

type PKMeta

type PKMeta struct {
	Column string
	Index  int
	Kind   reflect.Kind
}

PKMeta holds primary key metadata for a single PK column.

func FindPK

func FindPK(v reflect.Value) (PKMeta, bool)

FindPK finds the primary key field in a struct value. It first looks for a pk:"true" tag, then falls back to db:"id". When multiple fields carry pk:"true" the first one is returned for backward-compatibility; use FindPKs to obtain all of them.

func FindPKs

func FindPKs(v reflect.Value) []PKMeta

FindPKs returns all primary key fields from a struct value. Fields tagged with pk:"true" are returned in declaration order. When no pk:"true" tag is present it falls back to the single db:"id" field.

func (PKMeta) IsComposite

func (p PKMeta) IsComposite() bool

IsComposite returns true when the model uses a multi-column primary key. Use ModelMeta.CompositePK instead of ModelMeta.PK when this is true.

type RelationMeta

type RelationMeta struct {
	Type           string       // "has_one", "has_many", "belongs_to", "m2m", "polymorphic"
	Field          string       // struct field name
	JoinCol        string       // foreign key column (for belongs_to, has_one, has_many)
	JoinTable      string       // join table name (for m2m)
	JoinFK         string       // foreign key in join table pointing to this model (for m2m)
	JoinRefFK      string       // foreign key in join table pointing to related model (for m2m)
	PolyType       string       // polymorphic type identifier (for polymorphic)
	PolyTypeColumn string       // column storing the polymorphic type (for polymorphic)
	PolyIDColumn   string       // column storing the polymorphic foreign key (for polymorphic)
	RefType        reflect.Type // type of the related model (the struct type)
	IsSlice        bool         // true for has_many, m2m
}

RelationMeta holds metadata about a model relation.

type TableNamer

type TableNamer interface {
	TableName() string
}

TableNamer interface for custom table names.

Jump to

Keyboard shortcuts

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