Skip to main content

Store

Struct Store 

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

The top-level manager for document collections in Cyberpath Sentinel.

Store manages the root directory where all collections are stored. It handles directory creation, collection access, and serves as the entry point for all document storage operations. Each Store instance corresponds to a single filesystem-backed database.

§Architecture

The Store creates a hierarchical structure:

  • Root directory (specified at creation)
    • data/ subdirectory (contains all collections)
      • Collection directories (e.g., users/, audit_logs/)

§Examples

use sentinel_dbms::Store;

// Create a new store at the specified path
let store =
    Store::new("/var/lib/sentinel/db", Some("my_passphrase")).await?;

// Access a collection
let users = store.collection("users").await?;

§Thread Safety

Store is safe to share across threads. Multiple collections can be accessed concurrently, with each collection managing its own locking internally.

Implementations§

Source§

impl Store

Source

pub async fn collection(&self, name: &str) -> Result<Collection>

👎Deprecated since 2.0.2: Please use collection_with_config to specify WAL configuration

Retrieves or creates a collection with the specified name.

This method provides access to a named collection within the store. If the collection directory doesn’t exist, it will be created automatically under the data/ subdirectory of the store’s root path.

§Parameters
  • name - The name of the collection. This will be used as the directory name under data/. The name should be filesystem-safe (avoid special characters that are invalid in directory names on your target platform).
§Returns
  • Result<Collection> - Returns a Collection instance on success, or a SentinelError if:
    • The collection directory cannot be created due to permission issues
    • The name contains invalid characters for the filesystem
    • I/O errors occur during directory creation
§Examples
use sentinel_dbms::Store;
use serde_json::json;

let store = Store::new("/var/lib/sentinel", None).await?;

// Access a users collection
let users = store.collection("users").await?;

// Insert a document into the collection
users.insert("user-123", json!({
    "name": "Alice",
    "email": "alice@example.com"
})).await?;

// Access multiple collections
let audit_logs = store.collection("audit_logs").await?;
let certificates = store.collection("certificates").await?;
§Collection Naming

Collection names should follow these guidelines:

  • Use lowercase letters, numbers, underscores, and hyphens
  • Avoid spaces and special characters
  • Keep names descriptive but concise (e.g., users, audit_logs, api_keys)
§Notes
  • Calling this method multiple times with the same name returns separate Collection instances pointing to the same directory
  • The data/ subdirectory is created automatically on first collection access
  • Collections are not cached; each call creates a new Collection instance
  • No validation is performed on the collection name beyond filesystem constraints
Source

pub async fn collection_with_config( &self, name: &str, wal_overrides: Option<CollectionWalConfigOverrides>, ) -> Result<Collection>

Retrieves or creates a collection with the specified name and custom WAL configuration overrides.

This method provides access to a named collection within the store with custom WAL settings that override the stored or default configuration. If the collection directory doesn’t exist, it will be created automatically under the data/ subdirectory of the store’s root path.

§Parameters
  • name - The name of the collection. This will be used as the directory name under data/. The name should be filesystem-safe.
  • wal_overrides - Optional WAL configuration overrides for this collection
§Returns
  • Result<Collection> - Returns a Collection instance on success, or a SentinelError if:
    • The collection directory cannot be created due to permission issues
    • The name contains invalid characters for the filesystem
    • I/O errors occur during directory creation
§Examples
use sentinel_dbms::Store;
use sentinel_wal::CollectionWalConfigOverrides;
use serde_json::json;

let store = Store::new("/var/lib/sentinel", None).await?;
let wal_overrides = CollectionWalConfigOverrides {
    write_mode: Some(sentinel_wal::WalFailureMode::Warn),
    ..Default::default()
};

// Access a users collection with WAL overrides
let users = store.collection_with_config("users", Some(wal_overrides)).await?;

// Insert a document into the collection
users.insert("user-123", json!({
    "name": "Alice",
    "email": "alice@example.com"
})).await?;
Source

pub async fn delete_collection(&self, name: &str) -> Result<()>

Deletes a collection and all its documents.

This method removes the entire collection directory and all documents within it. The operation is permanent and cannot be undone. If the collection doesn’t exist, the operation succeeds silently (idempotent).

§Arguments
  • name - The name of the collection to delete
§Returns

Returns Ok(()) on success, or a SentinelError if the operation fails.

§Examples
use sentinel_dbms::Store;

let store = Store::new("/path/to/data", None).await?;

// Create a collection
let collection = store.collection("temp_collection").await?;

// ... use collection ...

// Delete the collection
store.delete_collection("temp_collection").await?;
Source

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

