Documentation
¶
Overview ¶
Package store — FTS5 search methods.
These methods implement the search pipeline from src/db/queries.ts's QueryBuilder.searchNodes (FTS5 BM25 → LIKE fallback → fuzzy Levenshtein, plus an exact-name supplement). They belong in store because the SQL lives here; the scoring/rescoring logic lives in the query package.
Package store implements the .codegraph SQLite knowledge-graph store: nodes, edges, files, unresolved references, and project metadata, plus the FTS5 search index maintained by schema triggers.
Ported from src/db/ of github.com/colbymchenry/codegraph (MIT). The schema (schema.sql) is copied verbatim from the original so indexes remain conceptually compatible; the SQLite driver is modernc.org/sqlite (pure Go, FTS5 included) per ADR-001's pure-Go mandate.
Like the original (one node:sqlite handle), the Store uses a single connection; concurrent use is safe via database/sql's serialization plus WAL mode and busy_timeout.
Index ¶
- Constants
- func EdgeKey(e model.Edge) string
- type CoverageRow
- type GraphStats
- type NodeCoverageRow
- type NowFunc
- type Option
- type Store
- func (s *Store) AllEdges() ([]model.Edge, error)
- func (s *Store) AllNodes() ([]model.Node, error)
- func (s *Store) Clear() error
- func (s *Store) ClearUnresolvedReferences() error
- func (s *Store) Close() error
- func (s *Store) DeleteEdgesBySource(sourceID string) error
- func (s *Store) DeleteFile(filePath string) error
- func (s *Store) DeleteNode(id string) error
- func (s *Store) DeleteNodesByFile(filePath string) error
- func (s *Store) DeleteUnresolvedByNode(nodeID string) error
- func (s *Store) EdgeExists(e model.Edge) (bool, error)
- func (s *Store) ExactNameCaseInsensitive(term string, kinds []model.NodeKind, langs []model.Language, limit int) ([]model.Node, error)
- func (s *Store) ExactNameCaseInsensitiveFiltered(term string, kinds []model.NodeKind, langs []model.Language, limit int, ...) ([]model.Node, error)
- func (s *Store) ExistingEdgeKeys(sourceIDs []string) (map[string]bool, error)
- func (s *Store) ExistingNodeIDs(ids []string) (map[string]struct{}, error)
- func (s *Store) FindEdgesBetweenNodes(nodeIDs []string, kinds []model.EdgeKind) ([]model.Edge, error)
- func (s *Store) GetAllCoverage() ([]CoverageRow, error)
- func (s *Store) GetAllFiles() ([]model.FileRecord, error)
- func (s *Store) GetAllMetadata() (map[string]string, error)
- func (s *Store) GetAllNodeCoverage() ([]NodeCoverageRow, error)
- func (s *Store) GetCoverageByFile(filePath string) (*CoverageRow, error)
- func (s *Store) GetDependencyFilePaths(filePath string) ([]string, error)
- func (s *Store) GetDependentFilePaths(filePath string) ([]string, error)
- func (s *Store) GetFileByPath(filePath string) (*model.FileRecord, error)
- func (s *Store) GetIncomingEdges(targetID string, kinds []model.EdgeKind) ([]model.Edge, error)
- func (s *Store) GetIncomingEdgesForTargetFiles(paths []string) ([]model.Edge, error)
- func (s *Store) GetIncomingEdgesLimited(targetID string, limit int) ([]model.Edge, error)
- func (s *Store) GetLastIndexedAt() (int64, error)
- func (s *Store) GetMetadata(key string) (string, error)
- func (s *Store) GetNodeByID(id string) (*model.Node, error)
- func (s *Store) GetNodesByFile(filePath string) ([]model.Node, error)
- func (s *Store) GetNodesByIDs(ids []string) (map[string]model.Node, error)
- func (s *Store) GetNodesByLowerName(lowerName string) ([]model.Node, error)
- func (s *Store) GetNodesByName(name string) ([]model.Node, error)
- func (s *Store) GetNodesByQualifiedNameExact(qualifiedName string) ([]model.Node, error)
- func (s *Store) GetNodesByQualifiedNameSuffix(qualifiedName string) ([]model.Node, error)
- func (s *Store) GetOutgoingEdges(sourceID string, kinds []model.EdgeKind, provenance string) ([]model.Edge, error)
- func (s *Store) GetOutgoingEdgesByKindLimited(sourceID string, kinds []model.EdgeKind, limit int) ([]model.Edge, error)
- func (s *Store) GetOutgoingEdgesLimited(sourceID string, limit int) ([]model.Edge, error)
- func (s *Store) GetStats() (GraphStats, error)
- func (s *Store) GetTraceEdgesByTarget(targetID string) ([]TraceEdge, error)
- func (s *Store) GetTraceNodes() ([]TraceNode, error)
- func (s *Store) GetUnresolvedByName(name string) ([]model.UnresolvedReference, error)
- func (s *Store) GetUnresolvedReferences() ([]model.UnresolvedReference, error)
- func (s *Store) GetUnresolvedReferencesBatch(offset, limit int) ([]model.UnresolvedReference, error)
- func (s *Store) GetUnresolvedReferencesByFiles(filePaths []string) ([]model.UnresolvedReference, error)
- func (s *Store) GetUnresolvedReferencesCount() (int, error)
- func (s *Store) InsertEdge(e model.Edge) error
- func (s *Store) InsertEdges(edges []model.Edge) error
- func (s *Store) InsertNode(n model.Node) error
- func (s *Store) InsertNodes(nodes []model.Node) error
- func (s *Store) InsertUnresolvedRef(r model.UnresolvedReference) error
- func (s *Store) InsertUnresolvedRefs(refs []model.UnresolvedReference) error
- func (s *Store) IterateNodesByKind(kind model.NodeKind, fn func(model.Node) error) error
- func (s *Store) JournalMode() string
- func (s *Store) Optimize() error
- func (s *Store) Path() string
- func (s *Store) PutCoverage(rows []CoverageRow) error
- func (s *Store) PutNodeCoverage(rows []NodeCoverageRow) error
- func (s *Store) ReplaceTrace(nodes []TraceNode, edges []TraceEdge, revision string) error
- func (s *Store) RunMaintenance()
- func (s *Store) SchemaVersion() (int, error)
- func (s *Store) SearchAllByFilters(kinds []model.NodeKind, langs []model.Language, limit int) ([]model.SearchResult, error)
- func (s *Store) SearchAllByFiltersAndSymbolFilters(kinds []model.NodeKind, langs []model.Language, limit int, ...) ([]model.SearchResult, error)
- func (s *Store) SearchFTS(text string, kinds []model.NodeKind, langs []model.Language, limit, offset int) ([]model.SearchResult, error)
- func (s *Store) SearchFTSFiltered(text string, kinds []model.NodeKind, langs []model.Language, limit, offset int, ...) ([]model.SearchResult, error)
- func (s *Store) SearchFuzzy(text string, kinds []model.NodeKind, langs []model.Language, limit int, ...) ([]model.SearchResult, error)
- func (s *Store) SearchFuzzyFiltered(text string, kinds []model.NodeKind, langs []model.Language, limit int, ...) ([]model.SearchResult, error)
- func (s *Store) SearchLike(text string, kinds []model.NodeKind, langs []model.Language, limit, offset int) ([]model.SearchResult, error)
- func (s *Store) SearchLikeFiltered(text string, kinds []model.NodeKind, langs []model.Language, limit, offset int, ...) ([]model.SearchResult, error)
- func (s *Store) SetMetadata(key, value string) error
- func (s *Store) Size() (int64, error)
- func (s *Store) Transaction(fn func(tx *sql.Tx) error) error
- func (s *Store) UpsertFile(f model.FileRecord) error
- type SymbolFilters
- type TraceEdge
- type TraceNode
Constants ¶
const CurrentSchemaVersion = 8
CurrentSchemaVersion mirrors CURRENT_SCHEMA_VERSION in the original.
const DatabaseFilename = "codegraph.db"
DatabaseFilename is the on-disk name of the index database.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CoverageRow ¶
type CoverageRow struct {
FilePath string
ContentHash string
Mode string
Ranges string
LinesCovered int
LinesUncovered int
PctCovered float64
RunAt int64
}
CoverageRow is a per-file line-coverage record (the `coverage` table). It is the store's own row type so the store package stays free of any dependency on the coverage package (which itself imports store); the coverage package converts to/from its own coverage.FileCoverage.
Ranges is the RLE JSON string exactly as stored ([[start,end,"hit"|"miss"],…]); the store treats it as an opaque blob.
type GraphStats ¶
type GraphStats struct {
NodeCount int `json:"nodeCount"`
EdgeCount int `json:"edgeCount"`
FileCount int `json:"fileCount"`
NodesByKind map[model.NodeKind]int `json:"nodesByKind"`
EdgesByKind map[model.EdgeKind]int `json:"edgesByKind"`
FilesByLanguage map[model.Language]int `json:"filesByLanguage"`
DBSizeBytes int64 `json:"dbSizeBytes"`
LastUpdated int64 `json:"lastUpdated"`
}
GraphStats summarizes the index, mirroring GraphStats in the original. DBSizeBytes is filled by the caller (Store.Size) like the original.
type NodeCoverageRow ¶
type NodeCoverageRow struct {
NodeID string
ContentHash string
LinesCovered int
LinesUncovered int
PctCovered float64
RunAt int64
}
NodeCoverageRow is a per-function innermost-attributed coverage record (the `node_coverage` table). Store-local row type, see CoverageRow.
type NowFunc ¶
type NowFunc func() int64
NowFunc returns the current time in Unix milliseconds. Injectable for tests.
type Option ¶
type Option func(*Store)
Option configures a Store.
func WithNowFunc ¶
WithNowFunc injects the clock used for updated_at/applied_at timestamps.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is an open codegraph index database.
func Initialize ¶
Initialize creates a new database at path (parent directories included), applies the schema, and records the current schema version.
func (*Store) ClearUnresolvedReferences ¶
ClearUnresolvedReferences deletes all unresolved references.
func (*Store) DeleteEdgesBySource ¶
DeleteEdgesBySource removes all outgoing edges of a node.
func (*Store) DeleteFile ¶
DeleteFile removes a file record and all nodes extracted from it.
func (*Store) DeleteNode ¶
DeleteNode deletes a node by ID (edges cascade via FK).
func (*Store) DeleteNodesByFile ¶
DeleteNodesByFile deletes every node extracted from filePath.
func (*Store) DeleteUnresolvedByNode ¶
DeleteUnresolvedByNode removes references originating from nodeID.
func (*Store) EdgeExists ¶ added in v0.5.0
EdgeExists reports whether this exact persisted relationship survived a replacement. It is used by incremental reindexing to distinguish a stable node ID reinserted after cascading edge deletion from an unchanged edge.
func (*Store) ExactNameCaseInsensitive ¶
func (s *Store) ExactNameCaseInsensitive( term string, kinds []model.NodeKind, langs []model.Language, limit int, ) ([]model.Node, error)
ExactNameCaseInsensitive finds nodes whose name matches term (case-insensitive).
func (*Store) ExactNameCaseInsensitiveFiltered ¶ added in v0.5.0
func (*Store) ExistingEdgeKeys ¶ added in v0.5.0
ExistingEdgeKeys loads persisted edge identities for all sources in one query, avoiding one existence probe per restored incoming edge.
func (*Store) ExistingNodeIDs ¶
ExistingNodeIDs returns the subset of ids that exist in the store.
func (*Store) FindEdgesBetweenNodes ¶
func (s *Store) FindEdgesBetweenNodes(nodeIDs []string, kinds []model.EdgeKind) ([]model.Edge, error)
FindEdgesBetweenNodes returns all edges whose source AND target are both in nodeIDs (uses json_each like the original to stay under param limits).
func (*Store) GetAllCoverage ¶
func (s *Store) GetAllCoverage() ([]CoverageRow, error)
GetAllCoverage returns every per-file coverage row ordered by file path.
func (*Store) GetAllFiles ¶
func (s *Store) GetAllFiles() ([]model.FileRecord, error)
GetAllFiles returns every tracked file ordered by path.
func (*Store) GetAllMetadata ¶
GetAllMetadata returns every metadata key-value pair.
func (*Store) GetAllNodeCoverage ¶
func (s *Store) GetAllNodeCoverage() ([]NodeCoverageRow, error)
GetAllNodeCoverage returns every per-node coverage row ordered by node id.
func (*Store) GetCoverageByFile ¶
func (s *Store) GetCoverageByFile(filePath string) (*CoverageRow, error)
GetCoverageByFile returns the coverage row for a file, or nil if absent.
func (*Store) GetDependencyFilePaths ¶
GetDependencyFilePaths returns file paths of files depended on by filePath via the resolved symbol edge graph (calls/references/etc. cross-file edges).
func (*Store) GetDependentFilePaths ¶
GetDependentFilePaths returns file paths of files that depend on filePath.
func (*Store) GetFileByPath ¶
func (s *Store) GetFileByPath(filePath string) (*model.FileRecord, error)
GetFileByPath returns a file record, or nil if untracked.
func (*Store) GetIncomingEdges ¶
GetIncomingEdges returns edges into targetID, optionally filtered by kinds.
func (*Store) GetIncomingEdgesForTargetFiles ¶ added in v0.5.0
GetIncomingEdgesForTargetFiles loads all incoming edges for a changed-file batch in one joined query. Incremental sync uses this instead of one query per target symbol (and then one per source edge).
func (*Store) GetIncomingEdgesLimited ¶ added in v0.5.0
func (*Store) GetLastIndexedAt ¶
GetLastIndexedAt returns the most recent indexed_at across all files in ms, or 0 when nothing is indexed yet.
func (*Store) GetMetadata ¶
GetMetadata returns a project metadata value, or "" if absent.
func (*Store) GetNodeByID ¶
GetNodeByID fetches one node, or nil if absent.
func (*Store) GetNodesByFile ¶
GetNodesByFile returns all nodes in a file ordered by start line.
func (*Store) GetNodesByIDs ¶
GetNodesByIDs batch-fetches nodes, returned as a map keyed by ID. Missing IDs are simply absent.
func (*Store) GetNodesByLowerName ¶
GetNodesByLowerName returns nodes matching lower(name) = lowerName (uses the idx_nodes_lower_name expression index).
func (*Store) GetNodesByName ¶
GetNodesByName returns all nodes with the exact name.
func (*Store) GetNodesByQualifiedNameExact ¶
GetNodesByQualifiedNameExact returns nodes whose qualified name matches exactly.
func (*Store) GetNodesByQualifiedNameSuffix ¶ added in v0.5.0
GetNodesByQualifiedNameSuffix finds lexical qualified names at the end of a package/module-qualified selector. It lets callers accept both Foo::Bar and package/path.Foo.Bar without broad fuzzy source selection.
func (*Store) GetOutgoingEdges ¶
func (s *Store) GetOutgoingEdges(sourceID string, kinds []model.EdgeKind, provenance string) ([]model.Edge, error)
GetOutgoingEdges returns edges from sourceID, optionally filtered by kinds and provenance.
func (*Store) GetOutgoingEdgesByKindLimited ¶ added in v0.10.0
func (s *Store) GetOutgoingEdgesByKindLimited(sourceID string, kinds []model.EdgeKind, limit int) ([]model.Edge, error)
GetOutgoingEdgesByKindLimited is the bounded equivalent of GetOutgoingEdges for graph traversals. It keeps traversal limits meaningful even for a single high-fan-out source.
func (*Store) GetOutgoingEdgesLimited ¶ added in v0.5.0
GetOutgoingEdgesLimited returns deterministic immediate edges without loading an unbounded adjacency list.
func (*Store) GetStats ¶
func (s *Store) GetStats() (GraphStats, error)
GetStats returns aggregate counts for the whole index.
func (*Store) GetTraceEdgesByTarget ¶ added in v0.3.0
GetTraceEdgesByTarget returns accepted links for a normalized target node.
func (*Store) GetTraceNodes ¶ added in v0.3.0
GetTraceNodes returns the complete projection in stable identity order.
func (*Store) GetUnresolvedByName ¶
func (s *Store) GetUnresolvedByName(name string) ([]model.UnresolvedReference, error)
GetUnresolvedByName returns unresolved references with the given name.
func (*Store) GetUnresolvedReferences ¶
func (s *Store) GetUnresolvedReferences() ([]model.UnresolvedReference, error)
GetUnresolvedReferences returns every unresolved reference.
func (*Store) GetUnresolvedReferencesBatch ¶
func (s *Store) GetUnresolvedReferencesBatch(offset, limit int) ([]model.UnresolvedReference, error)
GetUnresolvedReferencesBatch pages through unresolved references in bounded-memory chunks (LIMIT/OFFSET, rowid order — stable across pages).
func (*Store) GetUnresolvedReferencesByFiles ¶
func (s *Store) GetUnresolvedReferencesByFiles(filePaths []string) ([]model.UnresolvedReference, error)
GetUnresolvedReferencesByFiles returns references recorded in the given files.
func (*Store) GetUnresolvedReferencesCount ¶
GetUnresolvedReferencesCount counts unresolved references without loading them.
func (*Store) InsertEdge ¶
InsertEdge inserts an edge (INSERT OR IGNORE — duplicates are dropped).
func (*Store) InsertEdges ¶
InsertEdges inserts edges in one transaction, silently skipping edges whose endpoints don't exist (mirrors the original's endpoint-existence filter, which protects FK integrity during incremental syncs).
func (*Store) InsertNode ¶
InsertNode inserts or replaces a node. Nodes missing required fields are skipped (mirroring the original's defensive validation).
func (*Store) InsertNodes ¶
InsertNodes inserts nodes in one transaction.
func (*Store) InsertUnresolvedRef ¶
func (s *Store) InsertUnresolvedRef(r model.UnresolvedReference) error
InsertUnresolvedRef records a reference for later resolution.
func (*Store) InsertUnresolvedRefs ¶
func (s *Store) InsertUnresolvedRefs(refs []model.UnresolvedReference) error
InsertUnresolvedRefs inserts references in one transaction.
func (*Store) IterateNodesByKind ¶
IterateNodesByKind streams nodes of a kind to fn, in rowid order.
func (*Store) JournalMode ¶
JournalMode reports the journal mode actually in effect ("wal", "delete", …). SQLite silently keeps the prior mode when WAL can't be enabled (e.g. network mounts), so this is surfaced in status for triage (issue #238).
func (*Store) PutCoverage ¶
func (s *Store) PutCoverage(rows []CoverageRow) error
PutCoverage replaces the per-file coverage rows for the given files in one transaction. Each row's file_path overwrites any prior record for that file.
func (*Store) PutNodeCoverage ¶
func (s *Store) PutNodeCoverage(rows []NodeCoverageRow) error
PutNodeCoverage replaces the per-node coverage rows in one transaction. Rows whose node_id is absent from `nodes` are skipped (the FK would otherwise reject them); callers attribute only to nodes that exist.
func (*Store) ReplaceTrace ¶ added in v0.3.0
ReplaceTrace atomically replaces the complete trace projection and records the exact source revision from which it was built.
func (*Store) RunMaintenance ¶
func (s *Store) RunMaintenance()
RunMaintenance performs lightweight post-bulk-write maintenance (PRAGMA optimize + passive WAL checkpoint). Best-effort: errors ignored.
func (*Store) SchemaVersion ¶
SchemaVersion returns the highest applied schema version (0 if none).
func (*Store) SearchAllByFilters ¶
func (s *Store) SearchAllByFilters( kinds []model.NodeKind, langs []model.Language, limit int, ) ([]model.SearchResult, error)
SearchAllByFilters returns up to limit nodes matching kind/lang filters with a uniform score of 1. Used when no text is given.
func (*Store) SearchAllByFiltersAndSymbolFilters ¶ added in v0.5.0
func (s *Store) SearchAllByFiltersAndSymbolFilters(kinds []model.NodeKind, langs []model.Language, limit int, filters SymbolFilters) ([]model.SearchResult, error)
func (*Store) SearchFTS ¶
func (s *Store) SearchFTS( text string, kinds []model.NodeKind, langs []model.Language, limit, offset int, ) ([]model.SearchResult, error)
SearchFTS runs an FTS5 prefix-match query against nodes_fts and returns (node, raw-bm25-score) pairs. The BM25 column weights mirror the original: id=0, name=20, qualified_name=5, docstring=1, signature=2. Returns up to limit*5 rows (over-fetch for post-hoc rescoring). Returns nil on FTS parse error (mirrors the original's try-catch → []).
func (*Store) SearchFTSFiltered ¶ added in v0.5.0
func (*Store) SearchFuzzy ¶
func (s *Store) SearchFuzzy( text string, kinds []model.NodeKind, langs []model.Language, limit int, editDistFn func(a, b string, max int) int, ) ([]model.SearchResult, error)
SearchFuzzy runs an edit-distance sweep over all distinct symbol names. Only fires when text length ≥ 3.
func (*Store) SearchFuzzyFiltered ¶ added in v0.5.0
func (*Store) SearchLike ¶
func (s *Store) SearchLike( text string, kinds []model.NodeKind, langs []model.Language, limit, offset int, ) ([]model.SearchResult, error)
SearchLike runs a LIKE-based substring search (fallback when FTS returns nothing).
func (*Store) SearchLikeFiltered ¶ added in v0.5.0
func (*Store) SetMetadata ¶
SetMetadata upserts a project metadata key-value pair.
func (*Store) Transaction ¶
Transaction runs fn inside a single SQLite transaction.
func (*Store) UpsertFile ¶
func (s *Store) UpsertFile(f model.FileRecord) error
UpsertFile inserts or updates a file record.
type SymbolFilters ¶ added in v0.5.0
SymbolFilters constrains symbol searches before SQLite applies a result limit. Each non-empty group is ORed case-insensitively.
type TraceEdge ¶ added in v0.3.0
type TraceEdge struct {
SourceID string
TargetID string
Relation string
Accepted bool
SourcePath string
SourceLine int
SourceColumn int
TargetReference string
}
TraceEdge is an accepted or rejected typed source directive. Rejected edges remain indexed for deterministic diagnostics but are excluded from queries.
type TraceNode ¶ added in v0.3.0
type TraceNode struct {
ID string
Kind string
Reference string
Title string
Path string
StartLine int
StartColumn int
EndLine int
EndColumn int
Status string
}
TraceNode is a normalized SpecScore node or an attached code symbol. The trace projection has its own node identity because links cross graph scopes.