Tiny ergonomic rust database
src | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
README.md |
FeoxDB
A tiny rust-native kv oriented database, with columnar indexes.
Under the hood it uses:
Like fjall
it's thread-safe, but not multi-process safe.
Status
The database is still very experimental. Things that are needed for production workloads:
- Expose the transactional api.
- Use facet to handle auto-migrations (and/or prevent usage without migration)
- Add hooks for indexes (maybe combine with transactional api?)
- Add shared indexes (queued writes, instant read across threads)
- Improve key ergonomics (discourage incompatible key types)
Usage
- Define a model:
use rkyv::{Archive, Serialize, Deserialize}
use facet::Facet;
#[derive(PartialEq, Debug, Archive, Serialize, Deserialize, Facet)]
pub struct User {
pub email: String,
pub password_hash: u128,
pub role: ulid::Ulid,
}
// TODO: This should either be part of `Table::new()` (multi-tables) or derived (singletons)
impl DatabaseModel for User {
fn partition() -> &'static str {
"user"
}
}
- Use the database:
let table = Table::<User>::new();
let user_id = Ulid::new();
let user = User { email: "example@example.com".to_string(), password_hash: 0u128, role: Ulid::new() };
table.set_one(user_id, &user).unwrap();
// Note entry values are by default `rkyv::Archived`
let user_entry = table.get_one(user_id).unwrap();
let user_retrieved = user_entry.unarchived();
assert_eq!(Ulid::try_from(user_id.key).unwrap(), user_id);
assert_eq!(user_retrieved, user);
- Scale with indexes:
// TODO: add index update strategy (hooks w/ deferred option)
let index = CuckooUniqueIndex::<User, String>::new_empty("email").rebuild();
let user_id = index.get("example@example.com");
assert_eq!(Ulid::try_from(user_id.key).unwrap(), user_id);