pub struct Collection { /* private fields */ }Expand description
A collection represents a namespace for documents in the Sentinel database.
Collections are backed by filesystem directories, where each document is stored as a JSON file. The collection provides CRUD operations (Create, Read, Update, Delete) for managing documents asynchronously using tokio.
§Structure
Each collection is stored in a directory with the following structure:
{collection_name}/- Root directory for the collection{collection_name}/{id}.json- Individual document files
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
// Create a store and get a collection
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Insert a document
let user_data = json!({
"name": "Alice",
"email": "alice@example.com"
});
collection.insert("user-123", user_data).await?;
// Retrieve the document
let doc = collection.get("user-123").await?;
assert!(doc.is_some());Implementations§
Source§impl Collection
impl Collection
Sourcepub async fn insert(&self, id: &str, data: Value) -> Result<()>
pub async fn insert(&self, id: &str, data: Value) -> Result<()>
Inserts a new document into the collection or overwrites an existing one.
The document is serialized to pretty-printed JSON and written to a file named
{id}.json within the collection’s directory. If a document with the same ID
already exists, it will be overwritten.
§Arguments
id- A unique identifier for the document. This will be used as the filename (with.jsonextension). Must be filesystem-safe.data- The JSON data to store. Can be any validserde_json::Value.
§Returns
Returns Ok(()) on success, or a SentinelError if the operation fails
(e.g., filesystem errors, serialization errors).
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
let user = json!({
"name": "Alice",
"email": "alice@example.com",
"age": 30
});
collection.insert("user-123", user).await?;Sourcepub async fn get(&self, id: &str) -> Result<Option<Document>>
pub async fn get(&self, id: &str) -> Result<Option<Document>>
Retrieves a document from the collection by its ID.
Reads the JSON file corresponding to the given ID and deserializes it into
a Document struct. If the document doesn’t exist, returns None.
§Arguments
id- The unique identifier of the document to retrieve.
§Returns
Returns:
Ok(Some(Document))if the document exists and was successfully readOk(None)if the document doesn’t exist (file not found)Err(SentinelError)if there was an error reading or parsing the document
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Insert a document first
collection.insert("user-123", json!({"name": "Alice"})).await?;
// Retrieve the document
let doc = collection.get("user-123").await?;
assert!(doc.is_some());
assert_eq!(doc.unwrap().id(), "user-123");
// Try to get a non-existent document
let missing = collection.get("user-999").await?;
assert!(missing.is_none());Sourcepub async fn update(&self, id: &str, data: Value) -> Result<()>
pub async fn update(&self, id: &str, data: Value) -> Result<()>
Updates an existing document or creates a new one if it doesn’t exist.
This method is semantically equivalent to insert in the current implementation,
as it overwrites the entire document. Future versions may implement partial updates
or version tracking.
§Arguments
id- The unique identifier of the document to update.data- The new JSON data that will replace the existing document.
§Returns
Returns Ok(()) on success, or a SentinelError if the operation fails.
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Insert initial document
collection.insert("user-123", json!({"name": "Alice", "age": 30})).await?;
// Update the document with new data
collection.update("user-123", json!({"name": "Alice", "age": 31})).await?;
// Verify the update
let doc = collection.get("user-123").await?.unwrap();
assert_eq!(doc.data()["age"], 31);Sourcepub async fn delete(&self, id: &str) -> Result<()>
pub async fn delete(&self, id: &str) -> Result<()>
Deletes a document from the collection (soft delete).
Moves the JSON file corresponding to the given ID to a .deleted/ subdirectory
within the collection. This implements soft deletes, allowing for recovery
of accidentally deleted documents. The .deleted/ directory is created
automatically if it doesn’t exist.
If the document doesn’t exist, the operation succeeds silently (idempotent).
§Arguments
id- The unique identifier of the document to delete.
§Returns
Returns Ok(()) on success (including when the document doesn’t exist),
or a SentinelError if the operation fails due to filesystem errors.
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Insert a document
collection.insert("user-123", json!({"name": "Alice"})).await?;
// Soft delete the document
collection.delete("user-123").await?;
// Document is no longer accessible via get()
let doc = collection.get("user-123").await?;
assert!(doc.is_none());
// But the file still exists in .deleted/
// (can be recovered manually if needed)Sourcepub async fn list(&self) -> Result<Vec<String>>
pub async fn list(&self) -> Result<Vec<String>>
Lists all document IDs in the collection.
Scans the collection directory for JSON files and returns their IDs (filenames without the .json extension). This operation reads the directory contents and filters for valid document files, skipping hidden directories and metadata directories for optimization.
§Returns
Returns Ok(Vec<String>) containing all document IDs in the collection,
or a SentinelError if the operation fails due to filesystem errors.
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Insert some documents
collection.insert("user-123", json!({"name": "Alice"})).await?;
collection.insert("user-456", json!({"name": "Bob"})).await?;
// List all documents
let ids = collection.list().await?;
assert_eq!(ids.len(), 2);
assert!(ids.contains(&"user-123".to_string()));
assert!(ids.contains(&"user-456".to_string()));Sourcepub async fn bulk_insert(&self, documents: Vec<(&str, Value)>) -> Result<()>
pub async fn bulk_insert(&self, documents: Vec<(&str, Value)>) -> Result<()>
Performs bulk insert operations on multiple documents.
Inserts multiple documents into the collection in a single operation. If any document fails to insert, the operation stops and returns an error. Documents are inserted in the order provided.
§Arguments
documents- A vector of (id, data) tuples to insert.
§Returns
Returns Ok(()) on success, or a SentinelError if any operation fails.
In case of failure, some documents may have been inserted before the error.
§Example
use sentinel_dbms::{Store, Collection};
use serde_json::json;
let store = Store::new("/path/to/data", None).await?;
let collection = store.collection("users").await?;
// Prepare bulk documents
let documents = vec![
("user-123", json!({"name": "Alice", "role": "admin"})),
("user-456", json!({"name": "Bob", "role": "user"})),
("user-789", json!({"name": "Charlie", "role": "user"})),
];
// Bulk insert
collection.bulk_insert(documents).await?;
// Verify all documents were inserted
assert!(collection.get("user-123").await?.is_some());
assert!(collection.get("user-456").await?.is_some());
assert!(collection.get("user-789").await?.is_some());Trait Implementations§
Source§impl Clone for Collection
impl Clone for Collection
Source§fn clone(&self) -> Collection
fn clone(&self) -> Collection
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more