[−][src]Crate oxidizer
Oxidizer
A simple orm based on tokio-postgres and refinery
#[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, } pub enum ConvertError { Error } impl std::fmt::Display for ConvertError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("Error trying to convert") } } impl TryFrom<&MyEnum> for i32 { type Error = ConvertError; fn try_from(v: &MyEnum) -> Result<Self, Self::Error> { match v { MyEnum::Item1 => Ok(0), MyEnum::Item2 => Ok(1), } } } impl TryFrom<i32> for MyEnum { type Error = ConvertError; fn try_from(v: i32) -> Result<Self, Self::Error> { match v { 0 => Ok(MyEnum::Item1), 1 => Ok(MyEnum::Item2), _ => Err(ConvertError::Error), } } } #[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 TryFrom
trait functions to convert between the
actual type and the overriden type. The error type from the TryFrom
trait must implement the std::fmt::Display
trait
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:
#[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).
#[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):
#[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 |
Traits
TryFrom | Simple and safe type conversions that may fail in a controlled
way under some circumstances. It is the reciprocal of |
Attribute Macros
async_trait | Re-export of async_trait::async_trait |
Derive Macros
Entity | Entity derive macro |