orm

package
v0.1.13 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2021 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CreatedAt = "CreatedAt"
	UpdatedAt = "UpdatedAt"
	DeletedAt = "DeletedAt"
)

Defined struct time field names.

View Source
const (
	TagKey      = "orm"
	TagValidate = "validate"
)

Tag definitions.

View Source
const (
	MODEL      = "orm.model" // MODEL is the ctx key for validator.
	ID         = "ID"        // ID is the field name for primary keys.
	RootStruct = ""          // RootStruct is used for the configuration to identify the root Struct.
)

predefined constants.

View Source
const (
	BLACKLIST = 1
	WHITELIST = 2
)

permission policy

View Source
const (
	HasOne     = "hasOne"
	BelongsTo  = "belongsTo"
	HasMany    = "hasMany"
	ManyToMany = "m2m"
)

Relation types.

View Source
const (
	CREATE = "create"
	UPDATE = "update"
	DELETE = "delete"
)

constants to define the changed values.

Variables

View Source
var (
	ErrDbPrimaryKey    = "orm: defined primary key (%s) is not defined in the db table %s"
	ErrDbColumnMissing = "orm: column %s (%s) does not exist in table %s"
	ErrNullField       = "orm: column %s (%s) is null able but field (%s) does not implement the sql.Scanner or driver.Valuer interface"
	ErrSoftDelete      = "orm: soft delete field does not exist %w"
)

Error messages.

View Source
var (
	ErrInit      = "orm: forgot to call Init() on %s"
	ErrMandatory = "orm: %s is mandatory but has zero-value in %s"
	ErrResultPtr = "orm: result variable must be a ptr in %s (All)"
)

Error messages

View Source
var (
	ErrRelationKind = "orm: relation kind %s is not allowed on field type %s (%s)"
	ErrRelationType = "orm: relation type %s is not allowed (%s)"
	ErrPolymorphic  = "orm: polymorphism is only available on HasOne, HasMany and ManyToMany(not self-referencing) (%s)"
	ErrJoinTable    = "orm: required join table columns are not existing %s in %s"
)

Error messages.

View Source
var (
	ErrFieldType      = "" /* 182-byte string literal not displayed */
	ErrFieldName      = "orm: field/relation (%s) does not exist or does not have the required permission"
	ErrFieldUnique    = "orm: field name (%s) is not unique"
	ErrPrimaryKey     = "orm: no primary key is defined in %s"
	ErrMaxSearchDepth = "orm: the max parent search depth of %d was reached (%s)"
	ErrInfinityLoop   = "orm: 🎉 congratulation you created an infinity loop (%s)"
)

Error messages:

View Source
var (
	ErrNoRows = "orm: %s %w"
)

Error messages.

View Source
var (
	ErrValidation = "orm: validation failed for '%s' field '%s' on tag '%s' (value:%v)"
)

Error messages

Functions

func IsValueZero

func IsValueZero(value reflect.Value) bool

IsValueZero checks if a reflect.Value is zero or if its a ptr if the value is zero.

func NewConfig

func NewConfig() *config

NewConfig will return a new empty configuration struct.

func Register

func Register(name string, fn providerFn) error

Register a new strategy provider.

func RegisterModel

func RegisterModel(orm ...Interface)

RegisterModel is a function to register a models. This can be used on application start to pre-cache all models and boost the performance.

func RegisterModels

func RegisterModels() map[string]Interface

RegisterModels will return all registered models.

func RegisterValidation

func RegisterValidation(tag string, fn func(ctx context.Context, fl valid.FieldLevel) bool, callValidationEvenIfZero ...bool) error

RegisterValidation will add a validation to the global validator. As context the orm.Interface will be added under the name orm.MODEL.

func SetReflectValue

func SetReflectValue(field reflect.Value, value reflect.Value) error

SetReflectValue is a helper to set the fields value. It checks the field type and casts the value to it.

func Validate

func Validate() *valid.Validate

Validate will return the global validate instance.

Types

type ChangedValue

