model

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultPageSize = 50

DefaultPageSize is the fallback page size used when the caller supplies a non-positive limit.

View Source
const FederatedMaxRows = 10000

FederatedMaxRows is the default per-source fetch cap used by federated queries when no explicit MaxRows option is provided.

Variables

View Source
var (
	TextColumns     = []string{"ltbase_created_by", "ltbase_deleted_by", "ltbase_updated_by", "text_01", "text_02", "text_03", "text_04", "text_05", "text_06", "text_07", "text_08", "text_09", "text_10"}
	SmallintColumns = []string{"smallint_01", "smallint_02", "smallint_03"}
	IntegerColumns  = []string{"integer_01", "integer_02", "integer_03"}
	BigintColumns   = []string{"bigint_01", "bigint_02", "bigint_03"}
	DoubleColumns   = []string{"double_01", "double_02", "double_03"}
	UUIDColumns     = []string{"uuid_01", "uuid_02"}
)

Column slices define the physical hot-storage columns available in entity_main. These are declared once and treated as read-only after package init.

View Source
var (
	AllowedTextColumns     = makeColumnSet(TextColumns)
	AllowedSmallintColumns = makeColumnSet(SmallintColumns)
	AllowedIntegerColumns  = makeColumnSet(IntegerColumns)
	AllowedBigintColumns   = makeColumnSet(BigintColumns)
	AllowedDoubleColumns   = makeColumnSet(DoubleColumns)
	AllowedUUIDColumns     = makeColumnSet(UUIDColumns)
)

allowedXxxColumns are fast O(1) lookup sets built from the column slices above.

View Source
var EntityMainColumnDescriptors = buildEntityMainColumnDescriptors()

EntityMainColumnDescriptors is the ordered list of all columns (system + EAV) used to scan rows from entity_main. It is built once at package load time via a package-level var initializer, avoiding an init() side-effect.

View Source
var EntityMainProjection = func() string {
	names := make([]string, 0, len(EntityMainColumnDescriptors))
	for _, d := range EntityMainColumnDescriptors {
		names = append(names, d.Name)
	}
	return strings.Join(names, ", ")
}()

EntityMainProjection is the comma-separated column list used in SELECT statements against entity_main. Built once at package load time.

View Source
var SystemColumnDescriptors = []ColumnDescriptor{
	{Name: "ltbase_schema_id", Kind: ColumnKindSmallint},
	{Name: "ltbase_row_id", Kind: ColumnKindUUID},
	{Name: "ltbase_created_at", Kind: ColumnKindBigint},
	{Name: "ltbase_updated_at", Kind: ColumnKindBigint},
	{Name: "ltbase_deleted_at", Kind: ColumnKindBigint},
}

SystemColumnDescriptors contains the five fixed metadata columns that appear before the EAV columns in every entity_main SELECT projection. They are not present in the allowedXxx sets, so GetMainColumnDescriptor checks this list separately.

Functions

func CleanupEmptyMaps

func CleanupEmptyMaps(record *PersistentRecord)

CleanupEmptyMaps removes empty maps from the record to avoid nil-map checks

func ColumnKindToValueType

func ColumnKindToValueType(kind ColumnKind) forma.ValueType

ColumnKindToValueType maps a physical column kind to the forma value type used when a raw main-table column is referenced without schema metadata.

func ComputeTotalPages

func ComputeTotalPages(total int64, limit int) int

ComputeTotalPages returns the page count for total records at the given limit.

func IsMainTableColumn

func IsMainTableColumn(name string) bool

IsMainTableColumn reports whether name is a recognised entity_main column. Uses O(1) map lookups — no linear scan.

func ParseAttributesJSON

func ParseAttributesJSON(attrsJSON []byte, record *PersistentRecord) error

ParseAttributesJSON parses JSON-aggregated EAV attributes into the record

Types

type AtomicBatchPersistentRecordRepository

type AtomicBatchPersistentRecordRepository interface {
	BatchInsertPersistentRecords(ctx context.Context, tables StorageTables, records []*PersistentRecord) error
	BatchUpdatePersistentRecords(ctx context.Context, tables StorageTables, records []*PersistentRecord) error
	BatchDeletePersistentRecords(ctx context.Context, tables StorageTables, keys []PersistentRecordKey) error
}

type AttributeOrder

