mongod_derive | ||
src | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
README.md |
mongod
mongod is a rust crate for a model based database on top of MongoDB.
Usage
mongod
allows you to use structs as models
with data. it is build upon a MongoDB database. You need to pass a Connection URI for the database to use via the $DB_URI
environment variable.
Models
You can derive the Model
and Referencable
traits for your struct. This will provide you with functions like insert()
, delete()
, update()
, get()
, etc for your struct. Additionally you have to manually implement the Validate
trait which ensures a consistent valid state of your struct in order to never insert invalid data into the database.
use serde::{Deserialize, Serialize};
use mongod::Historic;
use mongod::Validate;
use mongod::Reference;
use mongod::derive::{Module, Referencable};
#[derive(Debug, Clone, Serialize, Deserialize, Module, Referencable)]
struct MyStruct {
_id: String,
name: String,
other: Option<Reference>,
}
impl Validate for MyStruct {
async fn validate(&self) -> bool {
true
}
}
This allows you to use your struct like this:
let a = MyStruct{
_id: "someid".to_string(),
name: "hello".to_string(),
other: None
};
a.insert().await;
a.update(serde_json::json!({"name": "bye"})).await.unwrap();
let new_a = MyStruct::get("someid");
Historic data
If you want certain fields to remember a history of changes you can use the Historic<T>
type.
This type will retain previous changes along with a timestamp when updates happen.
References
A Models field can be a reference to another model using the Reference
type.
let m = MyStruct::get("someid").await.unwrap();
// get a reference from model
// `reference()` is a convenience function and is exactly the same as the two references below
let myref = m.reference();
let sec_ref = Reference::new(MyStruct::collection_name(), "someid").await.unwrap();
let third_ref = Reference::new("my_struct", "someid").await.unwrap();
struct OtherStruct {
link: Reference
}
// store a reference
let other = OtherStruct{
link: myref
}
let m: MyStruct = other.link.get().await; // get back a model from reference
With the assert_reference_of!()
macro you can limit the models your reference can represent at validation. You can specify as many models as you want, but the reference must match one of them.
#[derive(Debug, Clone, Serialize, Deserialize, Module, Referencable)]
struct OtherStruct {
/* *** */
}
#[derive(Debug, Clone, Serialize, Deserialize, Module, Referencable)]
struct YetAnotherStruct {
/* *** */
}
impl Validate for MyStruct {
async fn validate(&self) -> bool {
if let Some(other) = self.other {
assert_reference_of!(other, OtherStruct, YetAnotherStruct);
}
true
}
}