type ChangedValue struct {
	Field     string
	Old       interface{}    `json:",omitempty"`
	New       interface{}    `json:",omitempty"`
	Operation string         // create, update or delete.
	Index     interface{}    `json:",omitempty"` // On delete index is used as ID field.
	Children  []ChangedValue `json:",omitempty"`
}

ChangedValue keeps recursively information of changed values.

type Field

type Field struct {
	Name        string
	SQLSelect   string
	Permission  Permission
	Information query.Column
	Validator   validator
	NoSQLColumn bool // defines a none db column.
}

Field is holding the struct field information.

type Interface

type Interface interface {
	Init(Interface) error
	Scope() (Scope, error)

	First(c ...condition.Condition) error
	All(result interface{}, c ...condition.Condition) error
	Count(c ...condition.Condition) (int, error)
	Create() error
	Update() error
	Delete() error

	// Permissions
	Permissions() (p int, fields []string)
	SetPermissions(p int, fields ...string)

	// Defaults
	DefaultBuilder() query.Builder
	DefaultTableName() string
	DefaultDatabaseName() string
	DefaultSoftDelete() SoftDelete
	DefaultCache() (cache.Manager, time.Duration)
	DefaultStrategy() string
	// contains filtered or unexported methods
}

Interface of the orm model.

type Join

type Join struct {
	Table                string
	ForeignColumnName    string
	ReferencesColumnName string
}

Join struct.

type Mapping

type Mapping struct {
	ForeignKey  Field
	References  Field
	Polymorphic Polymorphic
	Join        Join
}

Mapping struct defines the relation between two or more tables.

type Model

type Model struct {
	TimeFields
	// contains filtered or unexported fields
}

Model struct has to get embedded to enable the orm features.

func (*Model) All

func (m *Model) All(result interface{}, c ...condition.Condition) error

All will return all results found by the condition. The result argument must be as ptr slice to the struct. The condition is optional, if set the first argument will be used. No error will return if no result was found.

func (*Model) Count

func (m *Model) Count(c ...condition.Condition) (int, error)

Count the existing rows by the given condition. TODO move the logic to provider for none db orm in the future?

func (*Model) Create

func (m *Model) Create() (err error)

Create the given orm model. A transaction will be created in the background for all relations and a rollback will be triggered if an error happens. The orm model will be checked if its valid by tags. TODO tx on different database drivers.

func (Model) DefaultBuilder

func (m Model) DefaultBuilder() query.Builder

DefaultBuilder will return nil by default and will cause an error. It must get overwritten by the struct.

func (Model) DefaultCache

func (m Model) DefaultCache() (cache.Manager, time.Duration)

DefaultCache will return nil and will cause an error. It must get overwritten by the struct.

func (Model) DefaultDatabaseName

func (m Model) DefaultDatabaseName() string

DefaultDatabaseName will return the builder configured database.

func (Model) DefaultSoftDelete

func (m Model) DefaultSoftDelete() SoftDelete

DefaultSoftDelete returns the default soft deleting. Which is the "DeletedAt" Field if it exists in the database backend.

func (Model) DefaultStrategy

func (m Model) DefaultStrategy() string

DefaultStrategy will be eager.

func (Model) DefaultTableName

func (m Model) DefaultTableName() string

DefaultTableName will be the plural struct name in snake style.

func (*Model) Delete

func (m *Model) Delete() (err error)

Delete the orm model by its primary keys. A transaction will be created in the background for all relations and a rollback will be triggered if an error happens.

func (*Model) First

func (m *Model) First(c ...condition.Condition) error

First will return the first found row. The condition is optional, if set the first argument will be used. A sql.ErrNoRows will return if no result was found.

func (*Model) Init

func (m *Model) Init(caller Interface) error

Init the orm mode.

func (Model) IsValid

func (m Model) IsValid() error

IsValid checks if a custom validation was added and runs it. After that the struct will be validated by tag, if set.

func (*Model) Permissions

func (m *Model) Permissions() (p int, fields []string)

Permissions returns the permission policy and defined fields.

func (*Model) Scope

func (m *Model) Scope() (Scope, error)

