Documentation
¶
Index ¶
- func DecodeBase32ToUUID(s string) (uuid.UUID, error)
- func DecodeFromBase32(s string) ([]byte, error)
- func EncodeToBase32(data []byte) string
- func EncodeUUIDToBase32(id uuid.UUID) string
- func MapKeys[K comparable, V any](m map[K]V) []K
- func MapValues[K comparable, V any](m map[K]V) []V
- func NewEntityManager(transformer PersistentRecordTransformer, repository PersistentRecordRepository, ...) forma.EntityManager
- type AttributeConverter
- func (c *AttributeConverter) FromEAVRecord(record EAVRecord, valueType ValueType) (EntityAttribute, error)
- func (c *AttributeConverter) FromEAVRecords(records []EAVRecord) ([]EntityAttribute, error)
- func (c *AttributeConverter) ToEAVRecord(attr EntityAttribute, rowID uuid.UUID) (EAVRecord, error)
- func (c *AttributeConverter) ToEAVRecords(attributes []EntityAttribute, rowID uuid.UUID) ([]EAVRecord, error)
- type AttributeFallbackKind
- type AttributeFallbackMetadata
- type AttributeMetadata
- type AttributeOrder
- type AttributeQuery
- type AttributeStorageLocation
- type AttributeStorageMetadata
- type EAVRecord
- type EntityAttribute
- func (ea *EntityAttribute) BigInt() (*int64, error)
- func (ea *EntityAttribute) Bool() (*bool, error)
- func (ea *EntityAttribute) Date() (*time.Time, error)
- func (ea *EntityAttribute) DateTime() (*time.Time, error)
- func (ea *EntityAttribute) Integer() (*int32, error)
- func (ea *EntityAttribute) Numeric() (*float64, error)
- func (ea *EntityAttribute) SmallInt() (*int16, error)
- func (ea *EntityAttribute) Text() (*string, error)
- func (ea *EntityAttribute) UUID() (*uuid.UUID, error)
- type JSONSchema
- type MainColumn
- type MainColumnBinding
- type MainColumnEncoding
- type MainColumnType
- type MetadataCache
- type MetadataLoader
- type PersistentRecord
- type PersistentRecordPage
- type PersistentRecordQuery
- type PersistentRecordRepository
- type PersistentRecordTransformer
- type PostgresPersistentRecordRepository
- func (r *PostgresPersistentRecordRepository) DeletePersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) error
- func (r *PostgresPersistentRecordRepository) GetPersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) (*PersistentRecord, error)
- func (r *PostgresPersistentRecordRepository) InsertPersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
- func (r *PostgresPersistentRecordRepository) QueryPersistentRecords(ctx context.Context, query *PersistentRecordQuery) (*PersistentRecordPage, error)
- func (r *PostgresPersistentRecordRepository) UpdatePersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
- type PropertySchema
- type RelationSchema
- type SQLGenerator
- type SchemaAttributeCache
- type SchemaMetadata
- type SchemaRegistry
- type Set
- type StorageTables
- type Transformer
- type ValueType
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecodeFromBase32 ¶
func EncodeToBase32 ¶
func EncodeUUIDToBase32 ¶
func MapKeys ¶
func MapKeys[K comparable, V any](m map[K]V) []K
MapKeys extracts all keys from a map and returns them as a slice. The order of keys is non-deterministic due to map iteration.
func MapValues ¶
func MapValues[K comparable, V any](m map[K]V) []V
MapValues extracts all values from a map and returns them as a slice. The order of values is non-deterministic due to map iteration.
func NewEntityManager ¶
func NewEntityManager( transformer PersistentRecordTransformer, repository PersistentRecordRepository, registry SchemaRegistry, config *forma.Config, ) forma.EntityManager
NewEntityManager creates a new EntityManager instance
Types ¶
type AttributeConverter ¶
type AttributeConverter struct {
// contains filtered or unexported fields
}
AttributeConverter provides conversion between EntityAttribute and EAVRecord
func NewAttributeConverter ¶
func NewAttributeConverter(registry SchemaRegistry) *AttributeConverter
NewAttributeConverter creates a new AttributeConverter instance
func (*AttributeConverter) FromEAVRecord ¶
func (c *AttributeConverter) FromEAVRecord(record EAVRecord, valueType ValueType) (EntityAttribute, error)
FromEAVRecord converts an EAVRecord to an EntityAttribute
func (*AttributeConverter) FromEAVRecords ¶
func (c *AttributeConverter) FromEAVRecords(records []EAVRecord) ([]EntityAttribute, error)
FromEAVRecords converts a slice of EAVRecords to EntityAttributes
func (*AttributeConverter) ToEAVRecord ¶
func (c *AttributeConverter) ToEAVRecord(attr EntityAttribute, rowID uuid.UUID) (EAVRecord, error)
ToEAVRecord converts an EntityAttribute to an EAVRecord
func (*AttributeConverter) ToEAVRecords ¶
func (c *AttributeConverter) ToEAVRecords(attributes []EntityAttribute, rowID uuid.UUID) ([]EAVRecord, error)
ToEAVRecords converts a slice of EntityAttributes to EAVRecords
type AttributeFallbackKind ¶
type AttributeFallbackKind string
AttributeFallbackKind describes lossy storage behaviors.
const ( AttributeFallbackKindNone AttributeFallbackKind = "none" AttributeFallbackKindNumericToDouble AttributeFallbackKind = "numeric_to_double" AttributeFallbackKindDateToDouble AttributeFallbackKind = "date_to_double" AttributeFallbackKindDateToText AttributeFallbackKind = "date_to_text" AttributeFallbackKindBoolToDouble AttributeFallbackKind = "bool_to_double" AttributeFallbackKindBoolToText AttributeFallbackKind = "bool_to_text" )
type AttributeFallbackMetadata ¶
type AttributeFallbackMetadata struct {
Enabled bool `json:"enabled"`
Kind AttributeFallbackKind `json:"kind"`
ColumnType MainColumnType `json:"column_type"`
Encoding MainColumnEncoding `json:"encoding"`
Notes string `json:"notes"`
}
AttributeFallbackMetadata captures whether predicate rewrites are required.
type AttributeMetadata ¶
type AttributeMetadata struct {
AttributeName string `json:"attr_name"` // attr_name, JSON Path
AttributeID int16 `json:"attr_id"` // attr_id
ValueType ValueType `json:"value_type"` // 'text', 'numeric', 'date', 'bool'
Storage *AttributeStorageMetadata `json:"storage,omitempty"`
}
AttributeMetadata stores cached metadata from the attributes table.
func (AttributeMetadata) IsInsideArray ¶
func (m AttributeMetadata) IsInsideArray() bool
IsInsideArray infers if the attribute is inside an array based on its name.
type AttributeOrder ¶
type AttributeOrder struct {
AttrID int16
ValueType ValueType
SortOrder forma.SortOrder
StorageLocation AttributeStorageLocation // main or eav
ColumnName string // main table column name if StorageLocation == main
}
AttributeOrder specifies how to sort by a particular attribute.
func (*AttributeOrder) AttrIDInt ¶
func (ao *AttributeOrder) AttrIDInt() int
AttrIDInt returns the attribute ID as an int (for template compatibility).
func (*AttributeOrder) Desc ¶
func (ao *AttributeOrder) Desc() bool
Desc returns true if the sort order is descending.
func (*AttributeOrder) IsMainColumn ¶
func (ao *AttributeOrder) IsMainColumn() bool
IsMainColumn returns true if the attribute is stored in the main table.
func (*AttributeOrder) MainColumnName ¶
func (ao *AttributeOrder) MainColumnName() string
MainColumnName returns the column name in the main table.
func (*AttributeOrder) ValueColumn ¶
func (ao *AttributeOrder) ValueColumn() string
ValueColumn returns the EAV table column name for this attribute's value type.
type AttributeQuery ¶
type AttributeStorageLocation ¶
type AttributeStorageLocation string
AttributeStorageLocation enumerates where the attribute physically resides.
const ( AttributeStorageLocationUnknown AttributeStorageLocation = "" AttributeStorageLocationMain AttributeStorageLocation = "main" AttributeStorageLocationEAV AttributeStorageLocation = "eav" )
type AttributeStorageMetadata ¶
type AttributeStorageMetadata struct {
Location AttributeStorageLocation `json:"location"`
ColumnBinding *MainColumnBinding `json:"column_binding,omitempty"`
Fallback AttributeFallbackMetadata `json:"fallback"`
}
AttributeStorageMetadata records where and how an attribute is stored.
type EAVRecord ¶
type EAVRecord struct {
SchemaID int16
RowID uuid.UUID // UUID v7, identifies data row
AttrID int16 // Attribute ID from schema definition
ArrayIndices string // Comma-separated array indices (e.g., "0", "1,2", or "" for non-arrays)
ValueText *string // For valueType: "text"
ValueNumeric *float64 // For valueType: "numeric"
}
ValueType represents the type of value stored in a row of EAV table.
type EntityAttribute ¶
type EntityAttribute struct {
SchemaID int16
RowID uuid.UUID // UUID v7, identifies data row
AttrID int16
ArrayIndices string
ValueType ValueType
Value any
}
func (*EntityAttribute) BigInt ¶
func (ea *EntityAttribute) BigInt() (*int64, error)
func (*EntityAttribute) Bool ¶
func (ea *EntityAttribute) Bool() (*bool, error)
func (*EntityAttribute) Integer ¶
func (ea *EntityAttribute) Integer() (*int32, error)
func (*EntityAttribute) Numeric ¶
func (ea *EntityAttribute) Numeric() (*float64, error)
func (*EntityAttribute) SmallInt ¶
func (ea *EntityAttribute) SmallInt() (*int16, error)
func (*EntityAttribute) Text ¶
func (ea *EntityAttribute) Text() (*string, error)
type JSONSchema ¶
type JSONSchema struct {
ID int16 `json:"id"`
Name string `json:"name"`
Version int `json:"version"`
Schema string `json:"schema"`
Properties map[string]*PropertySchema `json:"properties"`
Required []string `json:"required"`
CreatedAt int64 `json:"created_at"`
}
JSONSchema represents a schema definition.
type MainColumn ¶
type MainColumn string
MainColumn enumerates available hot columns.
const ( MainColumnText01 MainColumn = "text_01" MainColumnText02 MainColumn = "text_02" MainColumnText03 MainColumn = "text_03" MainColumnText04 MainColumn = "text_04" MainColumnText05 MainColumn = "text_05" MainColumnText06 MainColumn = "text_06" MainColumnText07 MainColumn = "text_07" MainColumnText08 MainColumn = "text_08" MainColumnText09 MainColumn = "text_09" MainColumnText10 MainColumn = "text_10" MainColumnSmallint01 MainColumn = "smallint_01" MainColumnSmallint02 MainColumn = "smallint_02" MainColumnInteger01 MainColumn = "integer_01" MainColumnInteger02 MainColumn = "integer_02" MainColumnInteger03 MainColumn = "integer_03" MainColumnBigint01 MainColumn = "bigint_01" MainColumnBigint02 MainColumn = "bigint_02" MainColumnBigint03 MainColumn = "bigint_03" MainColumnBigint04 MainColumn = "bigint_04" MainColumnBigint05 MainColumn = "bigint_05" MainColumnDouble01 MainColumn = "double_01" MainColumnDouble02 MainColumn = "double_02" MainColumnDouble03 MainColumn = "double_03" MainColumnDouble04 MainColumn = "double_04" MainColumnDouble05 MainColumn = "double_05" MainColumnUUID01 MainColumn = "uuid_01" MainColumnUUID02 MainColumn = "uuid_02" )
type MainColumnBinding ¶
type MainColumnBinding struct {
ColumnName MainColumn `json:"col_name"`
Encoding MainColumnEncoding `json:"encoding,omitempty"`
}
MainColumnBinding describes how a schema attribute maps into a hot attribute column.
func (*MainColumnBinding) ColumnType ¶
func (m *MainColumnBinding) ColumnType() MainColumnType
type MainColumnEncoding ¶
type MainColumnEncoding string
MainColumnEncoding captures how logical values are encoded into the physical column.
const ( MainColumnEncodingDefault MainColumnEncoding = "default" MainColumnEncodingUnixMs MainColumnEncoding = "unix_ms" MainColumnEncodingBoolInt MainColumnEncoding = "bool_smallint" MainColumnEncodingBoolText MainColumnEncoding = "bool_text" MainColumnEncodingISO8601 MainColumnEncoding = "iso8601" )
type MainColumnType ¶
type MainColumnType string
MainColumnType enumerates physical column families inside the hot attributes table.
const ( MainColumnTypeText MainColumnType = "text" MainColumnTypeSmallint MainColumnType = "smallint" MainColumnTypeInteger MainColumnType = "integer" MainColumnTypeBigint MainColumnType = "bigint" MainColumnTypeDouble MainColumnType = "double" MainColumnTypeUUID MainColumnType = "uuid" )
type MetadataCache ¶
type MetadataCache struct {
// contains filtered or unexported fields
}
MetadataCache holds all metadata mappings for fast lookups
func NewMetadataCache ¶
func NewMetadataCache() *MetadataCache
NewMetadataCache creates a new metadata cache
func (*MetadataCache) GetSchemaCache ¶
func (mc *MetadataCache) GetSchemaCache(schemaName string) (SchemaAttributeCache, bool)
GetSchemaCache retrieves the schema attribute cache for a schema (thread-safe)
func (*MetadataCache) GetSchemaID ¶
func (mc *MetadataCache) GetSchemaID(schemaName string) (int16, bool)
GetSchemaID retrieves schema ID by name (thread-safe)
func (*MetadataCache) GetSchemaName ¶
func (mc *MetadataCache) GetSchemaName(schemaID int16) (string, bool)
GetSchemaName retrieves schema name by ID (thread-safe)
func (*MetadataCache) ListSchemas ¶
func (mc *MetadataCache) ListSchemas() []string
ListSchemas returns all schema names (thread-safe)
type MetadataLoader ¶
type MetadataLoader struct {
// contains filtered or unexported fields
}
MetadataLoader loads schema and attribute metadata from database and JSON files
func NewMetadataLoader ¶
func NewMetadataLoader(pool *pgxpool.Pool, schemaTableName, schemaDirectory string) *MetadataLoader
NewMetadataLoader creates a new metadata loader
func (*MetadataLoader) LoadMetadata ¶
func (ml *MetadataLoader) LoadMetadata(ctx context.Context) (*MetadataCache, error)
LoadMetadata loads all metadata and returns a cache
type PersistentRecord ¶
type PersistentRecord struct {
SchemaID int16
RowID uuid.UUID
TextItems map[string]string // e.g., "text_01" -> "Hello"
Int16Items map[string]int16
Int32Items map[string]int32
Int64Items map[string]int64
Float64Items map[string]float64
CreatedAt int64
UpdatedAt int64
DeletedAt *int64
OtherAttributes []EAVRecord // EAV attributes not in hot table
}
* PersistentRecord 是一个用于表示持久化存储记录的结构体,包含了`entity main`和EAV Attributes。
type PersistentRecordPage ¶
type PersistentRecordPage struct {
Records []*PersistentRecord
TotalRecords int64
TotalPages int
CurrentPage int
}
type PersistentRecordQuery ¶
type PersistentRecordQuery struct {
Tables StorageTables
SchemaID int16
Condition forma.Condition
AttributeOrders []AttributeOrder
Limit int
Offset int
}
type PersistentRecordRepository ¶
type PersistentRecordRepository interface {
InsertPersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
UpdatePersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
DeletePersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) error
GetPersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) (*PersistentRecord, error)
QueryPersistentRecords(ctx context.Context, query *PersistentRecordQuery) (*PersistentRecordPage, error)
}
type PersistentRecordTransformer ¶
type PersistentRecordTransformer interface {
ToPersistentRecord(ctx context.Context, schemaID int16, rowID uuid.UUID, jsonData any) (*PersistentRecord, error)
FromPersistentRecord(ctx context.Context, record *PersistentRecord) (map[string]any, error)
}
func NewPersistentRecordTransformer ¶
func NewPersistentRecordTransformer(registry SchemaRegistry) PersistentRecordTransformer
NewPersistentRecordTransformer creates a new PersistentRecordTransformer instance
type PostgresPersistentRecordRepository ¶
type PostgresPersistentRecordRepository struct {
// contains filtered or unexported fields
}
func NewPostgresPersistentRecordRepository ¶
func NewPostgresPersistentRecordRepository(pool *pgxpool.Pool, metadataCache *MetadataCache) *PostgresPersistentRecordRepository
func (*PostgresPersistentRecordRepository) DeletePersistentRecord ¶
func (r *PostgresPersistentRecordRepository) DeletePersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) error
func (*PostgresPersistentRecordRepository) GetPersistentRecord ¶
func (r *PostgresPersistentRecordRepository) GetPersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) (*PersistentRecord, error)
func (*PostgresPersistentRecordRepository) InsertPersistentRecord ¶
func (r *PostgresPersistentRecordRepository) InsertPersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
func (*PostgresPersistentRecordRepository) QueryPersistentRecords ¶
func (r *PostgresPersistentRecordRepository) QueryPersistentRecords(ctx context.Context, query *PersistentRecordQuery) (*PersistentRecordPage, error)
func (*PostgresPersistentRecordRepository) UpdatePersistentRecord ¶
func (r *PostgresPersistentRecordRepository) UpdatePersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
type PropertySchema ¶
type PropertySchema struct {
Name string `json:"name"`
Type string `json:"type"` // "string", "integer", "number", "boolean", "array", "object", "null"
Format string `json:"format,omitempty"`
Items *PropertySchema `json:"items,omitempty"`
Properties map[string]*PropertySchema `json:"properties,omitempty"`
Required bool `json:"required"`
Default any `json:"default,omitempty"`
Enum []any `json:"enum,omitempty"`
Minimum *float64 `json:"minimum,omitempty"`
Maximum *float64 `json:"maximum,omitempty"`
MinLength *int `json:"minLength,omitempty"`
MaxLength *int `json:"maxLength,omitempty"`
Pattern string `json:"pattern,omitempty"`
Relation *RelationSchema `json:"x-relation,omitempty"`
Storage string `json:"x-storage,omitempty"` // "json" for free-form objects
}
PropertySchema defines the schema for a single property.
type RelationSchema ¶
type RelationSchema struct {
Target string `json:"target"` // Target schema name
Type string `json:"type"` // "reference" for foreign key relationships
}
RelationSchema defines reference relationships between objects.
type SQLGenerator ¶
type SQLGenerator struct{}
SQLGenerator converts parsed conditions into SQL fragments and argument lists.
func NewSQLGenerator ¶
func NewSQLGenerator() *SQLGenerator
NewSQLGenerator constructs a SQLGenerator.
func (*SQLGenerator) ToSqlClauses ¶
func (g *SQLGenerator) ToSqlClauses( condition forma.Condition, eavTable string, schemaID int16, cache SchemaAttributeCache, paramIndex *int, ) (string, []any, error)
ToSqlClauses builds the SQL clause and arguments for a condition tree.
type SchemaAttributeCache ¶
type SchemaAttributeCache map[string]AttributeMetadata
SchemaAttributeCache is a mapping of attr_name -> metadata. Strongly recommended to populate per schema_id at application startup.
type SchemaMetadata ¶
type SchemaMetadata struct {
SchemaName string `json:"schema_name"`
SchemaID int16 `json:"schema_id"`
SchemaVersion int `json:"schema_version"`
Attributes []AttributeMetadata `json:"attributes"`
}
SchemaMetadata aggregates attribute mappings for a schema version.
type SchemaRegistry ¶
type SchemaRegistry interface {
GetSchemaByName(name string) (int16, SchemaAttributeCache, error)
GetSchemaByID(id int16) (string, SchemaAttributeCache, error)
ListSchemas() []string
}
func NewFileSchemaRegistry ¶
func NewFileSchemaRegistry(schemaDir string) (SchemaRegistry, error)
NewFileSchemaRegistry creates a new file-based schema registry
type Set ¶
type Set[T comparable] struct { // contains filtered or unexported fields }
Set is a generic data structure that represents a collection of unique items. It uses a map internally for O(1) operations.
func (*Set[T]) Add ¶
func (s *Set[T]) Add(item T)
Add inserts an item into the set. If the item already exists, it has no effect.
type StorageTables ¶
type Transformer ¶
type Transformer interface {
// Single object conversion
ToAttributes(ctx context.Context, schemaID int16, rowID uuid.UUID, jsonData any) ([]EntityAttribute, error)
FromAttributes(ctx context.Context, attributes []EntityAttribute) (map[string]any, error)
// Batch operations
BatchToAttributes(ctx context.Context, schemaID int16, jsonObjects []any) ([]EntityAttribute, error)
BatchFromAttributes(ctx context.Context, attributes []EntityAttribute) ([]map[string]any, error)
// Validation
ValidateAgainstSchema(ctx context.Context, jsonSchema any, jsonData any) error
}
func NewTransformer ¶
func NewTransformer(registry SchemaRegistry) Transformer
NewTransformer creates a new Transformer instance backed by the provided schema registry.
type ValueType ¶
type ValueType string
ValueType represents supported attribute value types.
const ( ValueTypeText ValueType = "text" ValueTypeSmallInt ValueType = "smallint" ValueTypeInteger ValueType = "integer" ValueTypeBigInt ValueType = "bigint" ValueTypeNumeric ValueType = "numeric" // double precision ValueTypeDate ValueType = "date" // for JSON attributes with format `date` ValueTypeDateTime ValueType = "datetime" // for JSON attributes with format `date-time` ValueTypeUUID ValueType = "uuid" ValueTypeBool ValueType = "bool" )
Source Files
¶
- advanced_query_template.go
- attribute_converter.go
- base32.go
- collections.go
- entity_main.go
- entity_manager.go
- interfaces.go
- jsonschema.go
- metadata_loader.go
- metadata_parser.go
- metadata_types.go
- persistent_transformer.go
- postgres_persistent_repository.go
- schema_metadata_cache.go
- schema_registry.go
- sql_generator.go
- sql_helpers.go
- transformer.go
- types.go
- utils.go