schema

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2025 License: MIT Imports: 18 Imported by: 8

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrFieldNotFound added in v0.1.0

func ErrFieldNotFound(schemaName, fieldName string) error

func ErrInvalidFieldValue added in v0.1.0

func ErrInvalidFieldValue(fieldName string, value any, errs ...error) error

func GetSchemasFromDir

func GetSchemasFromDir(dir string, systemSchemaTypes ...any) (map[string]*Schema, error)

func MergeFields added in v0.1.0

func MergeFields(f1, f2 *Field)

Merge Fields merge second field to the first field.

func NewRelationBackRefError

func NewRelationBackRefError(relation *Relation) error

func NewRelationNodeError

func NewRelationNodeError(schema *Schema, field *Field) error

func StringToFieldValue added in v0.1.0

func StringToFieldValue[T any](field *Field, strValue string) (T, error)

StringToFieldValue converts a string value to a specific type based on the provided field.

Types

type Builder

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

Builder holds the schema of the database.

func NewBuilderFromDir

func NewBuilderFromDir(dir string, systemSchemaTypes ...any) (*Builder, error)

NewBuilderFromDir creates a new schema builder from a directory.

func NewBuilderFromSchemas added in v0.0.5

func NewBuilderFromSchemas(dir string, schemas map[string]*Schema, systemSchemaTypes ...any) (*Builder, error)

NewBuilderFromSchemas creates a new schema from a map of schemas.

func (*Builder) AddSchema

func (b *Builder) AddSchema(schema *Schema)

AddSchema adds a new schema

func (*Builder) Clone

func (b *Builder) Clone() *Builder

Clone clones the builder.

func (*Builder) CreateFKs

func (b *Builder) CreateFKs() error

CreateFKs creates all foreign keys for relations

func (*Builder) CreateM2mJunctionSchema

func (b *Builder) CreateM2mJunctionSchema(currentSchema *Schema, r *Relation) (*Schema, bool, error)

func (*Builder) CreateRelations

func (b *Builder) CreateRelations() (err error)

CreateRelations creates all relations between nodes

func (*Builder) Dir

func (b *Builder) Dir(dirs ...string) string

Dir returns the directory of the builder. If dirs is not empty, it will set the dir to the first element of dirs.

func (*Builder) Init

func (b *Builder) Init() (err error)

Init initializes the builder.

func (*Builder) Relation

func (b *Builder) Relation(name string) *Relation

Relation returns a relation by it's name

func (*Builder) Relations

func (b *Builder) Relations() []*Relation

Relations returns all relations

func (*Builder) ReplaceSchema

func (b *Builder) ReplaceSchema(name string, schema *Schema)

ReplaceSchema replaces a schema

func (*Builder) SaveToDir

func (b *Builder) SaveToDir(dir string) error

SaveToDir saves all the schemas to a directory.

func (*Builder) Schema

func (b *Builder) Schema(name string) (*Schema, error)

Schema returns a node by it's name

func (*Builder) SchemaFile

func (b *Builder) SchemaFile(name string) string

SchemaFile returns the json file path of a schema

func (*Builder) Schemas

func (b *Builder) Schemas() []*Schema

Schemas returns all schemas

type CustomizableSchema added in v0.1.0

type CustomizableSchema interface {
	Schema() *Schema
}

CustomizableSchema allows the struct to customize the schema.

Method `Schema` should return the customized schema.
It supports the following types of customization:
	- Customize schema information:
		- Name
		- Namespace
		- LabelFieldName
		- DisableTimestamp
		- IsJunctionSchema
		- DB
	- Customize all field information, except `IsSystemField`:
		- Adding `Fields` ([]*Field) property to the returned schema to customize the fields.
		- Each field item contains data to customize schema field (partially or fully).
		- Matching will be done based on the field name.
		- Matched field item will be used to customize the corresponding schema field.
		- Non-matched field item will be ignored.

type Field

