jammdb
is an embedded, single-file database that allows you to store key /
value pairs as bytes.
It started life as a Rust port of Ben Johnson's BoltDB, which was inspired by Howard Chu's LMDB, so please check out both of these awesome projects!
jammdb
offers ACID compliance,
serializable and
isolated
transactions, with multiple lock-free readers and a single concurrent writer.
The data is organized in a
single level
B+ tree so random and sequential
reads are very fast. The underlying file is
memory mapped, so reads
require no additional memory allocation.
jammdb
is continuously cross-compiled and tested on the following platforms:
x86_64-unknown-linux-gnu
(Linux)i686-unknown-linux-gnu
x86_64-unknown-linux-musl
(Linux MUSL)x86_64-apple-darwin
(OSX)x86_64-pc-windows-msvc
(Windows)i686-pc-windows-msvc
x86_64-pc-windows-gnu
i686-pc-windows-gnu
Here are a couple of simple examples to get you started, but you should check out the docs for more details.
use jammdb::{DB, Data, Error};
fn main() -> Result<(), Error> {
{
// open a new database file
let db = DB::open("my-database.db")?;
// open a writable transaction so we can make changes
let tx = db.tx(true)?;
// create a bucket to store a map of first names to last names
let names_bucket = tx.create_bucket("names")?;
names_bucket.put("Kanan", "Jarrus")?;
names_bucket.put("Ezra", "Bridger")?;
// commit the changes so they are saved to disk
tx.commit()?;
}
{
// open the existing database file
let db = DB::open("my-database.db")?;
// open a read-only transaction to get the data
let tx = db.tx(false)?;
// get the bucket we created in the last transaction
let names_bucket = tx.get_bucket("names")?;
// get the key/ value pair we inserted into the bucket
if let Some(data) = names_bucket.get("Kanan") {
assert!(data.is_kv());
assert_eq!(data.kv().value(), b"Jarrus");
}
}
Ok(())
}
use jammdb::{DB, Data, Error};
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct User {
username: String,
password: String,
}
fn main() -> Result<(), Error> {
let user = User{
username: "my-user".to_string(),
password: "my-password".to_string(),
};
{
// open a new database file and start a writable transaction
let db = DB::open("my-database.db")?;
let tx = db.tx(true)?;
// create a bucket to store users
let users_bucket = tx.create_bucket("users")?;
// serialize struct to bytes and store in bucket
let user_bytes = rmp_serde::to_vec(&user).unwrap();
users_bucket.put("user1", user_bytes)?;
// commit the changes so they are saved to disk
tx.commit()?;
}
{
// open the existing database file
let db = DB::open("my-database.db")?;
// open a read-only transaction to get the data
let tx = db.tx(false)?;
// get the bucket we created in the last transaction
let users_bucket = tx.get_bucket("users")?;
// get the key / value pair we inserted into the bucket
if let Some(data) = users_bucket.get("user1") {
if data.is_kv() {
let kv = data.kv();
// deserialize into a user struct
let db_user: User = rmp_serde::from_slice(kv.value()).unwrap();
assert_eq!(db_user, user);
}
}
}
Ok(())
}
Currently 1.63
Available under both the Apache License or the MIT license.