[][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,
}

#[field_ignore]

Ignores the specified field. The field type must implement the Default trait.

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

    name: String,
    #[field_ignore]
    email: String,
}

#[custom_type]

The custom type attribute lets you override the default type provided by oxidizer.

use oxidizer::*;
pub enum MyEnum {
    Item1,
    Item2,
}

impl std::convert::From<&MyEnum> for i32 {
    fn from(v: &MyEnum) -> Self {
        match v {
            MyEnum::Item1 => 0,
            MyEnum::Item2 => 1,
        }
    }
}

impl std::convert::From<i32> for MyEnum {
    fn from(v: i32) -> Self {
        match v {
            0 => MyEnum::Item1,
            1 => MyEnum::Item2,
            _ => unimplemented!(),
        }
    }
}

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

    #[custom_type(ty = "i32")]
    my_enum: MyEnum,
}

The custom type requires you to explicity implement the related From functions to convert between the actual type and the overriden type

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

Attribute Macros

async_trait

Re-export of async_trait::async_trait

Derive Macros

Entity

Entity derive macro