type Field struct {
	Type       FieldType `json:"type"`
	Name       string    `json:"name"`
	Label      string    `json:"label"`
	IsMultiple bool      `json:"multiple,omitempty"`  // Is a multiple field.
	Size       int64     `json:"size,omitempty"`      // max size parameter for string, blob, etc.
	Unique     bool      `json:"unique,omitempty"`    // column with unique constraint.
	Optional   bool      `json:"optional,omitempty"`  // null or not null attribute.
	Default    any       `json:"default,omitempty"`   // default value.
	Immutable  bool      `json:"immutable,omitempty"` // immutable field.
	Setter     string    `json:"setter,omitempty"`    // setter expression.
	Getter     string    `json:"getter,omitempty"`    // getter expression.

	// Querier
	Sortable   bool           `json:"sortable,omitempty"`   // Has a "sort" option in the tag.
	Filterable bool           `json:"filterable,omitempty"` // Has a "filter" option in the tag.
	Renderer   *FieldRenderer `json:"renderer,omitempty"`   // renderer of the field.
	Enums      []*FieldEnum   `json:"enums,omitempty"`      // enum values.
	Relation   *Relation      `json:"relation,omitempty"`   // relation of the field.
	DB         *FieldDB       `json:"db,omitempty"`         // db config for the field.

	// SystemField is field created from Go code, not from user schema.
	IsSystemField bool `json:"is_system_field,omitempty"` // Is a system field.
	// Lock flag to prevent the field from being modified from API.
	IsLocked bool `json:"is_locked,omitempty"` // Is a locked field.
	// contains filtered or unexported fields
}

Field define the data struct for a field

func CreateUint64Field

func CreateUint64Field(name string) *Field

func (*Field) Clone

func (f *Field) Clone() *Field

Clone returns a copy of the field.

func (*Field) Init

func (f *Field) Init(schemaNames ...string) (err error)

Init initializes the field. schemaNames is the current schema that the field belongs to. schemaNames is required for file field.

func (*Field) IsValidValue

func (f *Field) IsValidValue(value any) bool

IsValidValue returns true if the value is valid for the column

type FieldDB

type FieldDB struct {
	Attr      string `json:"attr,omitempty"`      // extra attributes.
	Collation string `json:"collation,omitempty"` // collation type (utf8mb4_unicode_ci, utf8mb4_general_ci)
	Increment bool   `json:"increment,omitempty"` // auto increment
	Key       string `json:"key,omitempty"`       // key definition (PRI, UNI or MUL).
}

FieldDB define the db config for a field

func (*FieldDB) Clone

func (f *FieldDB) Clone() *FieldDB

type FieldEnum

type FieldEnum struct {
	Value string `json:"value"`
	Label string `json:"label"`
}

FieldEnum define the data struct for an enum field

func (*FieldEnum) Clone

func (f *FieldEnum) Clone() *FieldEnum

type FieldPair added in v0.1.0

type FieldPair struct {
	StructField string
	SchemaField string
}

While converting struct to schema, we need to convert the struct fields to schema fields.

We will need to know which struct field maps to which schema field.
This is done by making pairs of struct field and schema field.

type FieldRenderer

type FieldRenderer struct {
	Class    string         `json:"class,omitempty"`    // renderer class name
	Settings map[string]any `json:"settings,omitempty"` // renderer settings.
}

FieldRenderer define the renderer of a field

func (*FieldRenderer) Clone added in v0.1.0

func (fr *FieldRenderer) Clone() *FieldRenderer

type FieldType

type FieldType int

FieldType define the data type of a field

const (
	TypeInvalid FieldType = iota
	TypeBool
	TypeTime
	TypeJSON
	TypeUUID
	TypeBytes
	TypeEnum
	TypeString
	TypeText
	TypeInt8
	TypeInt16
	TypeInt32
	TypeInt
	TypeInt64
	TypeUint8
	TypeUint16
	TypeUint32
	TypeUint
	// TypeUintptr
	TypeUint64
	TypeFloat32
	TypeFloat64
	TypeRelation
	TypeFile
)

func FieldTypeFromReflectType added in v0.1.0

func FieldTypeFromReflectType(t reflect.Type) FieldType

func FieldTypeFromString added in v0.1.0

func FieldTypeFromString(s string) FieldType

func (FieldType) IsAtomic added in v0.1.0

func (t FieldType) IsAtomic() bool

IsAtomic reports if the given type is an atomic type.

func (FieldType) IsRelationType

func (t FieldType) IsRelationType() bool

func (FieldType) MarshalJSON

func (t FieldType) MarshalJSON() ([]byte, error)

MarshalJSON marshal an enum value to the quoted json string value

func (FieldType) String

func (t FieldType) String() string

String returns the string representation of a type.

func (FieldType) StructType added in v0.1.0

func (t FieldType) StructType() reflect.Type

StructType returns the reflect.Type of the field type

func (*FieldType) UnmarshalJSON

func (t *FieldType) UnmarshalJSON(b []byte) error

UnmarshalJSON unmashals a quoted json string to the enum value

func (FieldType) Valid

func (t FieldType) Valid() bool

Valid reports if the given type if known type.

type GetterArgs added in v0.6.0

type GetterArgs struct {
	Schema *Schema
	Entity *entity.Entity
	Value  any
	Exist  bool
}

type GetterProgram added in v0.6.0

type GetterProgram = expr.Program[GetterArgs, any]

