[][src]Crate oxidizer

Oxidizer

A simple orm based on tokio-postgres and refinery

This example is not tested
#[async_trait]
pub trait Entity: Sized {
    async fn save(&mut self, db: &DB) -> DBResult<bool>;
    async fn delete(&mut self, db: &DB) -> DBResult<bool>;

    fn from_row(row: &Row) -> Self;
    fn create_migration() -> DBResult<Migration>;
    fn get_table_name() -> String;

    async fn find(db: &DB, query: &str, params: &'_ [&'_ (dyn ToSql + Sync)]) -> DBResult<Vec<Self>>;
    async fn first(db: &DB, query: &str, params: &'_ [&'_ (dyn ToSql + Sync)]) -> DBResult<Option<Self>>;
}
use oxidizer::*;
use chrono::{DateTime, Utc};

#[derive(Entity)]
#[derive(Default)]
pub struct MyEntity {
    #[primary_key]
    id: i32,

    name: String,

    #[indexed]
    integer: i32,
    integer64: i64,

    float: f32,
    double: f64,

    boolean: bool,

    datetime: Option<DateTime<Utc>>,
}

#[tokio::test]
async fn test_my_entity() {
    let uri = "postgres://postgres:alkje2lkaj2e@db/postgres";
    let max_open = 50; // mobc
    let ca_file: Option<&str> = None;
    let db = DB::connect(&uri, max_open, ca_file).await.unwrap();

    db.migrate_tables(&[MyEntity::create_migration().unwrap()]).await.unwrap();

    let mut entity = MyEntity::default();
    let creating = entity.save(&db).await.unwrap();
    assert_eq!(creating, true);
}

Attributes

Derive attributes can be used to create indexes, change the default table name and create reverse relation accessors

#[primary_key]

Required Field attribute used to mark the field as the primary key, this will make the field autoincrement

use oxidizer::*;
#[derive(Entity)]
struct Entity {
    #[primary_key]
    id: i32
}

#[indexed]

Make the specified field indexed in the db

use oxidizer::*;
#[derive(Entity)]
struct Entity {
    #[primary_key]
    id: i32,
    #[indexed]
    name: String,
}

#[relation]

See Relations

#[has_many]

See Relations

#entity

General settings for the entity struct

table_name: String;

Allows one to change the table name of the entity

use oxidizer::*;
#[derive(Entity)]
#[entity(table_name="custom_table_name")]
struct Entity {
    #[primary_key]
    id: i32
}

#[index]

Creates a custom index/constraint on one or more column

use oxidizer::*;
#[derive(Default, Entity)]
#[index(name="myindex", columns="name, email", unique)]
struct MyEntity {
    #[primary_key]
    id: i32,

    name: String,
    email: String,
}

Relations

#[relation]

Relations can be created using the relation attribute as in the example:

use oxidizer::*;
#[derive(Entity)]
struct Entity {
    #[primary_key]
    id: i32,
}

#[derive(Entity)]
struct TestRelation {
    #[primary_key]
    id: i32,
    device_id: String,

    #[relation(model="Entity", key="id")]
    entity_id: i32,
}

This will implement for TestRelation the following generated trait:

This example is not tested
#[oxidizer::async_trait]
pub trait __AccessorTestRelationToEntity {
    async fn get_test_entity(&self, db: &oxidizer::db::DB) -> oxidizer::db::DBResult<Entity>;
    async fn set_test_entity(&mut self, db: &oxidizer::db::DB, v: &Entity) -> oxidizer::db::DBResult<()>;
}

#[has_many] 1-to-many or many-to-many relations can be achieved using the has_many attribute

basic (1-to-many)

use oxidizer::*;

#[derive(Entity)]
#[derive(Default)]
#[has_many(model="TargetEntity", field="entity_id")]
pub struct Entity {
    #[primary_key]
    id: i32,
    name: String
}

#[derive(Default, Entity)]
pub struct TargetEntity {
    #[primary_key]
    id: i32,
    #[relation(model="Entity", key="id")]
    entity_id: i32
}

This will create helper functions to access all the TargetEntity that Entity has. This is what the generated trait and implementation looks like (implementaion is also generated).

This example is not tested
#[oxidizer::async_trait]
pub trait __AccessorHasManyTargetEntityToEntity {
    async fn get_all_test_entity(&self, db: &oxidizer::db::DB) -> oxidizer::db::DBResult<Vec<Entity>>;
}

With a through table (many-to-many)

use oxidizer::*;

#[derive(Entity)]
#[derive(Default)]
pub struct Entity {
    #[primary_key]
    id: i32,
    name: String
}

#[derive(Default, Entity)]
#[has_many(model="Entity", field="entity_id", through="TestManyToMany")]
pub struct TargetEntity {
    #[primary_key]
    id: i32,
}

#[derive(Default, Entity)]
pub struct TestManyToMany {
    #[primary_key]
    id: i32,

    #[relation(model="TargetEntity", key="id")]
    target_id: i32,

    #[relation(model="Entity", key="id")]
    entity_id: i32,
}

This will create helper functions to access the related entities. This is what the generated trait looks like (implementaion is also generated):

This example is not tested
#[oxidizer::async_trait]
pub trait __AccessorHasManyTargetEntityToEntity {
    async fn get_all_test_entity(&self, db: &oxidizer::db::DB) -> oxidizer::db::DBResult<Vec<TestManyToMany>>;
}

Re-exports

pub use db::*;
pub use entity::*;
pub use tokio_postgres;

Modules

db
db_types

Types.

entity
migration

Migrations

types

Types constructor module

Macros

create_migration_module

Creates a new migration module

include_migration_mods

Imports Rust migration modules with migrations and inserts a function called runner that when called returns a Runner instance with the collected migration modules.

Attribute Macros

async_trait

Re-export of async_trait::async_trait

Derive Macros

Entity

Entity derive macro