This method returns a list of all collection names that exist in the store. The names are returned in no particular order.

§Returns

Returns a Vec<String> containing the names of all collections.

§Examples
use sentinel_dbms::Store;

let store = Store::new("/path/to/data", None).await?;

// Create some collections
store.collection("users").await?;
store.collection("products").await?;

// List all collections
let collections = store.list_collections().await?;
assert!(collections.contains(&"users".to_string()));
assert!(collections.contains(&"products".to_string()));
Source

pub fn set_signing_key(&mut self, key: SigningKey)

Source§

impl Store

Source

pub async fn new<P>(root_path: P, passphrase: Option<&str>) -> Result<Self>
where P: AsRef<Path>,

👎Deprecated since 2.0.2: Please use new_with_config to specify WAL configuration

Creates a new Store instance at the specified root path.

This method initializes the store by creating the root directory if it doesn’t exist. It does not create the data/ subdirectory until collections are accessed.

§Parameters
  • root_path - The filesystem path where the store will be created. This can be any type that implements AsRef<Path>, including &str, String, Path, and PathBuf.
§Returns
  • Result<Self> - Returns a new Store instance on success, or a SentinelError if:
    • The directory cannot be created due to permission issues
    • The path is invalid or cannot be accessed
    • I/O errors occur during directory creation
§Examples
use sentinel_dbms::Store;

// Create a store with a string path
let store = Store::new("/var/lib/sentinel", None).await?;

// Create a store with a PathBuf
use std::path::PathBuf;
let path = PathBuf::from("/tmp/my-store");
let store = Store::new(path, None).await?;

// Create a store in a temporary directory
let temp_dir = std::env::temp_dir().join("sentinel-test");
let store = Store::new(&temp_dir, None).await?;
§Notes
  • If the directory already exists, this method succeeds without modification
  • Parent directories are created automatically if they don’t exist
  • The created directory will have default permissions set by the operating system
Source

pub async fn new_with_config<P>( root_path: P, passphrase: Option<&str>, wal_config: StoreWalConfig, ) -> Result<Self>
where P: AsRef<Path>,

Creates a new Store instance at the specified root path with custom WAL configuration.

This method initializes the store by creating the root directory if it doesn’t exist and applies the provided WAL configuration. It does not create the data/ subdirectory until collections are accessed.

§Parameters
  • root_path - The filesystem path where the store will be created. This can be any type that implements AsRef<Path>, including &str, String, Path, and PathBuf.
  • passphrase - Optional passphrase for encrypting the signing key
  • wal_config - Custom WAL configuration for the store
§Returns
  • Result<Self> - Returns a new Store instance on success, or a SentinelError if:
    • The directory cannot be created due to permission issues
    • The path is invalid or cannot be accessed
    • I/O errors occur during directory creation
§Examples
use sentinel_dbms::Store;
use sentinel_wal::StoreWalConfig;

let wal_config = StoreWalConfig::default();
let store =
    Store::new_with_config("/var/lib/sentinel", None, wal_config).await?;
Source

pub const fn created_at(&self) -> DateTime<Utc>

Returns the creation timestamp of the store.

Source

pub fn last_accessed_at(&self) -> DateTime<Utc>

Returns the last access timestamp of the store.

Source

pub fn total_size_bytes(&self) -> u64

Returns the total size of all collections in the store in bytes.

Source

pub fn total_documents(&self) -> u64

Returns the total number of documents across all collections in the store.

Source

pub fn collection_count(&self) -> u64

Returns the total number of collections in the store.

Source

pub const fn root_path(&self) -> &PathBuf

Returns the root path of the store.

This method provides access to the root directory path where the store is located. This is useful for operations that need to access store-level metadata files.

§Returns

Returns a reference to the PathBuf containing the store’s root path.

Trait Implementations§

Source§

impl Debug for Store

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Drop for Store

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl StoreWalOps for Store

Source§

fn checkpoint_all_collections<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Perform a checkpoint on all collections in the store. Read more
Source§

fn stream_all_wal_entries<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<(String, LogEntry)>> + Send>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Stream WAL entries from all collections in the store. Read more
Source§

fn verify_all_collections<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<HashMap<String, Vec<WalVerificationIssue>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Verify all collections against their WAL files. Read more
Source§

fn recover_all_collections<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<HashMap<String, usize>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Recover all collections from their WAL files. Read more

Auto Trait Implementations§

§

impl !Freeze for Store

§

impl RefUnwindSafe for Store

§

impl Send for Store

§

impl Sync for Store

§

impl Unpin for Store

§

impl UnwindSafe 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more