Expand description
Daybreak
Daybreak was a Ruby Daybreak inspired single file Database. It has now since evolved into something else. Please check v1 for a more similar version.
This is a continuation of the Rustbreak project, which is now archived.
You will find an overview here in the docs, but to give you a more complete tale of how this is used please check the examples.
At its core, Daybreak is an attempt at making a configurable general-purpose store Database. It features the possibility of:
- Choosing what kind of Data is stored in it
- Which kind of Serialization is used for persistence
- Which kind of persistence is used
This means you can take any struct you can serialize and deserialize and stick it into this Database. It is then encoded with Ron, Yaml, JSON, Bincode, anything really that uses Serde operations!
There are three helper type aliases MemoryDatabase
, FileDatabase
,
and PathDatabase
, each backed by their respective backend.
The MemoryBackend
saves its data into a Vec<u8>
, which is not that
useful on its own, but is needed for compatibility with the rest of the
Library.
The FileDatabase
is a classical file based database. You give it a path
or a file, and it will use it as its storage. You still get to pick what
encoding it uses.
The PathDatabase
is very similar, but always requires a path for
creation. It features atomic saves, so that the old database contents won’t
be lost when panicing during the save. It should therefore be preferred to a
FileDatabase
.
Using the Database::with_deser
and Database::with_backend
one can
switch between the representations one needs. Even at runtime! However this
is only useful in a few scenarios.
If you have any questions feel free to ask at the main repo.
Quickstart
Add this to your Cargo.toml
:
[dependencies.rustbreak]
version = "2"
features = ["ron_enc"] # You can also use "yaml_enc" or "bin_enc"
use daybreak::{deser::Ron, MemoryDatabase};
let db = MemoryDatabase::<HashMap<u32, String>, Ron>::memory(HashMap::new())?;
println!("Writing to Database");
db.write(|db| {
db.insert(0, String::from("world"));
db.insert(1, String::from("bar"));
});
db.read(|db| {
// db.insert("foo".into(), String::from("bar"));
// The above line will not compile since we are only reading
println!("Hello: {:?}", db.get(&0));
})?;
Or alternatively:
use daybreak::{deser::Ron, MemoryDatabase};
let db = MemoryDatabase::<HashMap<u32, String>, Ron>::memory(HashMap::new())?;
println!("Writing to Database");
{
let mut data = db.borrow_data_mut()?;
data.insert(0, String::from("world"));
data.insert(1, String::from("bar"));
}
let data = db.borrow_data()?;
println!("Hello: {:?}", data.get(&0));
Error Handling
Handling errors in Daybreak is straightforward. Every Result
has as its
fail case as error::Error
. This means that you can now either
continue bubbling up said error case, or handle it yourself.
use daybreak::{deser::Ron, error::Error, MemoryDatabase};
let db = match MemoryDatabase::<usize, Ron>::memory(0) {
Ok(db) => db,
Err(e) => {
// Do something with `e` here
std::process::exit(1);
}
};
Panics
This Database implementation uses RwLock
and Mutex
under the hood.
If either the closures given to Database::write
or any of the Backend
implementation methods panic the respective objects are then poisoned. This
means that you cannot panic under any circumstances in your closures or
custom backends.
Currently there is no way to recover from a poisoned Database
other than
re-creating it.
Examples
There are several more or less in-depth example programs you can check out! Check them out here: Examples
config.rs
shows you how a possible configuration file could be managed with rustbreakfull.rs
shows you how the database can be used as a hashmap storeswitching.rs
show you how you can easily swap out different parts of the Database Note: To run this example you need to enable the featureyaml
like so:cargo run --example switching --features yaml
server/
is a fully fledged example app written with the Rocket framework to make a form of micro-blogging website. You will need rust nightly to start it.
Features
Daybreak comes with following optional features:
ron_enc
which enables the Ron de/serializationyaml_enc
which enables the Yaml de/serializationbin_enc
which enables the Bincode de/serialization- ‘mmap’ whhich enables memory map backend.
Enable them in your Cargo.toml
file to use them. You can
safely have them all turned on per-default.
Re-exports
pub use crate::deser::DeSerializer;
pub use crate::error::*;
Modules
Structs
Type Definitions
Vec<u8>
).