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
- 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) ExactNameCaseInsensitive(term string, kinds []model.NodeKind, langs []model.Language, limit int) ([]model.Node, 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) 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) GetOutgoingEdges(sourceID string, kinds []model.EdgeKind, provenance string) ([]model.Edge, error)
- func (s *Store) GetStats() (GraphStats, 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) 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) SearchFTS(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) SearchLike(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
Constants ¶
const CurrentSchemaVersion = 7
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 ¶
This section is empty.
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) 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) 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) 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) 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) GetStats ¶
func (s *Store) GetStats() (GraphStats, error)
GetStats returns aggregate counts for the whole index.
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) 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) 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) 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) 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) 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.