osunbitdb 0.1.0

A lightweight async db
Documentation

OsunbitDB

OsunbitDB is a lightweight, asynchronous key-value database for Rust. It supports collection-based data storage, JSON-friendly operations, and batch transactions.

Features

Async-first design using tokio

JSON-friendly, strongly typed with serde and bincode

Collections for organizing keys

Add, get, delete, scan, and update operations

Transaction support for multiple operations in one atomic block

Firestore-style simple API (db.add, db.get, etc.)

Installation

Add this to your Cargo.toml:

[dependencies] osunbitdb = "0.1.0"

Quick Start use osunbitdb::{OsunbitDB, OsunbitDBError}; use serde::{Serialize, Deserialize}; use osunbitdb::json; // for Firestore-style JSON objects

#[derive(Serialize, Deserialize, Debug)] struct User { id: String, name: String, age: u32, }

#[tokio::main] async fn main() -> Result<(), OsunbitDBError> { // Connect to the DB let db = OsunbitDB::new(&["http://127.0.0.1:2379"]).await?;

// Add a user
let user = json!({"id": "u1", "name": "Alice", "age": 25});
db.add("users", "u1", &user).await?;

// Get a user
let fetched = db.get("users", "u1").await?.unwrap();
println!("Fetched user: {:?}", fetched);

// Update a field
db.update("users", "u1", "age", &json!(30)).await?;
let updated = db.get("users", "u1").await?.unwrap();
println!("Updated user: {:?}", updated);

// Delete a user
db.delete("users", "u1").await?;
let deleted = db.get("users", "u1").await?;
println!("Deleted? {:?}", deleted.is_none());

Ok(())

}

Using Transactions

Transactions allow multiple operations to be executed atomically:

use osunbitdb::{OsunbitDB, json};

#[tokio::main] async fn main() -> Result<(), Box> { let db = OsunbitDB::new(&["http://127.0.0.1:2379"]).await?;

// Start a transaction
let mut tx = db.transaction().await?;

// Add multiple fields
let user = json!({"id": "u2", "name": "Bob", "age": 28});
tx.add("users", "u2", &user).await?;

// Commit transaction to persist
tx.commit().await?;

// Read inside another transaction
let mut tx_read = db.transaction().await?;
let fetched = tx_read.get("users", "u2").await?.unwrap();
println!("Fetched in transaction: {:?}", fetched);
tx_read.rollback().await?; // rollback if only reading

// Update a field in transaction
let mut tx_update = db.transaction().await?;
tx_update.update("users", "u2", "age", &json!(29)).await?;
tx_update.commit().await?;

// Delete user
let mut tx_delete = db.transaction().await?;
tx_delete.delete("users", "u2").await?;
tx_delete.commit().await?;

Ok(())

}

Scanning Keys

You can scan a collection for keys with a prefix:

let users = db.collection("users"); let scanned = users.scan("u", 10).await?; for (key, value) in scanned { println!("Key: {}, Value: {:?}", key, value); }

Notes

Collections: Logical namespaces for keys (e.g., "users", "posts")

Firestore-style API: db.add, db.get, db.update, db.delete are all backed by transactions internally.

Transactions: Use db.transaction() when you need multiple operations to be atomic.

License

MIT OR Apache-2.0