No description
Find a file
2024-07-18 14:10:29 +02:00
mongod_derive update 2024-07-18 14:10:29 +02:00
src update 2024-07-18 14:10:29 +02:00
.gitignore update 2024-07-18 14:10:29 +02:00
Cargo.lock add derive + docs 2024-07-17 16:49:35 +02:00
Cargo.toml add derive + docs 2024-07-17 16:49:35 +02:00
README.md add derive + docs 2024-07-17 16:49:35 +02:00

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
    }
}