type AttributeOrder struct {
	AttrID          int16
	ValueType       forma.ValueType
	SortOrder       forma.SortOrder
	StorageLocation forma.AttributeStorageLocation
	ColumnName      string
	AttrName        string
}

AttributeOrder specifies how to sort by a particular attribute.

func (*AttributeOrder) AttrIDInt

func (ao *AttributeOrder) AttrIDInt() int

func (*AttributeOrder) Desc

func (ao *AttributeOrder) Desc() bool

func (*AttributeOrder) IsMainColumn

func (ao *AttributeOrder) IsMainColumn() bool

func (*AttributeOrder) MainColumnName

func (ao *AttributeOrder) MainColumnName() string

func (*AttributeOrder) ValueColumn

func (ao *AttributeOrder) ValueColumn() string

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 ColumnDescriptor

type ColumnDescriptor struct {
	Name string
	Kind ColumnKind
}

func GetMainColumnDescriptor

func GetMainColumnDescriptor(name string) *ColumnDescriptor

GetMainColumnDescriptor returns the descriptor for a named entity_main column, or nil if the name is not recognised. Checks the system-column map first, then falls back to the ordered EAV descriptor list (linear but called infrequently).

type ColumnKind

type ColumnKind int
const (
	ColumnKindText ColumnKind = iota
	ColumnKindSmallint
	ColumnKindInteger
	ColumnKindBigint
	ColumnKindDouble
	ColumnKindUUID
)

type ConsistencyMode

type ConsistencyMode string
const (
	ConsistencyModeStrict   ConsistencyMode = "strict"
	ConsistencyModeEventual ConsistencyMode = "eventual"
)

type DataSourcePlan

type DataSourcePlan struct {
	Tier   DataTier
	Engine string
	SQL    string
	// Params holds the string forms of the bind parameters for SQL, in
	// order. Populated only when FederatedQueryOptions.IncludeExecutionPlan
	// is set, so diagnostic artifacts can replay the exact query (#173).
	Params            []string
	RowEstimate       int64
	PredicatePushdown bool
	ActualRows        int64
	DurationMs        int64
	Reason            string
}

type DataTier

type DataTier string
const (
	DataTierHot  DataTier = "hot"
	DataTierWarm DataTier = "warm"
	DataTierCold DataTier = "cold"
)

type DuckDBRenderHints

type DuckDBRenderHints struct {
	S3ParquetPathTemplate string
	TimeEncodingHint      string
}

type EAVRecord

type EAVRecord struct {
	SchemaID     int16
	RowID        uuid.UUID
	AttrID       int16
	ArrayIndices string
	ValueText    *string
	ValueNumeric *float64
	// ValueInt64 is an exact int64 sidecar for bigint and epoch-ms date
	// values. It is in-memory only: eav_data persistence and the EAV read
	// paths keep the float64 ValueNumeric contract (2^53 ceiling), while
	// main-column routing (storeInMainColumn) and read-back prefer
	// ValueInt64 so column-bound bigint/unix_ms values carry the full
	// int64 range without a float64 hop (#205).
	ValueInt64 *int64
}

EAVRecord represents one attribute row in EAV storage.

func ParseEAVAttribute

func ParseEAVAttribute(attrObj map[string]any) (EAVRecord, error)

ParseEAVAttribute converts a JSON object to an EAVRecord

type EntityAttribute

