Documentation
¶
Overview ¶
Package strata provides a three-tier auto-caching data library unifying in-memory (L1), Redis (L2), and PostgreSQL (L3) behind a single API.
Index ¶
- Variables
- func GetTyped[T any](ctx context.Context, ds *DataStore, schemaName, id string) (*T, error)
- func Q() *queryBuilder
- func SearchTyped[T any](ctx context.Context, ds *DataStore, schemaName string, q *Query) ([]T, error)
- func Version() string
- type AES256GCM
- type Codec
- type Config
- type DataStore
- func (ds *DataStore) Close() error
- func (ds *DataStore) Count(ctx context.Context, schemaName string, q *Query) (int64, error)
- func (ds *DataStore) Delete(ctx context.Context, schemaName, id string) error
- func (ds *DataStore) Exists(ctx context.Context, schemaName, id string) (bool, error)
- func (ds *DataStore) FlushDirty(ctx context.Context) error
- func (ds *DataStore) Get(ctx context.Context, schemaName, id string, dest any) error
- func (ds *DataStore) Invalidate(ctx context.Context, schemaName, id string) error
- func (ds *DataStore) InvalidateAll(ctx context.Context, schemaName string) error
- func (ds *DataStore) Migrate(ctx context.Context) error
- func (ds *DataStore) MigrateFrom(ctx context.Context, dir string) error
- func (ds *DataStore) MigrationStatus(ctx context.Context) ([]MigrationRecord, error)
- func (ds *DataStore) ReEmbed(ctx context.Context, schemaName, textFieldName string) error
- func (ds *DataStore) Register(s Schema) error
- func (ds *DataStore) Search(ctx context.Context, schemaName string, q *Query, destSlice any) error
- func (ds *DataStore) SearchCached(ctx context.Context, schemaName string, q *Query, destSlice any) error
- func (ds *DataStore) Set(ctx context.Context, schemaName, id string, value any) error
- func (ds *DataStore) SetMany(ctx context.Context, schemaName string, pairs map[string]any) error
- func (ds *DataStore) Stats() Stats
- func (ds *DataStore) Tx(ctx context.Context) *Tx
- func (ds *DataStore) VectorSearch(ctx context.Context, schemaName string, query string, topK int, ...) ([]SimilarityResult, error)
- func (ds *DataStore) WarmCache(ctx context.Context, schemaName string, limit int) error
- type EmbeddingProvider
- type Encryptor
- type EvictionPolicy
- type Index
- type IndexType
- type L1PoolConfig
- type L2PoolConfig
- type L3PoolConfig
- type L4Config
- type L4Policy
- type Logger
- type MemPolicy
- type MetricsRecorder
- type MigrationRecord
- type OllamaProvider
- type OpenAIProvider
- type PostgresPolicy
- type Query
- type RedisPolicy
- type Schema
- type SchemaHooks
- type SimilarityResult
- type Stats
- type Tx
- type WriteMode
Constants ¶
This section is empty.
Variables ¶
var ( ErrSchemaNotFound = errors.New("strata: schema not registered") ErrSchemaDuplicate = errors.New("strata: schema already registered") ErrNoPrimaryKey = errors.New("strata: struct has no primary_key field") ErrInvalidModel = errors.New("strata: model must be a non-nil pointer to a struct") ErrMissingPrimaryKey = errors.New("strata: value is missing primary key") )
Schema errors
var ( ErrNotFound = errors.New("strata: record not found") ErrDecodeFailed = errors.New("strata: failed to decode stored value") ErrEncodeFailed = errors.New("strata: failed to encode value for storage") )
Data errors
var ( )
Infrastructure errors
var ( ErrTxFailed = errors.New("strata: transaction failed") ErrTxTimeout = errors.New("strata: transaction timeout") )
Transaction errors
var ( ErrNoVectorField = errors.New("strata: schema has no vector field") ErrPgvectorExtensionMissing = errors.New("strata: pgvector extension not installed; run: CREATE EXTENSION IF NOT EXISTS vector;") ErrVectorDimensionMismatch = errors.New("strata: vector dimension does not match index") ErrInvalidIndexType = errors.New("strata: invalid index type for field") ErrTopKInvalid = errors.New("strata: topK must be >= 1") ErrNoEmbeddingProvider = errors.New("strata: EmbeddingProvider is required for vector schemas; set Config.EmbeddingProvider to NewOllamaProvider or NewOpenAIProvider") ErrEmbeddingModelChanged = errors.New("strata: embedding model has changed since last migration; call ds.ReEmbed() to migrate") ErrReEmbedAlreadyRunning = errors.New("strata: re-embed migration already in progress") ErrReEmbedTextFieldMissing = errors.New("strata: specified text field not found in schema model") ErrInvalidTagForType = errors.New("strata: strata:\"vector\" tag requires field type pgvector.Vector") ErrEmptyVectorQuery = errors.New("strata: vector query string must not be empty") ErrNilContext = errors.New("strata: context must not be nil") )
Vector / pgvector errors
var ( // BuildDate is the date and time the binary was built. // Set by: -ldflags "-X 'github.com/AndrewDonelson/strata.BuildDate=2026.02.28-1750'" BuildDate = "0000.00.00-0000" // BuildEnv is the target environment for this build. // Set by: -ldflags "-X 'github.com/AndrewDonelson/strata.BuildEnv=dev'" BuildEnv = "dev" )
Build-time variables injected via -ldflags by the Makefile. Defaults represent an unversioned local development build.
BuildDate format : YYYY.MM.DD-HHMM (24-hour clock) BuildEnv values : dev | qa | prod
Full version example: "2026.02.28-1750-dev"
var (
ErrHookPanic = errors.New("strata: hook panicked")
)
Hook errors
var (
ErrInsufficientFunds = errors.New("strata: insufficient funds")
)
Domain errors
var (
ErrInvalidConfig = errors.New("strata: invalid configuration")
)
Config errors
var (
ErrWriteBehindMaxRetry = errors.New("strata: write-behind exceeded max retries")
)
Write-behind errors
Functions ¶
Types ¶
type AES256GCM ¶
type AES256GCM struct {
// contains filtered or unexported fields
}
AES256GCM implements AES-256-GCM authenticated encryption.
func NewAES256GCM ¶
NewAES256GCM creates an AES-256-GCM encryptor from a 32-byte key.
type Config ¶
type Config struct {
// DSNs
PostgresDSN string
RedisAddr string
RedisPassword string
RedisDB int
// Pool sizes
L1Pool L1PoolConfig
L2Pool L2PoolConfig
L3Pool L3PoolConfig
// TTLs
DefaultL1TTL time.Duration
DefaultL2TTL time.Duration
// Write behaviour
DefaultWriteMode WriteMode
WriteBehindFlushInterval time.Duration
WriteBehindFlushThreshold int
WriteBehindMaxRetry int
// Invalidation
InvalidationChannel string
// L4 distributed peer sync (optional; schemas opt-in via Schema.L4.Enabled)
L4 L4Config
// Optional overrideable components
Codec codec.Codec
Clock clock.Clock
Metrics metrics.MetricsRecorder
Logger Logger
// Encryption key (must be 32 bytes for AES-256-GCM; nil = disabled).
EncryptionKey []byte
// EmbeddingProvider — required when any registered schema has a strata:"vector" field.
// If nil and a vector schema is registered, ds.Migrate() returns ErrNoEmbeddingProvider.
// Use NewOllamaProvider or NewOpenAIProvider to create a provider.
EmbeddingProvider EmbeddingProvider
}
Config contains all DataStore configuration.
type DataStore ¶
type DataStore struct {
// contains filtered or unexported fields
}
DataStore is the main entry-point for the Strata library.
func NewDataStore ¶
NewDataStore creates and initialises a DataStore from the provided Config.
func (*DataStore) FlushDirty ¶
FlushDirty blocks until all write-behind entries are flushed to L3.
func (*DataStore) Get ¶
Get fetches the record with the given id into dest. dest must be a pointer to the model type of the registered schema.
func (*DataStore) Invalidate ¶
Invalidate removes a key from all cache tiers and publishes an invalidation event.
func (*DataStore) InvalidateAll ¶
InvalidateAll flushes all cached entries for schemaName across L1 and L2.
func (*DataStore) MigrateFrom ¶
MigrateFrom applies SQL migration files from dir in NNN_description.sql order.
func (*DataStore) MigrationStatus ¶
func (ds *DataStore) MigrationStatus(ctx context.Context) ([]MigrationRecord, error)
MigrationStatus returns current migration state.
func (*DataStore) ReEmbed ¶
ReEmbed walks all L3 records for schemaName in batches of 100, re-embedding the textFieldName field using the current EmbeddingProvider. It is resumable: if interrupted, a subsequent call picks up where it left off using the reembed_progress counter in strata_schema_meta.
On completion it updates strata_schema_meta with the new model ID and dimension. If the dimension changed, it also rebuilds the vector index.
Returns ErrReEmbedAlreadyRunning if another migration is in progress, ErrReEmbedTextFieldMissing if textFieldName does not match any struct field, or a summary error if some records failed to embed.
func (*DataStore) Register ¶
Register compiles and stores a Schema definition. Returns ErrInvalidTagForType if a strata:"vector" tag is applied to a non-pgvector.Vector field, or ErrInvalidIndexType if an IVFFlat/HNSW index is applied to a non-vector field.
func (*DataStore) Search ¶
Search runs q against L3 and returns the results in destSlice (pointer to slice).
func (*DataStore) SearchCached ¶
func (ds *DataStore) SearchCached(ctx context.Context, schemaName string, q *Query, destSlice any) error
SearchCached runs q against L3; caches list result in L2 by SQL fingerprint.
func (*DataStore) VectorSearch ¶
func (ds *DataStore) VectorSearch( ctx context.Context, schemaName string, query string, topK int, filters map[string]any, ) ([]SimilarityResult, error)
VectorSearch performs an approximate nearest-neighbour search over the vector field of the named schema, using the configured EmbeddingProvider to embed the plain-text query string internally.
topK must be ≥ 1; filters maps column names to equality values (AND logic). Results are ordered by cosine similarity (highest first) and are back-filled into L2 then L1 before returning.
Returns ErrTopKInvalid, ErrSchemaNotFound, ErrNoVectorField, ErrNoEmbeddingProvider, ErrPgvectorExtensionMissing, or ErrEmptyVectorQuery for invalid inputs.
type EmbeddingProvider ¶
type EmbeddingProvider interface {
// Embed converts text to a vector. The returned vector length must equal Dimensions().
Embed(ctx context.Context, text string) (pgvector.Vector, error)
// Dimensions returns the number of dimensions this provider produces.
// Strata calls this once at schema Register time to size the Postgres column.
// Implementations should cache the value after the first resolution.
Dimensions() int
// ModelID returns a stable identifier for the current embedding model
// (e.g. "nomic-embed-text", "text-embedding-3-small").
// Strata stores this in strata_schema_meta and compares it on every Migrate()
// to detect model changes that require re-embedding.
ModelID() string
}
EmbeddingProvider converts text to a fixed-size float32 vector. Strata calls it once per VectorSearch query and once per record during ReEmbed. Implementations must be safe for concurrent use.
func NewOllamaProvider ¶
func NewOllamaProvider(baseURL, modelName string) EmbeddingProvider
NewOllamaProvider creates an OllamaProvider that embeds text using the model running at baseURL/api/embed. The dimension is resolved on the first Embed() or Dimensions() call and cached for subsequent calls.
func NewOpenAIProvider ¶
func NewOpenAIProvider(apiKey, modelName string) EmbeddingProvider
NewOpenAIProvider creates an OpenAIProvider using the official embeddings endpoint.
type Encryptor ¶
type Encryptor interface {
Encrypt(plaintext []byte) ([]byte, error)
Decrypt(ciphertext []byte) ([]byte, error)
}
Encryptor encrypts and decrypts field values for fields tagged with "encrypted".
type EvictionPolicy ¶
type EvictionPolicy int
EvictionPolicy determines which L1 entry is evicted when MaxEntries is reached.
const ( EvictLRU EvictionPolicy = iota EvictLFU EvictFIFO )
type Index ¶
type Index struct {
Fields []string // column names
Unique bool
Name string // optional; auto-generated if empty
Type IndexType // IndexDefault (btree) | IndexIVFFlat | IndexHNSW | IndexTrigram
Lists int // IVFFlat: number of lists (default: 100)
M int // HNSW: max connections per layer (default: 16)
EfConstruction int // HNSW: build-time search width (default: 64)
DistanceFunc string // "cosine" | "l2" | "ip" (default: "cosine")
}
Index defines a database index on one or more columns.
type L1PoolConfig ¶
type L1PoolConfig struct {
MaxEntries int
Eviction EvictionPolicy
}
L1PoolConfig configures the in-memory L1 cache tier.
type L2PoolConfig ¶
type L2PoolConfig struct {
PoolSize int
DialTimeout time.Duration
ReadTimeout time.Duration
WriteTimeout time.Duration
}
L2PoolConfig configures the Redis L2 cache tier client.
type L3PoolConfig ¶
type L3PoolConfig struct {
MaxConns int32
MinConns int32
MaxConnLifetime time.Duration
MaxConnIdleTime time.Duration
}
L3PoolConfig configures the PostgreSQL L3 connection pool.
type L4Config ¶
type L4Config struct {
Enabled bool // false = L4 is entirely inactive (default)
Mode string // "peer" (in-memory) or "ledger" (BoltDB-backed)
Port int // TCP listen port; default 7743
DataDir string // BoltDB directory for ledger mode; default "/var/lib/strata/l4"
SyncInterval time.Duration // gossip sync frequency; default 30s
MaxPeers int // max simultaneous peer connections; default 50
Quorum int // confirmations needed for pending → confirmed; default 3
BootstrapPeers []string // "host:port" addresses to dial on startup
DNSSeed string // DNS seed hostname for peer discovery
NodeKeyPath string // path to load/persist the Ed25519 node private key
}
L4Config configures the optional L4 distributed peer-to-peer sync layer. Set Enabled = true to activate; choose Mode and set Port/DataDir/Quorum as needed. Individual schemas opt-in via Schema.L4.Enabled.
type L4Policy ¶
type L4Policy struct {
Enabled bool // false = no L4 sync for this schema (default)
AppID string // L4 namespace; defaults to schema Name
SyncDeletes bool // if true, Delete() → L4 Revoke(); false = L4 record is left as-is
}
L4Policy configures optional L4 distributed-ledger sync for a schema. When Enabled is true, every successful L3 write is automatically published to the L4 peer layer. Deletes are revoked if SyncDeletes is also true.
type Logger ¶
type Logger interface {
Info(msg string, keysAndValues ...any)
Warn(msg string, keysAndValues ...any)
Error(msg string, keysAndValues ...any)
Debug(msg string, keysAndValues ...any)
}
Logger is the logging interface used internally by Strata. Implement this to route logs to zap, slog, logrus, etc.
type MemPolicy ¶
type MemPolicy struct {
TTL time.Duration
MaxEntries int
Eviction EvictionPolicy
}
MemPolicy configures L1 in-memory cache behavior for a schema.
type MetricsRecorder ¶
type MetricsRecorder = metrics.MetricsRecorder
Re-export types so callers only import this package.
type MigrationRecord ¶
MigrationRecord describes a single applied migration.
type OllamaProvider ¶
type OllamaProvider struct {
// contains filtered or unexported fields
}
OllamaProvider calls a local Ollama instance to generate embeddings. Dimensions() is auto-detected by calling Embed() once on startup and cached.
Example:
strata.NewOllamaProvider("http://cqai:11434", "nomic-embed-text")
func (*OllamaProvider) Dimensions ¶
func (p *OllamaProvider) Dimensions() int
Dimensions implements EmbeddingProvider. Calls Embed("") once to resolve the dimension, then caches it.
func (*OllamaProvider) ModelID ¶
func (p *OllamaProvider) ModelID() string
ModelID implements EmbeddingProvider.
type OpenAIProvider ¶
type OpenAIProvider struct {
// contains filtered or unexported fields
}
OpenAIProvider calls the OpenAI embeddings API (or compatible endpoints).
Example:
strata.NewOpenAIProvider(os.Getenv("OPENAI_API_KEY"), "text-embedding-3-small")
func (*OpenAIProvider) Dimensions ¶
func (p *OpenAIProvider) Dimensions() int
Dimensions implements EmbeddingProvider. Returns the known dimension for well-known models without an API call, falling back to a real Embed() call for unknown models.
func (*OpenAIProvider) ModelID ¶
func (p *OpenAIProvider) ModelID() string
ModelID implements EmbeddingProvider.
type PostgresPolicy ¶
PostgresPolicy configures L3 Postgres persistence for a schema.
type Query ¶
type Query struct {
Where string
Args []any
OrderBy string
Desc bool
Limit int
Offset int
Fields []string
ForceL3 bool
ForceL2 bool
}
Query specifies search parameters for the Search and SearchCached operations.
type RedisPolicy ¶
RedisPolicy configures L2 Redis cache behavior for a schema.
type Schema ¶
type Schema struct {
Name string
Model any
L1 MemPolicy
L2 RedisPolicy
L3 PostgresPolicy
L4 L4Policy
WriteMode WriteMode
Indexes []Index
Hooks SchemaHooks
}
Schema defines one data collection and its caching policy.
type SchemaHooks ¶
type SchemaHooks struct {
BeforeSet func(ctx context.Context, value any) error
AfterSet func(ctx context.Context, value any)
BeforeGet func(ctx context.Context, id string)
AfterGet func(ctx context.Context, value any)
OnEvict func(ctx context.Context, key string, value any)
OnWriteError func(ctx context.Context, key string, err error)
}
SchemaHooks provides optional lifecycle callbacks.
type SimilarityResult ¶
type SimilarityResult struct {
// ID is the primary-key value of the matching record.
ID string
// Score is the cosine similarity (0.0 = orthogonal, 1.0 = identical).
// Computed as 1 − cosine_distance, assuming unit-normalised vectors.
Score float64
// Value is the fully-hydrated model struct (same type as the schema Model).
// The embedding/vector field IS populated when results come directly from L3.
Value any
}
SimilarityResult is one item returned by VectorSearch.
type Stats ¶
type Stats struct {
Gets int64
Sets int64
Deletes int64
Errors int64
DirtyCount int64
L1Entries int64
}
Stats is the snapshot returned by DataStore.Stats().
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Tx is a lightweight transaction helper that queues L3 operations and updates caches on commit.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
clock
Package clock provides a testable clock interface for TTL calculations.
|
Package clock provides a testable clock interface for TTL calculations. |
|
codec
Package codec provides encode/decode interfaces for cache serialization.
|
Package codec provides encode/decode interfaces for cache serialization. |
|
l1
Package l1 provides a sharded, concurrent in-memory cache with TTL and eviction.
|
Package l1 provides a sharded, concurrent in-memory cache with TTL and eviction. |
|
l2
Package l2 provides the Redis tier cache adapter.
|
Package l2 provides the Redis tier cache adapter. |
|
l3
Package l3 provides the PostgreSQL persistence tier adapter.
|
Package l3 provides the PostgreSQL persistence tier adapter. |
|
l4
Package l4 provides the optional distributed ledger sync layer for Strata.
|
Package l4 provides the optional distributed ledger sync layer for Strata. |
|
metrics
Package metrics provides the MetricsRecorder interface and a noop implementation.
|
Package metrics provides the MetricsRecorder interface and a noop implementation. |
|
Package l4 re-exports the Strata L4 distributed sync layer for first-party consumers (such as LADL) that need direct access to the ledger primitives.
|
Package l4 re-exports the Strata L4 distributed sync layer for first-party consumers (such as LADL) that need direct access to the ledger primitives. |