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 awesome 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
* arm-linux-androideabi
(Android)
* aarch64-unknown-linux-gnu
(ARM)
* arm-unknown-linux-gnueabihf
* mips-unknown-linux-gnu
(MIPS)
* x86_64-apple-ios
(iOS)
Here are a couple of simple examples to get you started, but you should check out the docs for more details.
```rust use jammdb::{DB, Data, Error};
fn main() -> Result<(), Error> { { // open a new database file let mut db = DB::open("my-database.db")?;
// open a writable transaction so we can make changes
let mut 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(b"Kanan", b"Jarrus")?;
names_bucket.put(b"Ezra", b"Bridger")?;
// commit the changes so they are saved to disk
tx.commit()?;
} { // open the existing database file let mut db = DB::open("my-database.db")?; // open a read-only transaction to get the data let mut tx = db.tx(true)?; // get the bucket we created in the last transaction let namesbucket = tx.getbucket("names")?; // get the key/ value pair we inserted into the bucket if let Some(Data::KeyValue(kv)) = namesbucket.get(b"Kanan") { asserteq!(kv.value(), b"Jarrus"); } } Ok(()) } ```
```rust use jammdb::{DB, Data, Error}; use serde::{Deserialize, Serialize}; // use rmps crate to serialize structs using the MessagePack format use rmp_serde::{Deserializer, Serializer};
struct User { username: String, password: String, }
fn main() -> Result<(), Error> { let user = User{ username: "my-user".tostring(), password: "my-password".tostring(), }; { // open a new database file and start a writable transaction let mut db = DB::open("my-database.db")?; let mut 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(b"user1", user_bytes)?;
// commit the changes so they are saved to disk
tx.commit()?;
} { // open the existing database file let mut db = DB::open("my-database.db")?; // open a read-only transaction to get the data let mut tx = db.tx(true)?; // get the bucket we created in the last transaction let usersbucket = tx.getbucket("users")?; // get the key / value pair we inserted into the bucket if let Some(Data::KeyValue(kv)) = usersbucket.get(b"user1") { // deserialize into a user struct let dbuser: User = rmpserde::fromslice(kv.value()).unwrap(); asserteq!(dbuser, user); } } Ok(()) } ```
Available under both the Apache License or the MIT license.