internal

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2025 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeBase32ToUUID

func DecodeBase32ToUUID(s string) (uuid.UUID, error)

func DecodeFromBase32

func DecodeFromBase32(s string) ([]byte, error)

func EncodeToBase32

func EncodeToBase32(data []byte) string

func EncodeUUIDToBase32

func EncodeUUIDToBase32(id uuid.UUID) string

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 AttributeQuery struct {
	SchemaID        int16            `json:"schemaId"`
	Condition       forma.Condition  `json:"condition,omitempty"`
	OrderBy         []forma.OrderBy  `json:"orderBy"`
	AttributeOrders []AttributeOrder `json:"attributeOrders"`
	Limit           int              `json:"limit"`
	Offset          int              `json:"offset"`
}

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) Date

func (ea *EntityAttribute) Date() (*time.Time, error)

func (*EntityAttribute) DateTime

func (ea *EntityAttribute) DateTime() (*time.Time, 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)

func (*EntityAttribute) UUID

func (ea *EntityAttribute) UUID() (*uuid.UUID, 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 (*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 NewSet

func NewSet[T comparable]() *Set[T]

NewSet creates and returns a new empty Set.

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.

func (*Set[T]) Clear

func (s *Set[T]) Clear()

Clear removes all items from the set.

func (*Set[T]) Contains

func (s *Set[T]) Contains(item T) bool

Contains checks if an item exists in the set.

func (*Set[T]) Remove

func (s *Set[T]) Remove(item T)

Remove deletes an item from the set. If the item doesn't exist, it has no effect.

func (*Set[T]) Size

func (s *Set[T]) Size() int

Size returns the number of items in the set.

func (*Set[T]) ToSlice

func (s *Set[T]) ToSlice() []T

ToSlice converts the set to a slice containing all items. The order of items is non-deterministic due to map iteration.

type StorageTables

type StorageTables struct {
	EntityMain string
	EAVData    string
}

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"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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