Skip to main content

Store

Struct Store 

Source
pub struct Store {
    pub conn: Connection,
    pub root: PathBuf,
    pub repo_id: String,
    pub repo_name: String,
    /* private fields */
}

Fields§

§conn: Connection§root: PathBuf§repo_id: String

Repository id (repo:// id component).

§repo_name: String

Implementations§

Source§

impl Store

Source

pub fn record_revision( &self, source_hash: &str, extractor_version: &str, file_count: u64, semantic_config_hash: &str, graph_content_hash: &str, ) -> Result<GraphRevision, StoreError>

Record the current graph as a new revision, transactionally: revision row + full member row sets commit atomically, so a crash never leaves a revision with half its members.

Source

pub fn revisions(&self) -> Result<Vec<GraphRevision>, StoreError>

All recorded revisions, oldest first.

Source

pub fn prune_revisions(&self, keep: usize) -> Result<usize, StoreError>

Delete revisions below MAX(rev) - keep from revision_members

  • graph_revisions (issue #16).

Watch-mode repos append one full row-set per index, so the DB grows without bound. Called at record time with the configured history.max_revisions. Returns the number of revisions deleted. Never deletes the head revision itself: a keep of 0 still retains the newest row-set, so history/diff stay consistent.

Source

pub fn reclaim_freelist(&self) -> Result<usize, StoreError>

Release freelist pages back to the OS when fragmentation is materially large (C3). Bounded work per call (10k pages ≈ 40MB at 4K pages); returns pages freed.

Source

pub fn revision_members( &self, rev: i64, ) -> Result<(Vec<Entity>, Vec<Relationship>), StoreError>

Member id sets at a revision: the representative historical view. Rows are the recorded JSON; ids absent from the live graph decode as tombstones (present historically, gone now).

Source

pub fn revision_rows( &self, rev: i64, ) -> Result<(BTreeMap<String, String>, BTreeMap<String, String>), StoreError>

Raw recorded rows at a revision: id -> row JSON, the content half of the V2 diff. Rows decode losslessly (see Store::revision_members); comparing JSON here avoids re-serialization drift.

Source

pub fn semantic_diff( &self, from: i64, to: i64, ) -> Result<SemanticDelta, StoreError>

Introduction/removal/modification history between two revisions. Same id in both revisions with different row JSON (attributes, confidence, provenance, evidence) reports as modified — the V1 set-membership blind spot.

Source§

impl Store

Source

pub fn graph_content_hash(&self) -> Result<String, StoreError>

Content hash of the live graph rows (raw entity + relationship columns, fed incrementally in deterministic query order): the content-identity half of revision dedup. An extractor, confidence, or provenance change advances the revision even when no source file moved. Raw columns, not re-serialized structs: the old code parsed every row’s JSON and re-serialized it (parse + reserialize of 26k rows per record) only to hash the bytes. Same contract — opaque equality vs the head — at read cost only. NOTE: the digest value changes once vs pre-0.2.6 binaries (one extra revision on first record after upgrade, then dedup resumes).

Source

pub fn record_current_revision(&self) -> Result<GraphRevision, StoreError>

Record the current graph, skipping fully-identical runs: when source inventory, extractor, semantic config, AND graph content all match the head revision, that revision is returned instead of appending a duplicate. Any axis changing advances the history.

Source

pub fn record_current_revision_with_config( &self, semantic_config_hash: &str, ) -> Result<GraphRevision, StoreError>

[record_current_revision] with the caller’s semantic-config hash (language backends, resolver switches — the indexer hashes its semantic-relevant config). Empty means “no config axis”.

Source§

impl Store

Source

pub fn save_snapshot( &self, save: SnapshotSave<'_>, ) -> Result<ContextSnapshot, StoreError>

Persist a rendered artifact as a durable checkpoint. Idempotent: same (task, epoch) resolves to the same id and replaces it.

Source

pub fn load_snapshot( &self, id: &str, ) -> Result<Option<ContextSnapshot>, StoreError>

Load a snapshot by id. Survives later model changes: the row is never mutated by indexing, only replaced by an explicit re-save.

Source

pub fn diff_snapshot( &self, id: &str, ) -> Result<Option<SnapshotDiff>, StoreError>

Diff a snapshot against the current graph: presence AND content. A surviving id with a changed row is modified, not still_valid. Relationships touching the visible set, contract/state entities, flow names, and the artifact hash are compared too. Newly-relevant knowledge needs a re-render (resume), which this diff does not invent.

Source§

impl Store

Source

pub fn open_recovering( path: &Path, root: &Path, ) -> Result<(Store, Option<PathBuf>)>

Open (creating if needed) the SCC database at path for repository rooted at root. root must exist. A truncated or garbage existing file is refused rather than migrated into a fake empty index. Open, quarantining a corrupt database aside and starting fresh. ONLY for the index write path: a malformed file is renamed to <name>.corrupt-<epoch> (evidence preserved, WAL sidecars moved with it) and indexing rebuilds from the working tree. Readers keep using Store::open and fail loudly — a freshly rebuilt index is temporarily incomplete and must never be silently presented as truth on a read path. Returns the quarantine path when recovery ran.

Source

pub fn quarantine_db(path: &Path) -> Result<PathBuf>

Move a corrupt database (plus WAL sidecars) aside as <name>.db.corrupt-<epoch>. Evidence preserved; the path is free for a fresh rebuild.

Source

pub fn is_corruption(e: &StoreError) -> bool

True for corruption (as opposed to e.g. missing files or permission errors): the explicit Corrupt refusal plus SQLite’s own malformed / not-a-database errors, which surface lazily on first query despite a valid-looking header.

Source

pub fn batch_begin(&self) -> Result<()>

Begin a write batch: the outermost begin issues BEGIN IMMEDIATE, nested begins are depth-counted no-ops. Pair with Store::batch_end (commit at depth zero) or Store::batch_abort (full rollback). Lets one commit cover a whole file’s facts instead of one fsync per row — the dominant index-time cost on fsync-bound disks.

Source

pub fn batch_end(&self) -> Result<()>

Source

pub fn batch_abort(&self)

Source

pub fn batch_write<T, E>( &self, f: impl FnOnce() -> Result<T, E>, ) -> Result<T, E>
where E: From<StoreError>,

Run f inside a batch: commit on success, full rollback on error. Per-file callers use this so a failed file leaves no partial facts.

Source

pub fn open(path: &Path, root: &Path) -> Result<Store>

Source

pub fn adopt_stable_identity( &mut self, explicit: Option<&str>, remote_url: Option<&str>, ) -> Result<bool>

Adopt a stable identity derived from explicit config or the git remote. Only applies to a fresh database (no entities yet): once entity ids are written under an id, that id is load-bearing and must survive via the persistent rule in Store::open instead. Returns true when the identity changed.

Source

pub fn repository(&self) -> Repository

Source

pub fn plugin_state_put( &self, plugin_id: &str, key: &str, value: &str, ) -> Result<()>

Source

pub fn plugin_state_get( &self, plugin_id: &str, key: &str, ) -> Result<Option<String>>

Source

pub fn sidecar_put( &self, plugin_id: &str, graph: &str, key: &str, value: &str, ) -> Result<()>

Source

pub fn sidecar_get( &self, plugin_id: &str, graph: &str, key: &str, ) -> Result<Option<String>>

Source

pub fn sidecar_scan( &self, plugin_id: &str, graph: &str, prefix: &str, limit: usize, ) -> Result<Vec<(String, String)>>

Source

pub fn plugin_state_delete(&self, plugin_id: &str, key: &str) -> Result<()>

Source

pub fn plugin_state_scan( &self, plugin_id: &str, prefix: &str, limit: usize, ) -> Result<Vec<(String, String)>>

Source

pub fn meta_set(&self, key: &str, value: &str) -> Result<()>

Source

pub fn meta_get(&self, key: &str) -> Result<Option<String>>

Source

pub fn bump_epoch(&self, kind: ModelEpochKind) -> Result<()>

Bump one model-epoch generation. Called by every mutation path that changes system truth (index completion, LSP promotion, adapter import, intent load, runtime ingestion, derived recompilation).

Source

pub fn model_epoch(&self) -> Result<ModelEpoch>

Current model epoch (all generations plus the latest snapshot revision). Never cached by the caller: it must reflect every change immediately.

Source

pub fn begin_snapshot( &self, revision: &str, branch: Option<&str>, ) -> Result<i64>

Source

pub fn finish_snapshot(&self, id: i64, file_count: usize) -> Result<()>

Source

pub fn latest_snapshot(&self) -> Result<Option<Snapshot>>

Source

pub fn snapshot_status(&self) -> Result<Option<(Snapshot, i64)>>

Source

pub fn upsert_file( &self, path: &str, hash: &str, language: &str, kind: &str, size: u64, ) -> Result<()>

Source

pub fn file(&self, path: &str) -> Result<Option<(String, String, String, u64)>>

Source

pub fn all_files(&self) -> Result<Vec<(String, String, String, String, u64)>>

Source

pub fn delete_file(&self, path: &str) -> Result<()>

Source

pub fn purge_path(&self, path: &str) -> Result<()>

Remove everything tied to a source path: symbols, evidence, relationships derived from it, and symbol-level entities.

SCHEMA/REACTIVE concept entities are NOT deleted by path: concepts are keyed by (kind, name) and may occur in many files. Their OCCURRENCE entities (per concept/path/owner/line) are deleted by path, the concept’s sources provenance is recomputed from the surviving occurrences, and a concept with zero remaining occurrences is deleted entirely (with its edges) — so purging one file never deletes a schema another file still uses, and the derived occurrence count naturally reflects the survivors.

Source

pub fn paths_depending_on(&self, path: &str) -> Result<Vec<String>>

Files that import this path or CALL one of its symbols. Used to re-extract hash-unchanged dependents so incremental ≡ cold after type-narrowed CALLS are written on the caller.

Source

pub fn purge_all(&self) -> Result<()>

Remove all indexed facts (used by full reindex).

Source

pub fn insert_symbol( &self, file: &str, name: &str, kind: &str, signature: Option<&str>, start_line: u32, end_line: u32, exported: bool, docstring: Option<&str>, ) -> Result<i64>

Source

pub fn symbols_in_file( &self, file: &str, ) -> Result<Vec<(i64, String, String, Option<String>, u32, u32, bool, Option<String>)>>

Source

pub fn symbols_named(&self, name: &str) -> Result<Vec<(String, String, String)>>

Source

pub fn insert_imports( &self, file: &str, imports: &[(String, Vec<(String, String)>, u32, String)], ) -> Result<()>

Source

pub fn imports_in_file( &self, file: &str, ) -> Result<Vec<(String, Vec<(String, String)>, u32, String)>>

Source

pub fn all_imports( &self, ) -> Result<Vec<(String, String, Vec<(String, String)>, u32, String)>>

Source

pub fn insert_entity(&self, entity: &Entity, sources: &[String]) -> Result<()>

Source

pub fn get_entity(&self, id: &str) -> Result<Option<Entity>>

Source

pub fn entity_sources(&self, id: &str) -> Result<Vec<String>>

The sources provenance list of an entity — the repository-relative file paths that produced it. Stored separately from Entity (which carries no sources field), so this is the only reader.

Source

pub fn concept_occurrences(&self, concept_id: &str) -> Result<Vec<Entity>>

Live OCCURRENCE entities attached to a concept (OCCURS edges), sorted by id. Concept counts and sources provenance are always derived from these — never from a stored, write-time-mutated counter.

Source

pub fn entities_by_kind(&self, kind: &str) -> Result<Vec<Entity>>

Source

pub fn all_entities(&self) -> Result<Vec<Entity>>

Source

pub fn delete_entity(&self, id: &str) -> Result<()>

Source

pub fn delete_entities(&self, ids: &[String]) -> Result<()>

Source

pub fn insert_relationship( &self, rel: &Relationship, source_path: &str, ) -> Result<()>

Source

pub fn relationships_for(&self, subject: &str) -> Result<Vec<Relationship>>

Source

pub fn relationships_to(&self, object: &str) -> Result<Vec<Relationship>>

Source

pub fn relationships_between( &self, subject: &str, predicate: &str, object: &str, ) -> Result<Vec<Relationship>>

Source

pub fn all_relationships(&self) -> Result<Vec<Relationship>>

Source

pub fn relationship_ids_with_source( &self, path: &str, predicate: &str, ) -> Result<Vec<String>>

Relationship ids with the given source path and predicate.

Source

pub fn count_relationships(&self) -> Result<u64>

Source

pub fn delete_relationship(&self, id: &str) -> Result<()>

Source

pub fn insert_evidence(&self, ev: &Evidence) -> Result<()>

Source

pub fn get_evidence(&self, id: &str) -> Result<Option<Evidence>>

Source

pub fn all_evidence(&self) -> Result<Vec<Evidence>>

Source

pub fn evidence_for_path(&self, path: &str) -> Result<Vec<Evidence>>

Source

pub fn replace_components(&self, components: &[Entity]) -> Result<()>

Source

pub fn components(&self) -> Result<Vec<Entity>>

Source

pub fn replace_flow_graphs(&self, graphs: &[FlowGraph]) -> Result<()>

Source

pub fn flow_graphs(&self) -> Result<Vec<FlowGraph>>

Source

pub fn replace_flows(&self, flows: &[Flow]) -> Result<()>

Source

pub fn flows(&self) -> Result<Vec<Flow>>

Source

pub fn flow(&self, id: &str) -> Result<Option<Flow>>

Source

pub fn replace_invariants(&self, invariants: &[Invariant]) -> Result<()>

Source

pub fn invariants(&self) -> Result<Vec<Invariant>>

Source

pub fn insert_test( &self, id: &str, name: &str, file: &str, kind: &str, symbol: Option<&str>, ) -> Result<()>

Source

pub fn tests( &self, ) -> Result<Vec<(String, String, String, String, Option<String>)>>

Source

pub fn sweep_orphan_evidence(&self) -> Result<u64>

Delete evidence records no longer referenced by any entity, relationship, component, invariant, flow step, or flow-graph node/ edge. Run after the derived layer (components/flows) rebuilds, because derived edges may briefly hold references during recompilation.

Source

pub fn cache_epoch(&self) -> Result<String>

Canonical epoch string for cache keys: composite of every model generation plus the latest snapshot revision. A previously fresh pack can never be served after any source of system truth changed.

Source

pub fn cache_get(&self, key: &str, epoch: &str) -> Result<Option<String>>

Source

pub fn cache_put(&self, key: &str, pack: &str, epoch: &str) -> Result<()>

Source

pub fn cache_clear(&self) -> Result<()>

Source

pub fn replace_intent_claims(&self, claims: &[(String, Value)]) -> Result<()>

Source

pub fn intent_claims(&self) -> Result<Vec<(String, Value)>>

Source

pub fn runtime_edge_rows(&self) -> Result<Vec<RuntimeEdgeRow>>

Source

pub fn upsert_trace_signature( &self, signature: &str, latency_ms: f64, errors: u64, ) -> Result<()>

Record one occurrence of an observed trace-path signature. count increments by one (one trace occurrence), latency_ms is merged as a count-weighted running average, errors is additive. Does NOT bump any model-epoch generation: ingestion callers bump the Runtime generation once per payload.

Source

pub fn trace_signatures(&self) -> Result<Vec<(String, u64, f64, u64, String)>>

All observed trace signatures, ordered by (count DESC, signature).

Source

pub fn put_embedding( &self, entity_id: &str, vector: &[f32], model: &str, ) -> Result<()>

Source

pub fn get_embedding( &self, entity_id: &str, ) -> Result<Option<(Vec<f32>, String)>>

Source

pub fn embedding_count(&self) -> Result<u64>

Source

pub fn add_drift_finding( &self, kind: &str, severity: &str, message: &str, ) -> Result<i64>

Source

pub fn drift_findings( &self, unresolved_only: bool, ) -> Result<Vec<(i64, String, String, String, String)>>

Source

pub fn clear_drift_findings(&self) -> Result<()>

Source

pub fn search_entities(&self, query: &str, limit: usize) -> Result<Vec<Entity>>

Lexical search over entities (components, routes, data, stores…).

Source

pub fn search_symbols( &self, query: &str, limit: usize, ) -> Result<Vec<(String, String, String, String, u32)>>

Lexical search over symbols.

Source

pub fn search_entities_like( &self, term: &str, limit: usize, ) -> Result<Vec<Entity>>

Substring fallback over entity names AND attributes (docstrings, signatures, responsibilities) — case-insensitive. Used when FTS prefix matching misses morphological variants or multi-term AND queries drop otherwise-strong matches.

Source

pub fn search_entities_like_kind( &self, kind: &str, term: &str, limit: usize, ) -> Result<Vec<Entity>>

Kind-scoped substring start-set for traversal (§16): entities of kind whose name matches term (empty term = all of the kind, capped by limit). LIKE keeps this dependency-free (no FTS).

Source

pub fn search_symbols_like( &self, term: &str, limit: usize, ) -> Result<Vec<(String, String, String, String, u32)>>

Substring fallback over symbols (name, signature, docstring).

Source

pub fn stats(&self) -> Result<HashMap<String, u64>>

Trait Implementations§

Source§

impl Debug for Store

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Store

§

impl !RefUnwindSafe for Store

§

impl !Sync for Store

§

impl !UnwindSafe for Store

§

impl Send for Store

§

impl Unpin for Store

§

impl UnsafeUnpin for Store

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.