type Relation

type Relation struct {
	BackRef    *Relation `json:"-"` // back reference relation
	Name       string    `json:"-"` // relation name: auto generated
	SchemaName string    `json:"-"` // schema name: get from the current schema
	FieldName  string    `json:"-"` // field name: get from the current field

	TargetSchemaName string `json:"schema"`          // target schema name
	TargetFieldName  string `json:"field,omitempty"` // target field name, aka the back reference field name

	Type            RelationType       `json:"type"`            // the relation type: o2o, o2m, m2m
	Owner           bool               `json:"owner,omitempty"` // the relation owner: true, false
	FKColumns       *RelationFKColumns `json:"fk_columns"`
	JunctionTable   string             `json:"junction_table,omitempty"` // junction table name for m2m relation
	Optional        bool               `json:"optional"`
	FKFields        []*Field           `json:"-"`
	RelationSchemas []*Schema          `json:"-"` // for m2m relation
	JunctionSchema  *Schema            `json:"-"` // for m2m relation
}

Reation define the relation structure

func (*Relation) Clone

func (r *Relation) Clone() *Relation

Clone clone the relation

func (*Relation) CreateFKFields

func (r *Relation) CreateFKFields() (*Field, error)

CreateFKFields create the foreign key fields

func (*Relation) GetBackRefName

func (r *Relation) GetBackRefName() string

GetBackRefName get the back reference name

func (*Relation) GetFKColumns

func (r *Relation) GetFKColumns() *RelationFKColumns

GetFKColumns return the foreign key columns

func (*Relation) GetTargetFKColumn

func (r *Relation) GetTargetFKColumn() string

GetTargetFKColumn return the FK column name for o2m and o2o relation

func (*Relation) HasFKs

func (r *Relation) HasFKs() bool

HasFKs check if the relation has foreign keys

func (*Relation) Init

func (r *Relation) Init(schema *Schema, relationSchema *Schema, f *Field) *Relation

Init initialize the relation

func (*Relation) IsBidi

func (r *Relation) IsBidi() bool

IsBidi check if the relation is bidirectional

func (*Relation) IsSameType

func (r *Relation) IsSameType() bool

IsSameType check if the relation is same type

type RelationFKColumns

type RelationFKColumns struct {
	CurrentColumn string `json:"current_column"`
	TargetColumn  string `json:"target_column"`
}

type RelationType

type RelationType int

RelationType define the relation type of a field

const (
	RelationInvalid RelationType = iota
	O2O
	O2M
	M2M
)

func RelationTypeFromString added in v0.1.0

func RelationTypeFromString(s string) RelationType

func (RelationType) IsM2M

func (t RelationType) IsM2M() bool

func (RelationType) IsO2M

func (t RelationType) IsO2M() bool

func (RelationType) IsO2O

func (t RelationType) IsO2O() bool

func (RelationType) MarshalJSON

func (t RelationType) MarshalJSON() ([]byte, error)

MarshalJSON marshal an enum value to the quoted json string value

func (RelationType) String

func (t RelationType) String() string

String returns the string representation of a type.

func (*RelationType) UnmarshalJSON

func (t *RelationType) UnmarshalJSON(b []byte) error

UnmarshalJSON unmashals a quoted json string to the enum value

func (RelationType) Valid

func (t RelationType) Valid() bool

Valid reports if the given type if known type.

type Schema

type Schema struct {
	*SystemSchema `json:"-"`

	Name             string    `json:"name"`
	Namespace        string    `json:"namespace"`
	LabelFieldName   string    `json:"label_field"`
	DisableTimestamp bool      `json:"disable_timestamp"`
	Fields           []*Field  `json:"fields"`
	IsSystemSchema   bool      `json:"is_system_schema,omitempty"`
	IsJunctionSchema bool      `json:"is_junction_schema,omitempty"`
	DB               *SchemaDB `json:"db,omitempty"`
	// contains filtered or unexported fields
}

Schema holds the node data.

func CreateSchema added in v0.1.0

func CreateSchema(t any) (*Schema, error)

CreateSchema creates a schema from the given struct.

Schema information:
	- Will be created from the struct type: name, namespace.
	- Customize through CustomizableSchema interface: Supports all schema properties/fields.
	- Customize through specific field "_ any `\"fs:name=schema_name, name\"`": Does not support customizing fields.
