### Complete Nitrite Rust Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/repositories.md A full example demonstrating the creation of a Nitrite database, obtaining a repository, inserting, finding, updating, and removing user data. Includes necessary imports and error handling. ```rust use nitrite::Nitrite; use nitrite::filter::field; use nitrite_derive::{Convertible, NitriteEntity}; #[derive(Convertible, NitriteEntity, Clone)] #[entity( id(field = "id"), index(type = "unique", fields = "email") )] pub struct User { id: i64, name: String, email: String, active: bool, } fn main() -> Result<(), Box> { // Create database let db = Nitrite::builder().open_or_create(None, None)?; // Get repository let repo = db.repository::()?; // Insert users repo.insert(User { id: 1, name: "Alice".to_string(), email: "alice@example.com".to_string(), active: true, })?; // Find users let cursor = repo.find(field("active").eq(true))?; for result in cursor { println!("User: {:?}", result?); } // Find by ID if let Some(user) = repo.find_by_id(&1)? { println!("Found: {}", user.name); } // Update let filter = field("id").eq(1i64); let updated = User { id: 1, name: "Alice Smith".to_string(), email: "alice@example.com".to_string(), active: true, }; repo.update(filter, updated)?; // Remove repo.remove(field("id").eq(1i64), true)?; db.close()?; Ok(()) } ``` -------------------------------- ### Complete Document Creation and Usage Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md A comprehensive example demonstrating the creation of a Nitrite Document, adding various data types including nested structures and arrays, accessing fields, and iterating over document keys. ```rust use nitrite::collection::Document; use nitrite::doc; fn main() -> Result<(), Box> { // Create document let mut user = Document::new(); // Add basic fields user.put("id", 1i64)?; user.put("name", "Alice Johnson")?; user.put("email", "alice@example.com")?; user.put("age", 30i64)?; user.put("active", true)?; // Add nested address user.put("address.street", "123 Main St")?; user.put("address.city", "New York")?; user.put("address.zip", "10001")?; // Add array of tags let tags = vec!["engineer", "database", "rust"]; user.put("tags", tags)?; // Add nested document let mut metadata = Document::new(); metadata.put("created", 1234567890i64)?; metadata.put("updated", 1234567890i64)?; user.put("metadata", metadata)?; // Access fields println!("Name: {:?}", user.get("name")?); println!("City: {:?}", user.get("address.city")?); println!("Tags: {:?}", user.get("tags")?); println!("Size: {}", user.size()); // Iterate all fields for key in user.keys() { println!("Field: {}", key); } Ok(()) } ``` -------------------------------- ### Multi-condition OR Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/filters.md Shows how to use multiple `or` operations to match documents where a field can have any of several specified values. ```rust use nitrite::filter::field; let filter = field("role").eq("admin") .or(field("role").eq("manager")) .or(field("role").eq("lead")); let results = collection.find(filter)?; ``` -------------------------------- ### Configure Windows Database Path Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Example of setting the database path for Windows systems using FjallModule. Ensure all configurations are set before opening the database. ```rust let db = Nitrite::builder() .load_module( FjallModule::with_config() .db_path("C:\\ProgramData\\app\\database") .build() ) .open_or_create(None, None)?; ``` -------------------------------- ### Quick Start: Create, Insert, and Query in Nitrite Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite/README.md Demonstrates the basic workflow of creating an in-memory Nitrite database, accessing a collection, inserting a document, and querying for documents using a field filter. Ensure Nitrite, filter, and doc are imported. ```rust use nitrite::nitrite::Nitrite; use nitrite::filter::field; use nitrite::doc; // Create an in-memory database let db = Nitrite::builder() .open_or_create(None, None) .expect("Failed to create database"); // Get a collection let collection = db.collection("users").unwrap(); // Insert a document collection.insert(doc!{"name": "John", "age": 30}).unwrap(); // Query documents let cursor = collection.find(field("name").eq("John")).unwrap(); for doc in cursor { println!("{:?}", doc); } // Close the database db.close().unwrap(); ``` -------------------------------- ### Configure Linux/Unix Database Path Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Example of setting the database path for Linux/Unix systems using FjallModule. Ensure all configurations are set before opening the database. ```rust let db = Nitrite::builder() .load_module( FjallModule::with_config() .db_path("/var/lib/app/database") .build() ) .open_or_create(None, None)?; ``` -------------------------------- ### store Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/nitrite.md Gets the underlying storage backend implementation for the Nitrite database. ```APIDOC ## `pub fn store(&self) -> NitriteStore` ### Description Gets the underlying storage backend. ### Returns - **NitriteStore** - A clone of the `NitriteStore` implementing the storage provider. ``` -------------------------------- ### Complete Nitrite-Rust Configuration Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Demonstrates a comprehensive configuration including custom field separators, persistent storage with Fjall, spatial indexing, and schema versioning. Accesses configuration values after opening the database. ```rust use nitrite::Nitrite; use nitrite_fjall_adapter::FjallModule; use nitrite_spatial::SpatialModule; fn main() -> Result<(), Box> { // Create database with custom configuration let db = Nitrite::builder() // Configure nested field access .field_separator(".") // Use persistent storage .load_module( FjallModule::with_config() .db_path("/path/to/database") .build() ) // Enable spatial indexing .load_module(SpatialModule) // Set schema version .schema_version(1) // Open the database .open_or_create(None, None)?; // Use the database let collection = db.collection("locations")?; // Access configuration let config = db.config(); println!("Field separator: {}", config.field_separator()); println!("Schema version: {}", config.schema_version()); if let Some(path) = config.db_path() { println!("Database path: {}", path); } // Close the database db.close()?; Ok(()) } ``` -------------------------------- ### Basic Usage with Collections Source: https://github.com/nitrite/nitrite-rust/blob/main/README.md Demonstrates opening an in-memory Nitrite database, getting a collection, inserting documents using the doc! macro, and querying with filters. ```rust use nitrite::nitrite::Nitrite; use nitrite::filter::field; use nitrite::doc; // Open an in-memory database let db = Nitrite::builder() .open_or_create(None, None) .expect("Failed to open database"); // Get a collection let collection = db.collection("users").unwrap(); // Insert documents using the doc! macro collection.insert(doc!{ "name": "John Doe", "age": 30, "active": true }).unwrap(); // Query with filters let cursor = collection.find(field("name").eq("John Doe")).unwrap(); for doc in cursor { println!("{:?}", doc); } // Close the database db.close().unwrap(); ``` -------------------------------- ### Multi-condition AND Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/filters.md Demonstrates combining multiple field equality and range checks using the `and` operator for a comprehensive search. ```rust use nitrite::filter::field; let filter = field("department").eq("Engineering") .and(field("salary").gte(80000i64)) .and(field("years_experience").gte(5i64)); let results = collection.find(filter)?; ``` -------------------------------- ### Collection Not Found Error Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Illustrates the error scenario when attempting to use a collection that does not exist as a repository. ```rust // This will fail if "users" was created as a repository, not collection let collection = db.collection("users")?; // Error: Can't access repository "users" as a collection ``` -------------------------------- ### Configure macOS Database Path Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Example of setting the database path for macOS systems using FjallModule. Ensure all configurations are set before opening the database. ```rust let db = Nitrite::builder() .load_module( FjallModule::with_config() .db_path("~/Library/Application Support/app/database") .build() ) .open_or_create(None, None)?; ``` -------------------------------- ### Index Not Found Error Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Shows the error that occurs when attempting to drop an index that does not exist. ```rust collection.drop_index(vec!["nonexistent"])?; // Error: Index not found ``` -------------------------------- ### Check and Create Index if Not Exists Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/indexing.md Provides an example of checking if an index already exists on a field before creating it, preventing potential errors. ```rust use nitrite::index::unique_index; if !collection.has_index(vec!["email"])? { collection.create_index(vec!["email"], &unique_index())?; } ``` -------------------------------- ### Store Already Closed Error Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Demonstrates the `StoreAlreadyClosed` error, which occurs when attempting to access the database after it has been closed. ```rust let db = Nitrite::builder().open_or_create(None, None)?; db.close()?; let collection = db.collection("users")?; // Error: StoreAlreadyClosed ``` -------------------------------- ### Begin a New Transaction Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Start a new transaction within an active session using `begin_transaction`. This provides a `NitriteTransaction` object for subsequent operations. ```rust db.with_session(|session| { let transaction = session.begin_transaction()?; // Use transaction... Ok(()) })?; ``` -------------------------------- ### Nitrite-Rust Error Handling During Configuration Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Illustrates how configuration errors, such as an invalid empty field separator, are caught by the builder and returned as an `Err` when `open_or_create()` is called. The example shows how to match on the result to handle potential errors. ```rust use nitrite::Nitrite; let db = Nitrite::builder() .field_separator("") // Invalid: empty separator .open_or_create(None, None); // Returns Err with ValidationError match db { Ok(_) => println!("Success"), Err(e) => println!("Error: {}", e), } ``` -------------------------------- ### Nitrite Instance Repository Operations Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Shows methods for managing repositories (both generic and keyed) within a Nitrite database instance, including getting, checking existence, listing, and destroying repositories. ```rust // Repositories db.repository::()?; // get or create db.keyed_repository::("prod")?; // keyed variant db.has_repository::()?; // check existence db.has_keyed_repository::("prod")?; // check keyed db.list_repositories()?; // HashSet db.list_keyed_repositories()?; // HashMap> db.destroy_repository::()?; // drop repository db.destroy_keyed_repository::("prod")?; // drop keyed ``` -------------------------------- ### NitriteId Usage Examples Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/types.md Demonstrates common operations involving NitriteId, including auto-generation during insertion, retrieving documents by ID, and filtering documents based on their ID. ```rust use nitrite::collection::NitriteId; // IDs are auto-generated during insertion let result = collection.insert(doc)?; for id in result.inserted_ids() { println!("Inserted ID: {:?}", id); } // Retrieve by ID let doc = collection.get_by_id(&id)?; // Filter by ID let cursor = collection.find(by_id(id))?; ``` -------------------------------- ### Getting Values from a Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Details the `get` method for retrieving values by key, including support for nested fields and type-safe retrieval. ```APIDOC ### Getting Values `pub fn get(&self, key: &str) -> NitriteResult>` Retrieves the value associated with a given key. Supports nested field access using the configured separator. **Parameters:** - **key** (`&str`): The name of the field to retrieve. Can be a nested path (e.g., `"user.name"`). **Returns:** `Some(Value)` if the field exists, `None` if the field is not found. **Example:** ```rust let doc = doc! {"name": "Alice", "age": 30}; match doc.get("name")? { Some(Value::String(name)) => println!("Name: {}", name), Some(_) => println!("Wrong type"), None => println!("Field not found"), } // Nested access example: let nested_doc = doc! {"user": {"name": "Alice"}}; let name = nested_doc.get("user.name")?; ``` **Type-Safe Retrieval:** You can pattern match on the `Value` enum for type-safe access. ```rust if let Some(Value::Number(age)) = doc.get("age")? { println!("Age: {}", age); } ``` ``` -------------------------------- ### Get Nested Values from a Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Access nested field values using the dot separator ('.') with the `get` method. The result is an `Option`. ```rust let doc = doc! {"user": {"name": "Alice"}}; let name = doc.get("user.name")?; ``` -------------------------------- ### Compare Two Saved Baselines Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Compares two different saved baselines using the 'critcmp' tool. Ensure 'critcmp' is installed via 'cargo install critcmp'. ```bash # First save both baselines cargo bench -p nitrite_bench -- --save-baseline old-version # Make changes... cargo bench -p nitrite_bench -- --save-baseline new-version # Compare them using critcmp (install with: cargo install critcmp) critcmp old-version new-version ``` -------------------------------- ### Creating and Applying a Database Migration Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Illustrates how to create a `Migration` object with custom steps and apply it when opening or creating a Nitrite database. ```rust use nitrite::Nitrite; // Assuming MyMigration is defined elsewhere // let migration = Migration::create(1, 2) // .add_instruction(Box::new(MyMigration)) // .finalize(); // let db = Nitrite::builder() // .schema_version(2) // .add_migration(migration) // .open_or_create(None, None)?; ``` -------------------------------- ### Multi-Collection Transaction Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Shows how to perform atomic operations across multiple collections within a single transaction. All operations (inserts, updates) will either succeed together or fail together, ensuring data consistency. ```rust db.with_session(|session| { let transaction = session.begin_transaction()?; // Access multiple collections let users = transaction.collection("users")?; let orders = transaction.collection("orders")?; let inventory = transaction.collection("inventory")?; // Update all three atomically let user_doc = doc! {"id": 1, "order_count": 5}; let order_doc = doc! {"user_id": 1, "total": 99.99}; let inv_doc = doc! {"sku": "XYZ", "stock": 10}; users.insert(user_doc)?; orders.insert(order_doc)?; inventory.update(filter, &inv_doc)?; // Either all succeed or all fail transaction.commit()?; Ok(()) })?; ``` -------------------------------- ### Nitrite Instance Collection Operations Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Demonstrates methods for managing collections within a Nitrite database instance, including getting, checking existence, listing, and destroying collections. ```rust // Collections db.collection("users")?; // get or create db.has_collection("users")?; // check existence db.list_collection_names()?; // HashSet db.destroy_collection("users")?; // drop collection ``` -------------------------------- ### name Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/collections.md Gets the name of the current collection. ```APIDOC ## `pub fn name(&self) -> String` ### Description Returns the name of this collection. ### Example ```rust println!("Collection name: {}", collection.name()); ``` ``` -------------------------------- ### Get Collection Name Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/collections.md Retrieves the name of the current collection. ```rust println!("Collection name: {}", collection.name()); ``` -------------------------------- ### Create a new database instance Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/nitrite.md Use the `builder()` method to obtain a `NitriteBuilder` and configure database options before opening or creating the database. ```APIDOC ## `pub fn builder() -> NitriteBuilder` ### Description Creates a new `NitriteBuilder` for configuring and opening a database. ### Returns A new `NitriteBuilder` instance with default configuration. ### Example ```rust use nitrite::Nitrite; let db = Nitrite::builder() .open_or_create(None, None)?; ``` ``` -------------------------------- ### Create and Open a Nitrite Database Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/nitrite.md Use `Nitrite::builder()` to configure and open a new or existing Nitrite database. This is the initial step before performing any database operations. ```rust use nitrite::Nitrite; let db = Nitrite::builder() .open_or_create(None, None)?; ``` -------------------------------- ### Get Collection Size Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Returns the number of documents currently stored in a collection. ```rust // Collection metadata let count = col.size()?; ``` -------------------------------- ### Get the error message Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Retrieve the descriptive message associated with a NitriteError instance. ```rust eprintln!("Error: {}", error.message()); ``` -------------------------------- ### Document Creation Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Demonstrates how to create new documents using the `Document::new()` constructor and the `doc!` macro. ```APIDOC ## Document Creation ### Using `Document::new()` Creates an empty document. ```rust use nitrite::collection::Document; let mut doc = Document::new(); assert!(doc.is_empty()); assert_eq!(doc.size(), 0); ``` ### Using the `doc!` Macro Provides a convenient way to initialize documents with key-value pairs. ```rust use nitrite::doc; let doc = doc! { "name": "Alice", "age": 30, "email": "alice@example.com" }; ``` ### Cloning Documents Documents can be cloned efficiently using `clone()`, which shares internal data. ```rust let doc1 = doc! {"name": "Alice"}; let doc2 = doc1.clone(); // Cheap operation, shares internal structure ``` ``` -------------------------------- ### Run Full Benchmark Suite with HTML Report Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Executes all benchmarks and generates an HTML report for detailed analysis. ```bash cargo bench -p nitrite_bench ``` -------------------------------- ### Get Collection Document Count Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/collections.md Returns the total number of documents currently stored in the collection. ```rust let count = collection.size()?; println!("Collection has {} documents", count); ``` -------------------------------- ### Get All Values from a Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Retrieves all values from a Nitrite document as a vector. Useful for iterating over all fields. ```rust let values = doc.values(); // Vec for value in values { println!("Value: {:?}", value); } ``` -------------------------------- ### Initialize Tantivy Full-Text Search Module Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Demonstrates how to load the TantivyFtsModule with default and custom configurations when opening or creating a Nitrite database. ```rust use nitrite_tantivy_fts::{TantivyFtsModule, fts_index, fts_field}; // Default config let db = Nitrite::builder() .load_module(TantivyFtsModule::default()) .open_or_create(None, None)?; // Custom config let db = Nitrite::builder() .load_module(TantivyFtsModule::with_config() .index_writer_heap_size(100 * 1024 * 1024) .num_threads(4) .search_result_limit(5000) .build()) .open_or_create(None, None)?; let col = db.collection("articles")?; col.create_index(vec!["content"], &fts_index())?; let results = col.find(fts_field("content").matches("rust database"))?; ``` -------------------------------- ### Get Repository Name Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/repositories.md Retrieves the name of the repository, typically derived from the entity type it manages. ```rust println!("Repository: {}", repo.name()); ``` -------------------------------- ### open_or_create Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Opens or creates a database with the configured settings. This method handles database initialization, module loading, and schema migration execution. ```APIDOC ## `pub fn open_or_create(self, username: Option<&str>, password: Option<&str>) -> NitriteResult` ### Description Opens or creates a database with the configured settings. This method handles database initialization, module loading, and schema migration execution. ### Parameters #### Path Parameters - **username** (Option<&str>) - No - Optional username for authentication - **password** (Option<&str>) - No - Optional password for authentication ### Returns `Ok(Nitrite)` if successful, or `Err(NitriteError)` if initialization fails. ### Errors - `ValidationError` if configuration is invalid - `IOError` if database file access fails - `SecurityError` if authentication fails - Errors from loaded modules ### Behavior - Returns errors captured during builder configuration - Initializes all loaded modules - Creates database if it doesn't exist - Opens existing database if it exists - Validates authentication credentials if provided - Executes schema migrations if version mismatch ### Example ```rust use nitrite::Nitrite; // Basic usage - in-memory database let db = Nitrite::builder() .open_or_create(None, None)?; // With authentication let db = Nitrite::builder() .open_or_create(Some("admin"), Some("password"))?; // With configuration let db = Nitrite::builder() .field_separator("|") .schema_version(2) .load_module(FjallModule::with_config().db_path("./data").build()) .open_or_create(None, None)?; ``` ``` -------------------------------- ### Get Document by ID Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/collections.md Retrieves a document from a collection using its unique NitriteId. This is a constant-time O(1) operation. ```rust if let Some(doc) = collection.get_by_id(&id)? { println!("Found: {:?}", doc); } else { println!("Document not found"); } ``` -------------------------------- ### Create ObjectRepository Instance Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/repositories.md Demonstrates how to create an ObjectRepository for a User struct. Ensure the User struct derives Convertible and NitriteEntity. ```rust use nitrite_derive::{NitriteEntity, Convertible}; use nitrite::filter::field; #[derive(Convertible, NitriteEntity)] #[entity(id(field = "id"))] pub struct User { pub id: i64, pub name: String, pub email: String, } let db = Nitrite::builder().open_or_create(None, None)?; let repo: ObjectRepository = db.repository()?; ``` -------------------------------- ### FindOptions Builder and Constructors Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Demonstrates how to build FindOptions using the builder pattern or convenience constructors for sorting, skipping, and limiting results. ```rust use nitrite::collection::{FindOptions, order_by, skip_by, limit_to, distinct}; use nitrite::common::SortOrder; // Builder pattern let opts = FindOptions::new() .sort_by("name", SortOrder::Ascending) .sort_by("age", SortOrder::Descending) .skip(10) .limit(20); // Convenience constructors let opts = order_by("name", SortOrder::Ascending); let opts = skip_by(5); let opts = limit_to(100); let opts = distinct(); ``` -------------------------------- ### Get the error kind Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Inspect the specific type of error that occurred using the error's kind. ```rust match error.kind() { ErrorKind::IndexNotFound => println!("Index missing"), _ => println!("Other error"), } ``` -------------------------------- ### Nitrite Filters - Special Operators Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Includes examples for 'all' to match all documents and 'by_id' to match by NitriteId. ```rust use nitrite::filter::{all, by_id}; // Special all() // match all documents by_id(&id) // match by NitriteId ``` -------------------------------- ### Create a Document with the `doc!` Macro Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md The `doc!` macro provides a concise way to initialize a document with key-value pairs. ```rust use nitrite::doc; let doc = doc! { "name": "Alice", "age": 30, "email": "alice@example.com" }; ``` -------------------------------- ### Create Nitrite DB with Fjall Default Configuration Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-fjall-adapter/README.md Demonstrates how to create a Nitrite database using the Fjall adapter with its default configuration. Ensure the `nitrite` and `nitrite_fjall_adapter` crates are in scope. ```rust use nitrite::nitrite::Nitrite; use nitrite_fjall_adapter::FjallModule; // Create with default configuration let storage = FjallModule::with_config() .db_path("/path/to/database") .build(); let db = Nitrite::builder() .load_module(storage) .open_or_create(None, None) .expect("Failed to create database"); ``` -------------------------------- ### Run Database Comparison Benchmarks Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Executes comparison benchmarks against other embedded databases like SQLite, Redb, and Sled. Dependencies are downloaded on the first run. ```bash cargo bench -p nitrite_bench --features comparison --bench comparison_bench ``` -------------------------------- ### Get Document ID in Rust Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/collections.md Demonstrates how to retrieve and check the '_id' field from a document, specifically identifying it as a NitriteId. ```rust use nitrite::collection::NitriteId; // Getting an ID from a document if let Ok(Some(id_value)) = doc.get("_id") { match id_value { Value::NitriteId(id) => println!("Document ID: {:?}", id), _ => {} } } ``` -------------------------------- ### Run CI Benchmark Configuration Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Executes benchmarks with reduced warm-up and measurement times for faster execution in CI environments, sacrificing some statistical precision. ```bash # Quick CI benchmark (faster, less statistical precision) cargo bench -p nitrite_bench -- --warm-up-time 1 --measurement-time 2 ``` -------------------------------- ### Defining a Custom Migration Step Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Shows how to implement the `MigrationStep` trait to define custom database migration logic. ```rust use nitrite::migration::{Migration, MigrationStep, MigrationArguments}; struct MyMigration; impl MigrationStep for MyMigration { fn migrate(&self, args: &mut MigrationArguments) -> nitrite::errors::NitriteResult<()> { // args provides transactional access: // args.collection("name") -> TransactionalCollection // args.repository::() -> TransactionalRepository Ok(()) } } ``` -------------------------------- ### Build Nitrite Rust from Source Source: https://github.com/nitrite/nitrite-rust/blob/main/README.md Instructions for cloning the Nitrite Rust repository and building the project from source using Cargo. This includes running tests to ensure the build integrity. ```bash git clone https://github.com/nitrite/nitrite-rust.git cd nitrite-rust cargo build --release cargo test --workspace ``` -------------------------------- ### Get Document by ID from Collection Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Retrieves a single document from a collection using its unique identifier. Returns an `Option`. ```rust // Get by ID let doc = col.get_by_id(&id)?; // returns Option ``` -------------------------------- ### Get Nitrite Database Configuration Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/nitrite.md Retrieves the configuration of the Nitrite database. This allows access to settings like the field separator. ```rust let config = db.config(); let separator = config.field_separator(); ``` -------------------------------- ### Invalid Operation Error Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Shows the `ErrorKind::InvalidOperation` error, which occurs when attempting an operation that is not permitted in the current context. ```rust doc.put("_id", "manual_id")?; // Error: Can't set _id manually ``` -------------------------------- ### Initialize Spatial Indexing Module Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Load the `SpatialModule` to enable spatial indexing capabilities. Create indexes on location fields and use spatial filters for queries. ```rust use nitrite_spatial::{SpatialModule, spatial_index, spatial_field, Geometry}; let db = Nitrite::builder() .load_module(SpatialModule) .open_or_create(None, None)?; let col = db.collection("places")?; col.create_index(vec!["location"], &spatial_index())?; ``` -------------------------------- ### Compare Against Previous Release Baseline Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Runs benchmarks and compares the current results against a previously saved baseline. ```bash # Run benchmarks and compare against saved baseline cargo bench -p nitrite_bench -- --baseline v0.1.0 ``` -------------------------------- ### Consistency Guarantee Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Maintains database consistency by validating constraints before a transaction is committed. If constraints are violated, the transaction will fail. ```rust // Constraints validated before commit transaction.commit()?; ``` -------------------------------- ### Build and Test Commands for Nitrite Rust Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Provides essential commands for building, testing, and benchmarking the Nitrite Rust workspace. Includes options for feature flags and specific crate testing. ```bash # Build everything cargo build --workspace ``` ```bash # Run all unit + doc tests cargo test --workspace --verbose ``` ```bash # Run tests with custom separator feature flag cargo test --features custom_separator -- custom_separator_test ``` ```bash # Integration tests: Fjall (persistent) backend (default) cargo test -p nitrite_int_test ``` ```bash # Integration tests: in-memory backend cargo test -p nitrite_int_test --features memory --no-default-features ``` ```bash # Run benchmarks cargo bench -p nitrite_bench ``` ```bash # Run comparison benchmarks (vs SQLite/Redb/Sled) cargo bench -p nitrite_bench --features comparison ``` -------------------------------- ### Get Nitrite Database Metadata Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/nitrite.md Retrieves the metadata associated with the Nitrite database, including its version. This is useful for understanding database properties. ```rust let meta = db.database_metadata()?; println!("Database version: {}", meta.nitrite_version()); ``` -------------------------------- ### Get All Keys from a Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Retrieve a `HashSet` containing all the keys (field names) present in the document using the `keys()` method. ```rust let doc = doc! {"name": "Alice", "age": 30, "email": "alice@example.com"}; let keys = doc.keys(); // HashSet for key in keys { println!("Field: {}", key); } ``` -------------------------------- ### Full Index Lifecycle Management Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/indexing.md Demonstrates the complete lifecycle of indexes, including creation of unique and non-unique indexes, data insertion, querying, listing, checking existence, and dropping indexes. ```rust use nitrite::Nitrite; use nitrite::filter::field; use nitrite::index::{unique_index, non_unique_index}; fn main() -> Result<(), Box> { let db = Nitrite::builder().open_or_create(None, None)?; let col = db.collection("users")?; // Create indexes col.create_index(vec!["email"], &unique_index())?; col.create_index(vec!["department"], &non_unique_index())?; // Insert data (index maintained automatically) for i in 0..1000 { let doc = doc! { "email": format!("user{}@example.com", i), "name": format!("User {}", i), "department": if i % 3 == 0 { "Engineering" } else { "Sales" } }; col.insert(doc)?; } // Query uses indexes efficiently let results = col.find(field("email").eq("user500@example.com"))?; // List current indexes let indexes = col.list_indexes()?; println!("Active indexes: {:?}", indexes.len()); // Check specific index if col.has_index(vec!["email"])? { println!("Email index exists"); } // Drop unused index col.drop_index(vec!["department"])?; db.close()?; Ok(()) } ``` -------------------------------- ### Get Transactional Collection Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Retrieves a transactional collection by its name. This allows performing CRUD operations within the context of an active transaction. ```APIDOC ## `pub fn collection(&self, name: &str) -> NitriteResult` ### Description Retrieves a transactional collection by its name. This allows performing CRUD operations within the context of an active transaction. ### Method `collection` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let transaction = session.begin_transaction()?; let users_col = transaction.collection("users")?; let orders_col = transaction.collection("orders")?; ``` ### Response #### Success Response (200) - **TransactionalCollection** (type) - A collection object that supports transactional operations. #### Response Example ```rust // Returns a TransactionalCollection object ``` ### Errors - Returns error if the collection cannot be accessed within the transaction. ``` -------------------------------- ### Create an Empty Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Use `Document::new()` to create an empty document. Check its initial state using `is_empty()` and `size()`. ```rust use nitrite::collection::Document; let mut doc = Document::new(); assert!(doc.is_empty()); assert_eq!(doc.size(), 0); ``` -------------------------------- ### Get the cause of an error Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Access the underlying error that caused the current error, if one exists. This helps in debugging chained errors. ```rust if let Some(cause) = error.cause() { println!("Caused by: {}", cause.message()); } ``` -------------------------------- ### In-Memory Database Configuration Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/README.md Shows how to configure and open an in-memory Nitrite database. This is useful for temporary data storage or testing scenarios where persistence is not required. ```rust use nitrite::Nitrite; use nitrite::error::NitriteResult; fn open_in_memory_db() -> NitriteResult { Nitrite::builder() .open_or_create(None, None)? } ``` -------------------------------- ### Get Transactional Repository Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Retrieve a typed repository within a transaction using `repository`. This allows for operations on entities of a specific type `T`. ```rust let transaction = session.begin_transaction()?; let user_repo = transaction.repository::()?; let order_repo = transaction.repository::()?; ``` -------------------------------- ### Configure Fjall Adapter with Production Preset Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-fjall-adapter/README.md Applies the 'production' preset for balanced settings suitable for production workloads. Specify the database path. ```rust let storage = FjallModule::with_config() .production_preset() .db_path("/path/to/database") .build(); ``` -------------------------------- ### Check Document Size and Emptiness Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Use the `size()` method to get the number of fields and `is_empty()` to check if the document contains any fields. ```rust let doc = doc! {"a": 1, "b": 2, "c": 3}; assert_eq!(doc.size(), 3); assert!(!doc.is_empty()); ``` -------------------------------- ### Create and Manipulate Nitrite Documents Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Shows how to create a new document, add key-value pairs (including nested fields), and retrieve values using the Document API and the `doc!` macro. ```rust use nitrite::collection::Document; use nitrite::doc; let mut doc = Document::new(); doc.put("name", "Alice")?; // accepts any Into doc.put("address.city", "NYC")?; // nested path via field separator let name = doc.get("name")?; // returns &Value // Or use the macro let doc = doc! { "name": "Alice", "age": 30i64 }; // Macro with nested documents let doc = doc! { "name": "Alice", "age": 30i64, "active": true, "address": { "city": "NYC", "zip": "10001" }, "tags": ["rust", "database"], }; ``` -------------------------------- ### Opening a Database Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Demonstrates various ways to open or create a Nitrite database connection, including in-memory, persistent storage with authentication, and custom configurations. ```APIDOC ## Opening a Database ### Description Provides examples for initializing a Nitrite database connection. This includes in-memory databases (with and without authentication) and persistent databases using the Fjall adapter. Custom configurations like field separators, schema versions, and migrations are also shown. ### Usage ```rust use nitrite::nitrite::Nitrite; use nitrite_fjall_adapter::FjallModule; // In-memory (default) let db = Nitrite::builder() .open_or_create(None, None)?; // In-memory with auth let db = Nitrite::builder() .open_or_create(Some("username"), Some("password"))?; // Persistent with Fjall let db = Nitrite::builder() .load_module(FjallModule::with_config().db_path("./mydb").build()) .open_or_create(None, None)?; // Custom field separator and schema version let db = Nitrite::builder() .field_separator("|") .schema_version(2) .add_migration(my_migration) .open_or_create(None, None)?; db.close()?; // explicit close; also auto-closes on last Arc drop ``` ### Closing the Database ```rust db.close()?; ``` ``` -------------------------------- ### Invalid Data Type Error Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Illustrates the `ErrorKind::InvalidDataType` error, which is triggered by data type conversion or parsing failures. ```rust "not_a_number".parse::()?; // Error: InvalidDataType ``` -------------------------------- ### Unique Constraint Violation Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/errors.md Demonstrates a `ErrorKind::UniqueConstraintViolation` error triggered by inserting a document with a duplicate value on a unique-indexed field. ```rust // Assuming "email" has a unique index collection.create_index(vec!["email"], &unique_index())?; let doc1 = doc! {"email": "user@example.com"}; collection.insert(doc1)?; let doc2 = doc! {"email": "user@example.com"}; // This fails with: ErrorKind::UniqueConstraintViolation collection.insert(doc2)?; ``` -------------------------------- ### Creating Nitrite Documents Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/types.md Shows two methods for creating Nitrite documents: using the convenient `doc!` macro for inline definition and manual construction by iteratively adding key-value pairs. ```rust // Using doc! macro let doc = doc! { "name": "Alice", "age": 30, "email": "alice@example.com" }; // Manual construction let mut doc = Document::new(); doc.put("name", "Alice")?; doc.put("age", 30i64)?; doc.put("email", "alice@example.com")?; ``` -------------------------------- ### Using ObjectRepository for Type-Safe Operations Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Shows how to get and use an ObjectRepository for CRUD operations on User entities, including finding by filter and ID. ```rust use nitrite::filter::{field}; // Assuming User struct and db are defined elsewhere // let repo: ObjectRepository = db.repository()?; // Keyed repository (multiple instances of same type) // let repo_prod: ObjectRepository = db.keyed_repository("prod")?; // repo.insert(User { id: 1, name: "Alice".into(), email: "a@b.com".into() })?; // repo.insert_all(vec![user1, user2])?; // let cursor = repo.find(field("name").eq("Alice"))?; // let user: Option = repo.get_by_id(&1)?; // repo.update(field("name").eq("Alice"), &updated_user)?; // repo.remove(field("id").eq(1))?; // repo.remove_by_id(&1)?; ``` -------------------------------- ### Load Storage and Feature Modules Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Integrate different storage backends or feature modules like persistent storage or spatial indexing by loading them into the builder. Load modules before calling open_or_create. ```rust use nitrite::Nitrite; use nitrite_fjall_adapter::FjallModule; use nitrite_spatial::SpatialModule; // Create database with persistent storage let db = Nitrite::builder() .load_module(FjallModule::with_config().db_path("/path/to/db").build()) .open_or_create(None, None)?; // Create database with spatial indexing let db = Nitrite::builder() .load_module(SpatialModule) .open_or_create(None, None)?; // Combine multiple modules let db = Nitrite::builder() .load_module(FjallModule::with_config().db_path("/path/to/db").build()) .load_module(SpatialModule) .open_or_create(None, None)?; ``` -------------------------------- ### View HTML Reports on Different OS Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-bench/README.md Opens the generated HTML benchmark report using the default system browser. ```bash # macOS open target/criterion/report/index.html # Linux xdg-open target/criterion/report/index.html # Windows start target/criterion/report/index.html ``` -------------------------------- ### Get Database Path from NitriteConfig Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Retrieves the database file path if the database is file-based. Returns None if the database is configured to run in-memory. ```rust let config = db.config(); if let Some(path) = config.db_path() { println!("Database file: {}", path); } else { println!("In-memory database"); } ``` -------------------------------- ### Run All Integration Tests Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-int-test/README.md Execute all integration tests for the nitrite-int-test crate. ```bash cargo test -p nitrite-int-test ``` -------------------------------- ### Overwrite an Existing Field in a Document Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Calling `put` with an existing key will update the field's value. Verify the update using `get`. ```rust let mut doc = doc! {"status": "inactive"}; doc.put("status", "active")?; // Updates existing value assert_eq!(doc.get("status")?, Some(Value::String("active".to_string()))); ``` -------------------------------- ### Initialize Fjall Persistent Storage Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Load the `FjallModule` to enable persistent storage. Configure the database path and other settings using the builder. ```rust use nitrite_fjall_adapter::FjallModule; let db = Nitrite::builder() .load_module(FjallModule::with_config() .db_path("/path/to/db") .build()) .open_or_create(None, None)?; ``` -------------------------------- ### Durability Guarantee Example Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Guarantees that committed data will survive system crashes. The commit operation ensures data is persisted to storage before returning. ```rust // Persist to storage before returning transaction.commit()?; ``` -------------------------------- ### Efficient Document Cloning and Mutation Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/documents.md Demonstrates the O(1) cloning and O(log n) mutation characteristics of Nitrite Documents, highlighting how mutations on a cloned document do not affect the original. ```rust use nitrite::doc; // Cheap clone let doc1 = doc! {"a": 1, "b": 2}; let doc2 = doc1.clone(); // O(1), shares structure // Mutations don't affect clone let mut doc2 = doc2; doc2.put("c", 3)?; assert_eq!(doc1.size(), 2); // Unaffected assert_eq!(doc2.size(), 3); // Updated ``` -------------------------------- ### Search Documents using FTS Source: https://github.com/nitrite/nitrite-rust/blob/main/nitrite-tantivy-fts/README.md Perform a full-text search query on an indexed field. This example searches for the term 'fox' in the 'content' field. ```rust use nitrite_tantivy_fts::fts_field; // Search for a term in the indexed field let filter = fts_field("content").matches("fox"); let cursor = collection.find(filter).unwrap(); ``` -------------------------------- ### Session Usage for Transactions Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/types.md Manages transactional sessions for ACID operations. Use with_session to obtain a session and begin_transaction to start a new transaction. ```rust db.with_session(|session| { let transaction = session.begin_transaction()?; let col = transaction.collection("users")?; col.insert(doc)?; transaction.commit()?; Ok(()) })?; ``` -------------------------------- ### Creating a Custom NitriteError Source: https://github.com/nitrite/nitrite-rust/blob/main/SKILL.md Demonstrates how to create a `NitriteError` with a message and an `ErrorKind`. ```rust use nitrite::errors::{NitriteError, ErrorKind, NitriteResult}; fn example() -> NitriteResult<()> { Err(NitriteError::new("message", ErrorKind::IndexNotFound)) } ``` -------------------------------- ### Accessing Nitrite Configuration at Runtime Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Demonstrates how to retrieve and assert configuration values like field separator and schema version after the database has been opened. This is useful for verifying settings or using them in subsequent operations. ```rust let db = Nitrite::builder() .field_separator("|") .schema_version(2) .open_or_create(None, None)?; // Access configuration let config = db.config(); assert_eq!(config.field_separator(), "|"); assert_eq!(config.schema_version(), 2); ``` -------------------------------- ### Creating Nitrite Filters Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/types.md Demonstrates how to construct various filter expressions using the filter API. ```rust use nitrite::filter::{field, all, by_id, and, or, not}; field("age").gte(18) // Range comparison field("name").eq("Alice") // Equality field("email").regex(".*@example\\.com$") // Regex all() // Match all by_id(id) // By ID field("a").gt(10).and(field("b").lt(20)) // Logical AND ``` -------------------------------- ### Get Migrations from NitriteConfig Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/configuration.md Retrieves all registered migrations, grouped by their source version. This allows inspection of the migration history and definitions within the database configuration. ```rust let config = db.config(); let migrations = config.migrations(); for entry in migrations.iter() { println!("From version {}", entry.key()); } ``` -------------------------------- ### Get Transactional Repository Source: https://github.com/nitrite/nitrite-rust/blob/main/_autodocs/api-reference/transactions.md Retrieves a transactional typed repository for a given entity type. This enables performing CRUD operations on entities within a transaction. ```APIDOC ## `pub fn repository(&self) -> NitriteResult>` ### Description Retrieves a transactional typed repository for a given entity type. This enables performing CRUD operations on entities within a transaction. ### Method `repository` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let transaction = session.begin_transaction()?; let user_repo = transaction.repository::()?; let order_repo = transaction.repository::()?; ``` ### Response #### Success Response (200) - **TransactionalRepository** (type) - A repository object that supports transactional operations for the specified entity type `T`. #### Response Example ```rust // Returns a TransactionalRepository object ``` ### Errors - Returns error if the repository cannot be accessed within the transaction. ```