Embedded (Library)
Redliteâs primary use case is as an embedded library. No separate server process neededâjust add it to your Cargo.toml and start using it.
Opening a Database
Section titled âOpening a Databaseâuse redlite::Db;
// Persistent storage (creates file if doesn't exist)let db = Db::open("mydata.db")?;
// In-memory (great for testing)let db = Db::open_memory()?;String Operations
Section titled âString OperationsâSET and GET
Section titled âSET and GETâuse std::time::Duration;
// Basic set (no expiration)db.set("user:1:name", b"Alice", None)?;
// Get returns Option<Vec<u8>>let name = db.get("user:1:name")?;assert_eq!(name, Some(b"Alice".to_vec()));
// Non-existent keys return Nonelet missing = db.get("nonexistent")?;assert_eq!(missing, None);With TTL (Time-To-Live)
Section titled âWith TTL (Time-To-Live)âuse std::time::Duration;
// Expires in 60 secondsdb.set("session:abc", b"user_data", Some(Duration::from_secs(60)))?;
// Expires in 100 millisecondsdb.set("temp", b"quick", Some(Duration::from_millis(100)))?;Conditional SET with Options
Section titled âConditional SET with Optionsâuse redlite::SetOptions;
// NX - Only set if key does NOT existlet opts = SetOptions::new().nx();db.set_opts("counter", b"0", opts)?; // Sets valuedb.set_opts("counter", b"1", opts)?; // Does nothing, key exists
// XX - Only set if key DOES existlet opts = SetOptions::new().xx();db.set_opts("counter", b"10", opts)?; // Updates existing keydb.set_opts("new_key", b"0", opts)?; // Does nothing, key doesn't exist
// Combine with TTLlet opts = SetOptions::new() .nx() .ex(Duration::from_secs(300));db.set_opts("lock:resource", b"owner_id", opts)?;Deleting Keys
Section titled âDeleting Keysâ// Delete single keydb.del(&["user:1:name"])?;
// Delete multiple keys at oncedb.del(&["key1", "key2", "key3"])?;Multiple Databases
Section titled âMultiple DatabasesâLike Redis, Redlite supports multiple logical databases (0-15 by default):
// Default is database 0db.set("key", b"in db 0", None)?;
// Switch to database 1db.select(1)?;db.set("key", b"in db 1", None)?;
// Keys are isolated between databasesdb.select(0)?;assert_eq!(db.get("key")?, Some(b"in db 0".to_vec()));Error Handling
Section titled âError Handlingâuse redlite::{Db, KvError};
fn example() -> redlite::Result<()> { let db = Db::open("mydata.db")?;
match db.get("key") { Ok(Some(value)) => println!("Found: {:?}", value), Ok(None) => println!("Key not found"), Err(e) => eprintln!("Error: {}", e), }
Ok(())}Thread Safety
Section titled âThread SafetyâThe Db struct is thread-safe and can be shared across threads using Arc:
use std::sync::Arc;use std::thread;
let db = Arc::new(Db::open("mydata.db")?);
let handles: Vec<_> = (0..4).map(|i| { let db = Arc::clone(&db); thread::spawn(move || { db.set(&format!("key:{}", i), b"value", None).unwrap(); })}).collect();
for handle in handles { handle.join().unwrap();}SQLite Advantages
Section titled âSQLite AdvantagesâBecause Redlite uses SQLite under the hood, you get:
- ACID transactions - Data integrity guaranteed
- WAL mode - Concurrent readers with single writer
- Durability - Survives crashes and power failures
- Zero configuration - No tuning required
- Portability - Single file, easy to backup/move