Skip to main content

SessionStore

Struct SessionStore 

Source
pub struct SessionStore { /* private fields */ }
Expand description

SQLite-backed persistent session and cache store with FTS5 full-text search.

Stores sessions, cache entries, compression logs, and known files in a single SQLite database. Uses WAL mode for concurrent read access.

use sqz_engine::SessionStore;
use std::path::Path;

let store = SessionStore::open_or_create(Path::new("~/.sqz/sessions.db")).unwrap();
let results = store.search("authentication refactor").unwrap();
for session in &results {
    println!("{}: {}", session.id, session.compressed_summary);
}

Implementations§

Source§

impl SessionStore

Source

pub fn open(path: &Path) -> Result<Self>

Open an existing database at path. Returns an error if the file does not exist or cannot be opened.

Source

pub fn open_or_create(path: &Path) -> Result<Self>

Open the database at path, creating it if it does not exist. If the database is corrupted, a fresh database is created at the same path and a warning is logged to stderr.

Source

pub fn save_session(&self, session: &SessionState) -> Result<SessionId>

Persist a session. Returns the session id.

Source

pub fn load_session(&self, id: SessionId) -> Result<SessionState>

Load a session by id.

Source

pub fn search(&self, query: &str) -> Result<Vec<SessionSummary>>

Full-text search using FTS5 (porter stemmer, ASCII tokenizer).

Source

pub fn search_by_date( &self, from: DateTime<Utc>, to: DateTime<Utc>, ) -> Result<Vec<SessionSummary>>

Query sessions whose updated_at falls within [from, to].

Source

pub fn latest_session(&self) -> Result<Option<SessionSummary>>

Return the most recently updated session, or None if no sessions exist.

Source

pub fn search_by_project(&self, dir: &Path) -> Result<Vec<SessionSummary>>

Query sessions whose project_dir matches dir exactly.

Source

pub fn save_cache_entry( &self, hash: &str, compressed: &CompressedContent, ) -> Result<()>

Persist a cache entry keyed by content hash.

Stores both the compressed JSON (data) used for dedup-hit responses AND the raw uncompressed bytes (original) so that sqz expand <prefix> can serve truly uncompressed content. See [save_cache_entry_with_original] for the original-aware version; this convenience wrapper exists for callers that do not (yet) have the pre-compression bytes handy. Rows written through this path leave original as NULL, and expand will degrade to returning the compressed blob with a note.

Source

pub fn save_cache_entry_with_original( &self, hash: &str, compressed: &CompressedContent, original: Option<&[u8]>, ) -> Result<()>

Persist a cache entry with both compressed and original content.

original must be the exact bytes that produced compressed, so that expand is a true inverse of dedup. We store the raw bytes (not the UTF-8 string) because command output may include non-UTF-8 sequences — storing the text would lose them.

Source

pub fn get_cache_entry_original(&self, hash: &str) -> Result<Option<Vec<u8>>>

Retrieve the stored original bytes for a cached hash, if the caller populated them via save_cache_entry_with_original.

Returns Ok(None) for missing entries AND for entries that were saved by an older call site that did not pass original. The caller should fall back to the compressed blob in the latter case and surface a note to the user so they know this specific entry wasn’t round-trippable.

Source

pub fn delete_cache_entry(&self, hash: &str) -> Result<()>

Delete a cache entry by content hash.

Source

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

Return all cache entries ordered by accessed_at ASC (oldest first), as (hash, size_bytes) pairs where size_bytes is the byte length of the stored JSON data.

Source

pub fn get_cache_entry(&self, hash: &str) -> Result<Option<CompressedContent>>

Retrieve a cache entry by content hash, updating accessed_at.

Source

pub fn get_cache_entry_by_prefix( &self, prefix: &str, ) -> Result<Option<(String, CompressedContent)>>

Look up a cache entry by a prefix of the content hash.

The inline dedup refs we hand to the LLM carry only the first 16 hex chars of the SHA-256 (§ref:<16-hex>§), so when an agent runs sqz expand <prefix> we need to resolve those 16 chars back to the full 64-char key. Uses LIKE 'prefix%' with an index-friendly anchored pattern so the query stays O(log n) on the primary key.

Returns Ok(Some((full_hash, entry))) on unique match. Returns Ok(None) if no entries match. Returns Err(_) if the prefix is ambiguous (2+ matches) — the caller should tell the user to use a longer prefix. 16-hex collisions are astronomically unlikely (one in 2^64) but we refuse to guess rather than quietly serve a surprise file.

The prefix is validated as lowercase hex. Non-hex input returns None without touching the database — this is how we handle the common user-error case of pasting the ref with the § markers still attached (they get rejected before we query SQLite).

Source

pub fn get_cache_entry_accessed_at( &self, hash: &str, ) -> Result<Option<DateTime<Utc>>>

Read the accessed_at timestamp for a cached hash without updating it. Returns None if the hash is not cached.

Used by the dedup freshness check: if accessed_at is recent, the LLM likely still has the original content in its context window, so returning a ref is safe. If it’s old, re-send the full content.

Source

pub fn cache_entry_exists(&self, hash: &str) -> Result<bool>

Check if a cache entry exists without updating accessed_at.

Source

pub fn touch_cache_entry(&self, hash: &str) -> Result<()>

Update accessed_at for a cached hash to the current time. Called by the cache manager when a ref is served so the next staleness check sees the recent send.

Source

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

Set a metadata key/value. Persists across sqz process boundaries (each shell-hook invocation is a short-lived process).

Source

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

Get a metadata value. Returns None if the key has never been set.

Source

pub fn log_compression( &self, tokens_original: u32, tokens_compressed: u32, stages: &[String], mode: &str, ) -> Result<()>

Log a compression event for cumulative stats tracking.

Source

pub fn compression_stats(&self) -> Result<CompressionStats>

Get cumulative compression stats from the log.

Source

pub fn daily_gains(&self, days: u32) -> Result<Vec<DailyGain>>

Get daily compression gains for the last N days.

Source

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

Record a file path as “known” (its content is in the dedup cache). Used by cross-command context refs to annotate error messages.

Source

pub fn known_files(&self) -> Result<Vec<String>>

Load all known file paths from the persistent store.

Source

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

Clear all known files (e.g. on session reset).

Auto Trait Implementations§

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<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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.