type EntityAttribute struct {
	SchemaID     int16
	RowID        uuid.UUID
	AttrID       int16
	ArrayIndices string
	ValueType    forma.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 ExecutionPlan

type ExecutionPlan struct {
	Routing RoutingDecision
	Sources []DataSourcePlan
	Merge   MergePlan
	Timings map[string]int64
	Notes   []string
}

type FederatedAttributeQuery

type FederatedAttributeQuery struct {
	AttributeQuery
	PreferredTiers  []DataTier
	PreferHot       bool
	UseMainAsAnchor bool
	DuckDBHints     *DuckDBRenderHints
	KeysetCursor    *KeysetCursor
}

type FederatedQueryEngine

type FederatedQueryEngine interface {
	Query(ctx context.Context, tables StorageTables, fq *FederatedAttributeQuery, opts *FederatedQueryOptions) (*PersistentRecordPage, error)
}

type FederatedQueryOptions

type FederatedQueryOptions struct {
	MaxRows                  int
	Parallelism              int
	AllowPartialDegradedMode bool
	KeysetEnabled            bool
	IncludeExecutionPlan     bool
	ExecutionPlan            *ExecutionPlan
	ConsistencyMode          ConsistencyMode
	// PartialScan is an engine out-parameter like ExecutionPlan, but NOT
	// gated on IncludeExecutionPlan: the #348 public partial marker must
	// reach callers that never asked for a plan. The last executed DuckDB
	// pass overwrites it, so it describes the pass that produced the page,
	// and Query resets it at entry, so after any call — including a
	// postgres-only answer that never runs a pass — it describes that call
	// even when one options value is reused across queries.
	// Being an out-parameter, it has nowhere to land when the caller passes
	// nil options: such a call drops the marker, so a caller that needs it
	// must pass a non-nil *FederatedQueryOptions.
	PartialScan *PartialScan
}

type KeysetColumn

type KeysetColumn struct {
	Attribute string
	Direction forma.SortOrder
}

type KeysetCursor

type KeysetCursor struct {
	Columns []KeysetColumn
	Values  []interface{}
	Mode    KeysetCursorMode
}

type KeysetCursorMode

type KeysetCursorMode string
const (
	KeysetCursorModeAfter  KeysetCursorMode = "after"
	KeysetCursorModeBefore KeysetCursorMode = "before"
)

type MergePlan

type MergePlan struct {
	Strategy   MergeStrategy
	PreferHot  bool
	DedupKeys  []string
	DurationMs int64
	Notes      []string
}

type MergeStrategy

type MergeStrategy string
const MergeStrategyLastWriteWins MergeStrategy = "last-write-wins"

type PartialScan

type PartialScan struct {
	ExcludedObjects []string
}

PartialScan reports that the DuckDB pass that answered this query ran over a deliberately reduced object set: verification-confirmed corrupt parquet objects (#251) were excluded and the page came from the readable remainder plus the hot tier. Internal form — ExcludedObjects carries full storage keys for embedders and operators; the public projection (forma.QueryResult.Partial) surfaces only the reason and the count (#348, #301/#306 boundary).

type PersistentRecord

type PersistentRecord struct {
	SchemaID        int16
	RowID           uuid.UUID
	TextItems       map[string]string
	Int16Items      map[string]int16
	Int32Items      map[string]int32
	Int64Items      map[string]int64
	Float64Items    map[string]float64
	UUIDItems       map[string]uuid.UUID
	CreatedAt       int64
	UpdatedAt       int64
	DeletedAt       *int64
	OtherAttributes []EAVRecord
}

PersistentRecord represents a persisted entity row plus EAV attributes.

type PersistentRecordKey

type PersistentRecordKey struct {
	SchemaID int16
	RowID    uuid.UUID
}

type PersistentRecordPage

type PersistentRecordPage struct {
	Records       []*PersistentRecord
	TotalRecords  int64
	TotalPages    int
	CurrentPage   int
	ExecutionPlan *ExecutionPlan
	Partial       *PartialScan
}

type PersistentRecordQuery

type PersistentRecordQuery struct {
	Tables          StorageTables
	SchemaID        int16
	Condition       forma.Condition
	AttributeOrders []AttributeOrder
	Limit           int
	Offset          int
}

type PersistentRecordReader

type PersistentRecordReader interface {
	GetPersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) (*PersistentRecord, error)
	QueryPersistentRecords(ctx context.Context, query *PersistentRecordQuery) (*PersistentRecordPage, error)
	// QueryPersistentRecordsByAttrValues fetches full records whose attribute
	// equals any of the given values via one set-based lookup (#268). It exists
	// for internal batch lookups (relation enrichment); it must never expand to
	// an OR-of-N condition per value.
	QueryPersistentRecordsByAttrValues(ctx context.Context, tables StorageTables, schemaID int16, attr string, values []string, limit int) (*PersistentRecordPage, error)
}

type PersistentRecordRepository

type PersistentRecordRepository interface {
	PersistentRecordWriter
	PersistentRecordReader
}

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

type PersistentRecordWriter

type PersistentRecordWriter 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
}

type RoutingDecision

type RoutingDecision struct {
	Tiers           []DataTier
	UseDuckDB       bool
	Reason          string
	MaxScanRows     int
	QueryTimeout    time.Duration
	AllowS3Fallback bool
}

type StorageTables

type StorageTables struct {
	EntityMain     string
	EAVData        string
	ChangeLog      string
	SchemaRegistry string
}

Jump to

Keyboard shortcuts

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