Fields information:
	- The struct fields will be converted to schema fields.
	- The struct field tags will be used to customize the schema fields.
	- The struct field  conversion will follow the following rules:
	- If the field is not exported, it will be ignored.
	- If the field is a primitive/time type, it will be mapped arcorrdingly reflectTypesToFieldType.
	- If the field is a struct or slice of struct, it must has a field tag define it as a relation.
	- If the field is a complex type of primitives, it must has a field tag to define the type as json.
	- Enums field must be string with struct tag: fs.enums="[{'value': 'v1', 'label': 'L1'}, {'value': 'v2', 'label': 'L2'}]".

func NewSchemaFromJSON

func NewSchemaFromJSON(jsonData string) (*Schema, error)

NewSchemaFromJSON creates a new node from a json string.

func NewSchemaFromJSONFile

func NewSchemaFromJSONFile(jsonFile string) (*Schema, error)

NewSchemaFromJSONFile creates a new node from a json file.

func NewSchemaFromMap added in v0.5.0

func NewSchemaFromMap(data map[string]interface{}) (*Schema, error)

func (*Schema) ApplyGetters added in v0.6.0

func (s *Schema) ApplyGetters(ctx context.Context, e *entity.Entity, configs ...expr.Config) error

ApplyGetters applies the getter programs to the given entity.

func (*Schema) ApplySetters added in v0.6.0

func (s *Schema) ApplySetters(ctx context.Context, e *entity.Entity, configs ...expr.Config) error

ApplySetters applies the setter programs to the given entity.

func (*Schema) Clone

func (s *Schema) Clone() *Schema

Clone returns a copy of the schema.

func (*Schema) CreateField added in v0.1.0

func (s *Schema) CreateField(sf reflect.StructField) (*Field, error)

func (*Schema) CreateFields added in v0.1.0

func (s *Schema) CreateFields() error

func (*Schema) Customize added in v0.1.0

func (s *Schema) Customize() (_ *Schema, err error)

func (*Schema) ExtendFieldByTag added in v0.1.0

func (s *Schema) ExtendFieldByTag(sf reflect.StructField, field *Field) error

ExtendFieldByTag extends the given field by parsing the struct field tag and updating the field properties accordingly.

Common properties format:
- E.g: `fs:"type=string;name=custom_name;label=Custom Label;size=10;multiple;unique;optional;sortable;filterable;default=10"`
- Supported field properties:
	- type: Tag fs="type=string".
	- name: Use json tag to customize the field name, e.g. `json:"custom_name"`.
	- label: Tag fs="label=Custom Label".
	- size: Tag fs="size=10".
	- multiple: Tag fs="multiple".
	- unique: Tag fs="unique".
	- optional: Tag fs="optional".
	- sortable: Tag fs="sortable".
	- filterable: Tag fs="filterable".
	- default: Tag fs="default=10", if field is time, use RFC3339 format.
Complex properties format:
- E.g: `fs.enums="[{'value': 'v1', 'label': 'L1'}, {'value': 'v2', 'label': 'L2'}]"`
- E.g: `fs.relation="{'type': 'o2m', 'schema': 'post', 'field': 'categories', 'owner': true}"`
	- enums: Only for string fields. Tag fs.enums=hjson -> []*FieldEnum
	- relation: Tag fs.relation=hjson -> *Relation
	- renderer: Tag fs.renderer=hjson -> *Field.Renderer
	- db: Tag fs.db=hjson -> *FieldDB

To extend other field properties, you can implement the CustomizableSchema interface.

func (*Schema) Field

func (s *Schema) Field(name string) *Field

Field return field by it's name

func (*Schema) HasField

func (s *Schema) HasField(fieldName string) bool

HasField checks if the schema has a field.

func (*Schema) Init

func (s *Schema) Init(disableIDColumn bool) error

Init initializes the node.

func (*Schema) SaveToFile

func (s *Schema) SaveToFile(filename string) error

SaveToFile saves the schema to a file.

func (*Schema) Validate

func (s *Schema) Validate() error

Validate inspects the fields of the schema for validation errors.

type SchemaDB

type SchemaDB struct {
	Indexes []*SchemaDBIndex `json:"indexes,omitempty"`
}

type SchemaDBIndex

type SchemaDBIndex struct {
	Name    string   `json:"name,omitempty"`
	Unique  bool     `json:"unique,omitempty"`
	Columns []string `json:"columns,omitempty"`
}

type SetterArgs added in v0.6.0

type SetterArgs struct {
	Schema *Schema
	Entity *entity.Entity
	Value  any
	Exist  bool
}

type SetterProgram added in v0.6.0

type SetterProgram = expr.Program[SetterArgs, any]

type SystemSchema added in v0.1.0

type SystemSchema struct {
	Instance   any
	RType      reflect.Type
	FieldPairs []*FieldPair
}

type Undefined added in v0.6.0

type Undefined struct{}

Jump to

Keyboard shortcuts

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