r3tag

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package r3tag provides struct tag parsing for r3 entities.

It handles the `r3` tag (primary) with `db` tag as fallback for column mapping, and finally the `gorm` tag (column:/primaryKey) so gorm-tagged models resolve to the same physical columns the GORM driver binds.

Column tag syntax (r3 or db):

r3:"column_name"
r3:"column_name,pk"
r3:"column_name,pk,soft_delete"
r3:"-"               // skip this field
r3:"soft_delete"      // column name derived from field name
db:"column_name,pk"  // fallback when no r3 tag
gorm:"column:name"   // fallback when neither r3 nor db names the column

Relation tag syntax (r3 only):

r3:"rel:has-many,fk:city_id"
r3:"rel:belongs-to,fk:city_id"
r3:"rel:has-many,fk:city_id,table:translations"
r3:"rel:many-to-many,join:city_tags,fk:city_id,ref:tag_id,order:sort_order"
r3:"rel:many-to-many,join:city_tags,fk:city_id,ref:tag_id,where:kind=topic"

order: names an integer column on the M2M join table that persists the slice order: sync writes each element's index into it, preload orders by it.

where: scopes an M2M relation to one slice of its join table via a constant predicate (`where:<column>=<value>`), so two relations can share one join table without seeing or deleting each other's rows: reads filter on it, writes filter and supply it. The value is always bound as a query argument, so the database coerces it to the column's type; it cannot contain a comma (the tag separator). M2M only - other relation kinds ignore it.

Capability flags (additive — they tighten the permissive defaults, never widen):

r3:"secret_token,no-filter,no-sort,no-output" // hidden from filter/sort/select
r3:"population,readonly"                        // not creatable, not mutable
r3:"slug,immutable"                             // creatable once, not mutable
r3:"status,enum:draft|planned|published"        // enum type + allowed values

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeclaresRelation added in v0.5.2

func DeclaresRelation(field reflect.StructField) bool

DeclaresRelation reports whether a field is a relation because it says so - through its own `rel:` tag or a gorm association tag - as opposed to merely having a relation-shaped Go type.

This is the gate the document-store engines use. There a slice, a map and a subdocument are native values, so only a declaration makes a field a relation; everything else is stored. r3utils.IsRelationType stays the gate for SQL, where a relation-shaped field cannot be one column.

A gorm association is only ever declared on a relation-shaped field, so that form keeps the type guard: a scalar carrying a stray gorm option is a column.

func HasGormAssociationTag added in v0.5.2

func HasGormAssociationTag(field reflect.StructField) bool

HasGormAssociationTag reports whether a field's `gorm` tag declares an association (foreignKey / references / many2many) rather than a column.

func HasRelationTag added in v0.5.2

func HasRelationTag(field reflect.StructField) bool

HasRelationTag reports whether a field's `r3` tag carries a `rel:` part, i.e. declares a relation - complete or not. ParseRelationTag is the stricter test that also requires a foreign key before the relation can be used.

Types

type ColumnTag

type ColumnTag struct {
	Column     string // resolved column name
	IsPK       bool   // field is the primary key
	Skip       bool   // field should be skipped (tag value is "-")
	SoftDelete bool   // r3:"soft_delete"

	// Capability flags. They are additive and only ever tighten the schema's
	// permissive defaults (see r3.SchemaOf) — never widen them.
	NoFilter  bool     // r3:"...,no-filter"  — not allowed in Query.Filters
	NoSort    bool     // r3:"...,no-sort"    — not allowed in Query.Sorts
	NoOutput  bool     // r3:"...,no-output"  — hidden from SELECT and serialized output
	ReadOnly  bool     // r3:"...,readonly"   — not creatable and not mutable
	Immutable bool     // r3:"...,immutable"  — creatable once, then not mutable
	Enum      []string // r3:"...,enum:a|b|c" — enum data type with the allowed values
	Codec     string   // r3:"...,codec:name" — value codec name (resolved in schema derivation)
}

ColumnTag holds parsed column-level tag info for a single struct field.

func ParseColumnTag

func ParseColumnTag(field reflect.StructField) ColumnTag

ParseColumnTag reads column metadata from struct tags, in priority order: `r3`, then `db`, then the `gorm` tag's column/primaryKey info (so gorm-tagged models resolve to the same physical columns the GORM driver binds). With no column name from any tag, the field name's snake_case is used.

type RelationKind

type RelationKind int

RelationKind describes the type of relationship between two entities.

const (
	// RelHasMany represents a one-to-many relationship.
	RelHasMany RelationKind = iota
	// RelBelongsTo represents a many-to-one relationship.
	RelBelongsTo
	// RelManyToMany represents a many-to-many relationship via a join table.
	RelManyToMany
)

type RelationTag

type RelationTag struct {
	Kind      RelationKind
	FKColumn  string // foreign key column name (or left FK for M2M)
	RefColumn string // right FK column for M2M join table
	TableName string // explicit table name override (optional)
	JoinTable string // join table name for M2M relations
	// OrderColumn is an integer column on the M2M join table that persists the
	// relation slice's order: sync writes each element's index into it, preload
	// orders by it. Empty means order is not persisted.
	OrderColumn string
	// WhereColumn and WhereValue are the constant predicate scoping an M2M
	// relation to one slice of its join table (`where:<column>=<value>`). Empty
	// WhereColumn means the relation spans the whole join table, as before.
	WhereColumn string
	WhereValue  string
	Owned       bool // if true, children are lifecycle-bound to parent (delete orphans on update)
}

RelationTag holds parsed relation tag info.

func ParseRelationTag

func ParseRelationTag(field reflect.StructField) (RelationTag, bool)

ParseRelationTag parses the `r3` struct tag on a relation field. Returns a RelationTag and true if the tag declares a valid relation.

Jump to

Keyboard shortcuts

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