Documentation
¶
Overview ¶
Package store is the SOLE owner of the github.com/duckdb/duckdb-go/v2 import in this module. Phase 57 decision D-12 locks the duckdb-go module path to `github.com/duckdb/duckdb-go/v2` at version `v2.10502.0` (the canonical DuckDB Foundation Go binding repo; the historical `marcboeker/go-duckdb` repository was archived 2025-10-20 and MUST NOT be used).
Boundary enforcement: the cmd/vet-noduckdb/ analyzer (Phase 57 plan P04) fails the build if any package outside this directory imports duckdb-go. The analyzer's `forbiddenImport` constant is the prefix `github.com/duckdb/duckdb-go`, so any future major-version bump still trips the gate.
Three-tier open contract (STORE-01) ¶
Open(ctx, cfg, logger, metrics) classifies the workspace's `<workspace>/.helix/semantic.duckdb` into one of three tiers:
existing+clean — file exists, opens cleanly, schema-version row is present and ≤ CurrentSchemaVersion. Open returns the Store. Counter: helix_semantic_store_open_total{outcome="opened"}.
quarantine+rebuild — file exists but is corrupt, has an unreadable schema-version table, or has a forward-incompatible version. Open renames the file to `<path>.corrupt.<unix-ts>` (T-57-02-02: refuses to follow symlinks at the rename target), emits slog.Warn, increments helix_semantic_store_quarantine_total{reason=...}, and creates a fresh DB at the original path. Counter: helix_semantic_store_open_total{outcome="quarantined"}.
hard fail — Tier-2 rebuild itself fails (e.g., disk full, permission denied). Open returns an error so the daemon refuses to start.
Quarantine reasons are a closed enum (D-07): {corrupt_file, schema_forward_incompat, schema_unreadable, unknown}.
Schema versioning (D-01, D-02, D-03) ¶
`semantic_schema_version` holds an INTEGER PRIMARY KEY column stamped to CurrentSchemaVersion (= 1 in P57). Each snapshot row in `semantic_snapshots` ALSO records `schema_version INTEGER NOT NULL` so readers can detect mid-rebuild inconsistency. Migrations are declared in migrations.go as a slice of Migration{From, To, Kind} where Kind ∈ {InPlace, Reindex}.
CGO=0 stub policy (D-12, STORE-04) ¶
duckdb-go requires CGO. Under CGO_ENABLED=0, duckdb_nocgo.go provides a stub Store whose every method returns serr.ErrUnsupported. The daemon's step 6a refuses to start under CGO=0 (Phase 51.1), so the stub is only exercised in unit tests built with CGO_ENABLED=0 explicitly.
Schema 1 contract ¶
Phase 57 ships Schema 1 empty-but-correct: every SPEC §8 table is created (16 tables enumerated in migrations.go), `semantic_schema_version` row = 1, and the QueryEffective* read API returns empty results because there are no data write paths in P57. P59 (snapshot writes) and P60 (overlay writes) populate the data the read API serves.
Concurrency (T-57-02-04) ¶
DuckDB acquires its own file lock at open time. A second daemon instance opening the same workspace's store will get a clear error and refuse to start (Tier-3 hard fail). This is intentional — single-daemon-per-workspace is a v1.10 invariant.
Index ¶
- Constants
- Variables
- type Migration
- type MigrationKind
- type Store
- func (s *Store) Available() bool
- func (s *Store) Close() error
- func (s *Store) QueryEffectiveEdges(ctx context.Context, req any) ([]any, error)
- func (s *Store) QueryEffectiveFiles(ctx context.Context, repoID, path any) (any, error)
- func (s *Store) QueryEffectiveReferences(ctx context.Context, req any) ([]any, error)
- func (s *Store) QueryEffectiveSymbols(ctx context.Context, req any) ([]any, error)
Constants ¶
const CurrentSchemaVersion = 2
CurrentSchemaVersion is the schema version stamped into `semantic_schema_version` by Open when creating a fresh database, and the upper bound for "clean reopen" classification (D-03).
Phase 57 shipped version 1. Phase 59 lights up the registry mechanism for the first time and bumps to version 2 (the partial-extraction columns prescribed by 59-CONTEXT.md D-05). Future versions append entries to the migrations slice (see migrations_registry_cgo.go).
Variables ¶
var ErrForwardIncompatible = errors.New("semantic store: schema_version is forward-incompatible with binary CurrentSchemaVersion; rebuild required")
ErrForwardIncompatible is the sentinel returned by runMigrations (and surfaced by Open) when the on-disk schema_version exceeds the binary's CurrentSchemaVersion. Open propagates this error rather than falling through to the quarantine-and-rebuild path so an operator running a downgraded binary against a newer DB sees an explicit failure they can fix (rebuild via the documented quarantine path) instead of silent data loss from automatic quarantine.
Functions ¶
This section is empty.
Types ¶
type Migration ¶
type Migration struct {
From int
To int
Kind MigrationKind
Apply func(ctx context.Context, db *sql.DB) error
}
Migration declares one version transition. Phase 57's bootstrap migration is From=0, To=1, Kind=InPlace; Phase 59 adds From=1, To=2, Kind=InPlace for the partial-extraction column delta (59-CONTEXT.md D-05).
Apply is the migration body. It is bound only in CGO=1 source files (see migrations_registry_cgo.go) because the bodies reference DuckDB SQL. The CGO=0 build does not exercise the registry — Open under !cgo returns serr.ErrUnsupported before any migration runs.
type MigrationKind ¶
type MigrationKind string
MigrationKind classifies a Migration entry's effect.
D-02: keeping the kind explicit (rather than inferring it from From/To integers) makes the forward-vs-rebuild decision auditable in source.
const ( // MigrationInPlace adds columns / indexes / tables without rewriting // existing rows. Cheap; runs at Open time. MigrationInPlace MigrationKind = "in_place" // MigrationReindex requires re-extracting facts from the workspace. // The store ALONE cannot perform this — it returns a sentinel that the // daemon (or a future migration runner) handles by rebuilding. MigrationReindex MigrationKind = "reindex" )
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the DuckDB-backed semantic fact store. Phase 57 ships Schema 1 empty-but-correct: all SPEC §8 tables exist, no write paths are exposed (P59/P60 land those). The effective-read API surface returns empty results until then.
func Open ¶
func Open(ctx context.Context, cfg semantic.Config, logger *slog.Logger, metrics *obs.Metrics) (*Store, error)
Open opens (or quarantines+rebuilds, or hard-fails) the DuckDB file at `cfg.Store.Path`. Three-tier resolution per CONTEXT.md D-01..D-03:
- existing+clean → reopen, increment open_total{outcome="opened"}.
- existing+corrupt OR forward-incompat OR schema-unreadable → quarantine via .corrupt.<unix-ts> rename and rebuild fresh, incrementing quarantine_total{reason=...} + open_total{outcome="quarantined"}.
- fresh path / no file → create fresh DB, run migration_001, increment open_total{outcome="created"}.
On Tier-2 if the rebuild itself fails, the function returns an error so the daemon's bootstrap step 6b refuses to start (Tier-3 hard fail).
func (*Store) Available ¶
Available reports whether the store is functional in the current build. Under CGO=1 a non-nil Store is functional; under CGO=0 the stub returns false (see duckdb_nocgo.go).
func (*Store) QueryEffectiveEdges ¶
QueryEffectiveEdges returns the effective edge facts matching a query. Phase 57 Schema 1 returns an empty slice.
func (*Store) QueryEffectiveFiles ¶
QueryEffectiveFiles returns the effective file fact (snapshot ⊕ overlay − tombstones) for the given repo+path key. Phase 57 Schema 1 contract: returns nil, nil because no data write paths exist yet.
func (*Store) QueryEffectiveReferences ¶
QueryEffectiveReferences returns the effective reference facts matching a query. Phase 57 Schema 1 returns an empty slice.