Scope will return the models scope with some helper functions. Error will return if the model was not initialized yet.

func (*Model) SetPermissions

func (m *Model) SetPermissions(p int, fields ...string)

SetPermissions allows to set a policy (White/Blacklist), Fields or Relations.

func (*Model) Update

func (m *Model) Update() (err error)

Update the given orm model. A transaction will be created in the background for all relations and a rollback will be triggered if an error happens. The orm model will be checked if its valid by tags. A snapshot is taken and only changed values will trigger a sql query. TODO tx on different database drivers.

type Permission

type Permission struct {
	Read  bool
	Write bool
}

Permission of the field. If read or write is disabled, the database strategy will ignore this field.

type Polymorphic

type Polymorphic struct {
	TypeField Field
	Value     string
}

Polymorphic struct.

type Relation

type Relation struct {
	Field string
	Kind  string
	Type  reflect.Type

	NoSQLColumn bool
	Permission  Permission
	Validator   validator

	Mapping Mapping
}

Relation struct.

func (Relation) IsPolymorphic

func (r Relation) IsPolymorphic() bool

IsPolymorphic returns true if a polymorphic was defined for this relation.

type Scope

type Scope interface {
	Name(bool) string

	Builder() query.Builder
	FqdnTable() string
	FqdnModel(string) string
	Model() *Model
	Caller() Interface

	Cache() cache.Manager
	SetCache(mgr cache.Manager) error

	SQLFields(permission Permission) []Field
	Fields(permission Permission) []Field
	SQLScanFields(permission Permission) []interface{}
	SQLColumns(permission Permission) []string

	Field(name string) (*Field, error)
	FieldValue(name string) reflect.Value

	SQLRelation(relation string, permission Permission) (Relation, error)
	SQLRelations(permission Permission) []Relation
	Relations(permission Permission) []Relation

	PrimaryKeys() ([]Field, error)
	PrimaryKeysSet() bool

	// helper
	InitRelationByField(field string, setParent bool) (Interface, error)
	InitRelation(relation Interface, field string) error
	SetBackReference(Relation) error
	NewScopeFromType(reflect.Type) (Scope, error)

	// experimental
	Config(...string) config
	SetConfig(*config, ...string)
	SoftDelete() *SoftDelete
	Parent(name string) (*Model, error) // needed for back reference
	SetParent(model *Model)             // needed to avoid loops when called from outside of the orm package (grid).
	IsEmpty(Permission) bool            // needed in create
	IsSelfReferenceLoop(relation Relation) bool
	IsSelfReferencing(relation Relation) bool

	TakeSnapshot(bool)
	Snapshot() Interface

	ChangedValues() []ChangedValue
	AppendChangedValue(c ChangedValue)
	SetChangedValues(c []ChangedValue)
	ChangedValueByFieldName(field string) *ChangedValue
	// contains filtered or unexported methods
}

Scope provide some useful helper functions for the orm.Model.

type SoftDelete

type SoftDelete struct {
	Field        string // the sql name
	Value        interface{}
	ActiveValues []interface{}
}

SoftDelete should return the field and value. If the ActiveValues are nil, sql NULL will be searched as active value.

type Strategy

type Strategy interface {
	First(scope Scope, c condition.Condition, permission Permission) error
	All(res interface{}, scope Scope, c condition.Condition) error
	Create(scope Scope) error
	Update(scope Scope, c condition.Condition) error
	Delete(scope Scope, c condition.Condition) error

	// reserved for none eager strategies to load relations
	Load(interface{}) Strategy
}

Strategy interface.

type TimeFields

type TimeFields struct {
	CreatedAt *query.NullTime `orm:"permission:w" json:",omitempty"`
	UpdatedAt *query.NullTime `orm:"permission:w" json:",omitempty"`
	DeletedAt *query.NullTime `orm:"permission:w" json:",omitempty"`
}

TimeFields are embedded in every model. If the fields exists in the DB, the will be filled automatically. But they are excluded from First and All. This behaviour can be changed by permission.

Jump to

Keyboard shortcuts

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