pub struct DocumentStore { /* private fields */ }Expand description
The top-level embedded document store.
Holds a collection of parsed Markdown documents and provides access to the query interface. Documents are stored in memory with their flattened block lists and interval indexes.
§Load modes
DocumentStore::new/DocumentStore::add_str— in-memory, blocks immediately availableDocumentStore::load— reads all blocks from a.mq-dbfile into memoryDocumentStore::open— reads catalog only; blocks loaded on demand viaload_all_blocks
Secondary indexes (DocumentIndex) are built once via
load_all_indexes and cached, so
subsequent crate::SqlEngine construction is O(1).
§Example
use mq_db::DocumentStore;
let mut store = DocumentStore::new();
store.add_str("# Hello\n\nWorld").unwrap();
let results = store.query().heading_depth(1).blocks();
assert_eq!(results.len(), 1);
assert_eq!(results[0].content, "Hello");Implementations§
Source§impl DocumentStore
impl DocumentStore
Sourcepub fn execute_sql_mut(&mut self, sql: &str) -> Result<QueryOutput, MqdbError>
pub fn execute_sql_mut(&mut self, sql: &str) -> Result<QueryOutput, MqdbError>
Execute a SQL statement that may mutate the store.
UPDATE/DELETE against the blocks table are handled directly —
see the module-level write-back notes above — and are written back
to the affected document’s source Markdown file (re-parsed in
place, same DocumentId). Everything else (SELECT, CREATE TABLE, INSERT, DROP TABLE, DESC, SHOW TABLES) delegates to
the regular read-only SqlEngine::execute.
Callers that expose this over an interface an end user might not expect to mutate files (a CLI, an HTTP/MCP endpoint) should gate it behind an explicit opt-in before calling this — write-back mutates the user’s Markdown source on disk.
Source§impl DocumentStore
impl DocumentStore
Sourcepub fn set_store_spans(&mut self, val: bool)
pub fn set_store_spans(&mut self, val: bool)
When set to false, source line/column spans are stripped from every
block added after this call. Reduces memory by ~21 bytes per block.
Sourcepub fn register_table(
&mut self,
name: impl Into<String>,
columns: Vec<String>,
rows: Vec<Vec<String>>,
)
pub fn register_table( &mut self, name: impl Into<String>, columns: Vec<String>, rows: Vec<Vec<String>>, )
Register a custom virtual table that can be queried via SQL.
The table is queryable with SELECT … FROM <name>. All column values
are treated as strings; cast them in SQL as needed.
Calling this a second time with the same name replaces the previous table.
Sourcepub fn unregister_table(&mut self, name: &str) -> bool
pub fn unregister_table(&mut self, name: &str) -> bool
Remove a previously registered custom table. Returns true if it existed.
Sourcepub fn attach(&self, alias: DatabaseAlias, path: &Path) -> Result<(), MqdbError>
pub fn attach(&self, alias: DatabaseAlias, path: &Path) -> Result<(), MqdbError>
Attach another .mq-db store under alias, queryable as
<alias>.<table>. Session-scoped; not persisted.
Sourcepub fn detach(&self, alias: &str) -> bool
pub fn detach(&self, alias: &str) -> bool
Detach a previously attached store. Returns true if alias was
attached, false otherwise.
Sourcepub fn add_file(
&mut self,
path: impl AsRef<Path>,
) -> Result<DocumentId, MqdbError>
pub fn add_file( &mut self, path: impl AsRef<Path>, ) -> Result<DocumentId, MqdbError>
Parses and adds a Markdown file from disk.
Returns the assigned DocumentId on success.
Sourcepub fn add_str(&mut self, content: &str) -> Result<DocumentId, MqdbError>
pub fn add_str(&mut self, content: &str) -> Result<DocumentId, MqdbError>
Parses and adds Markdown content from a string.
Returns the assigned DocumentId on success.
Sourcepub fn add_str_with_path(
&mut self,
content: &str,
path: Option<PathBuf>,
) -> Result<DocumentId, MqdbError>
pub fn add_str_with_path( &mut self, content: &str, path: Option<PathBuf>, ) -> Result<DocumentId, MqdbError>
Parses and adds already-read Markdown content, attributing it to
path. For callers that read files concurrently and want to skip
add_file’s own read.
Sourcepub fn append_str(&mut self, content: &str) -> Result<DocumentId, MqdbError>
pub fn append_str(&mut self, content: &str) -> Result<DocumentId, MqdbError>
Append a Markdown string to the existing .mq-db file (in-place).
Works only when the store was opened via DocumentStore::open (i.e.
self.storage is Some). New block pages and an index page chain are
appended to the file and the catalog is rewritten to include the new
entry.
When called on an in-memory store (no backing file) this behaves
identically to add_str.
Sourcepub fn append_file(
&mut self,
path: impl AsRef<Path>,
) -> Result<DocumentId, MqdbError>
pub fn append_file( &mut self, path: impl AsRef<Path>, ) -> Result<DocumentId, MqdbError>
Append a Markdown file to the existing .mq-db file (in-place).
See append_str for full semantics.
Sourcepub fn replace_document(
&mut self,
doc_id: DocumentId,
content: &str,
path: Option<PathBuf>,
) -> Result<(), MqdbError>
pub fn replace_document( &mut self, doc_id: DocumentId, content: &str, path: Option<PathBuf>, ) -> Result<(), MqdbError>
Replace the content of an existing document in place, keeping its
DocumentId stable (so any external references to it — e.g. mq()
join columns, application code holding the id — stay valid).
Re-parses content, writes fresh block/index page chains to the
backing storage file (if one is open) and overwrites that document’s
catalog entry; the old page chains become orphaned dead space (no
compaction yet — a future vacuum command could reclaim them).
For in-memory-only stores (no backing file open), this only updates
in-memory state — call save afterward to
persist.
Returns an error if no document with doc_id exists.
Sourcepub fn reindex_paths(
&mut self,
files: &[PathBuf],
prune: bool,
) -> Result<ReindexReport, MqdbError>
pub fn reindex_paths( &mut self, files: &[PathBuf], prune: bool, ) -> Result<ReindexReport, MqdbError>
Index files, skipping any whose content hash matches what’s already
catalogued (see content_hashes), replacing changed ones in place via
replace_document (same
DocumentId), and adding new ones exactly like
append_file/add_file
depending on whether a backing file is open.
When prune is true, any catalogued document whose path is not
present in files is dropped from the store.
Documents with no path (added via add_str) are left untouched and
are never counted as “removed” by prune.
Sourcepub fn get_document(&self, id: DocumentId) -> Option<&Document>
pub fn get_document(&self, id: DocumentId) -> Option<&Document>
Looks up a document by its DocumentId.
Sourcepub fn stats(&self) -> StoreStats
pub fn stats(&self) -> StoreStats
Aggregate block-type / code-language statistics across every document currently loaded in memory.
Sourcepub fn load_all_blocks(&mut self) -> Result<(), MqdbError>
pub fn load_all_blocks(&mut self) -> Result<(), MqdbError>
Load blocks for every document that has not yet been loaded.
No-op when the store was built in memory or fully loaded via load().
Sourcepub fn load_all_indexes(&mut self) -> Result<(), MqdbError>
pub fn load_all_indexes(&mut self) -> Result<(), MqdbError>
Build or load persisted secondary indexes for every document and cache them.
Must be called after load_all_blocks.
Subsequent crate::SqlEngine construction reuses the cache and pays no
per-block index rebuild cost.
Sourcepub fn save(&self, path: impl AsRef<Path>) -> Result<(), MqdbError>
pub fn save(&self, path: impl AsRef<Path>) -> Result<(), MqdbError>
Persist all in-memory documents to a .mq-db file, including secondary
indexes. Writes atomically: writes to path.tmp then renames to path.
Sourcepub fn vacuum(
&mut self,
path: impl AsRef<Path>,
) -> Result<VacuumReport, MqdbError>
pub fn vacuum( &mut self, path: impl AsRef<Path>, ) -> Result<VacuumReport, MqdbError>
Rewrites the backing .mq-db file at path from scratch (same
compaction save already does), reclaiming dead page
chains left behind by replace_document,
DROP TABLE/DROP VIEW, and re-indexing changed files. Requires a
store opened via open (a live backing file).
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self, MqdbError>
pub fn open(path: impl AsRef<Path>) -> Result<Self, MqdbError>
Open a .mq-db file in lazy mode: reads only catalog and zone maps.
Block data is not loaded until you call
load_all_blocks. Secondary indexes
are not built until you call
load_all_indexes.
Sourcepub fn load(path: impl AsRef<Path>) -> Result<Self, MqdbError>
pub fn load(path: impl AsRef<Path>) -> Result<Self, MqdbError>
Load a .mq-db file and reconstruct the in-memory DocumentStore.
All block data is read from disk. Secondary indexes are not built
here — crate::SqlEngine builds them lazily on construction.
Sourcepub fn load_catalog_only(path: impl AsRef<Path>) -> Result<Self, MqdbError>
pub fn load_catalog_only(path: impl AsRef<Path>) -> Result<Self, MqdbError>
Load only the catalog metadata from a .mq-db file — no block data.
Documents have block_count populated from the catalog but blocks
is empty. Useful for commands that only need zone-map metadata (e.g.
list), avoiding the cost of deserialising all block data.
Sourcepub fn file_version(path: impl AsRef<Path>) -> Result<u32, MqdbError>
pub fn file_version(path: impl AsRef<Path>) -> Result<u32, MqdbError>
The on-disk file-format version at path, without loading the
catalog. Use this to decide whether DocumentStore::migrate is
needed before calling DocumentStore::open.
Sourcepub fn migrate(path: impl AsRef<Path>) -> Result<u32, MqdbError>
pub fn migrate(path: impl AsRef<Path>) -> Result<u32, MqdbError>
Rewrites a store written by an older but still-recognised file
format (see storage::page) in the current format, rebuilding every
document’s secondary index (including any index sections added since
that version) from its stored blocks. Returns the version the file
was in before migrating; a no-op if it was already current.
This does not touch the original bytes in place — like Self::save,
it writes a new file to <path>.tmp and renames it over path, so a
failure or interruption midway leaves the original file untouched.
Callers that want a backup of the pre-migration file should copy it
before calling this.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for DocumentStore
impl RefUnwindSafe for DocumentStore
impl Send for DocumentStore
impl Sync for DocumentStore
impl Unpin for DocumentStore
impl UnsafeUnpin for DocumentStore
impl UnwindSafe for DocumentStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more