Skip to content

Commit

Permalink
Merge pull request #34 from SeaQL/ss/bakery
Browse files Browse the repository at this point in the history
Design and implement the Bakery Chain schema
  • Loading branch information
tyt2y3 authored Jul 9, 2021
2 parents 82992aa + 550d9a7 commit 883bd16
Show file tree
Hide file tree
Showing 18 changed files with 1,336 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ async-stream = { version = "^0.3" }
chrono = { version = "^0", optional = true }
futures = { version = "^0.3" }
futures-util = { version = "^0.3" }
rust_decimal = { version = "^1", optional = true }
sea-query = { version = "^0.12" }
sea-orm-macros = { path = "sea-orm-macros", optional = true }
serde = { version = "^1.0", features = [ "derive" ] }
Expand All @@ -45,6 +46,7 @@ serde_json = { version = "^1", optional = true }
[dev-dependencies]
async-std = { version = "^1.9", features = [ "attributes" ] }
maplit = { version = "^1" }
rust_decimal_macros = { version = "^1" }
sea-orm = { path = ".", features = ["sqlx-sqlite", "sqlx-json", "sqlx-chrono", "sqlx-decimal", "runtime-async-std-native-tls"] }

[features]
Expand All @@ -54,7 +56,7 @@ macros = [ "sea-orm-macros" ]
mock = []
with-json = [ "serde_json", "sea-query/with-json" ]
with-chrono = [ "chrono", "sea-query/with-chrono" ]
with-rust_decimal = [ "sea-query/with-rust_decimal" ]
with-rust_decimal = [ "rust_decimal", "sea-query/with-rust_decimal" ]
sqlx-dep = [ "sqlx" ]
sqlx-json = [ "sqlx/json", "with-json" ]
sqlx-chrono = [ "sqlx/chrono", "with-chrono" ]
Expand Down
56 changes: 56 additions & 0 deletions src/executor/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,59 @@ try_getable_mysql!(u64);
try_getable_all!(f32);
try_getable_all!(f64);
try_getable_all!(String);

#[cfg(feature = "with-rust_decimal")]
use rust_decimal::Decimal;

#[cfg(feature = "with-rust_decimal")]
impl TryGetable for Decimal {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
row.try_get(column.as_str()).map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row;
let val: f64 = row.try_get(column.as_str()).map_err(crate::sqlx_error_to_query_err)?;
use rust_decimal::prelude::FromPrimitive;
Decimal::from_f64(val).ok_or_else(|| DbErr::Query("Failed to convert f64 into Decimal".to_owned()))
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
}
}
}

#[cfg(feature = "with-rust_decimal")]
impl TryGetable for Option<Decimal> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
match row.try_get(column.as_str()) {
Ok(v) => Ok(Some(v)),
Err(_) => Ok(None),
}
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => {
let result: Result<Decimal, _> = TryGetable::try_get(res, pre, col);
match result {
Ok(v) => Ok(Some(v)),
Err(_) => Ok(None),
}
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) {
Ok(v) => Ok(Some(v)),
Err(_) => Ok(None),
},
}
}
}
81 changes: 81 additions & 0 deletions tests/bakery_chain/baker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use sea_orm::entity::prelude::*;

#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;

impl EntityName for Entity {
fn table_name(&self) -> &str {
"baker"
}
}

#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
pub struct Model {
pub id: i32,
pub name: String,
pub bakery_id: Option<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
Name,
BakeryId,
}

#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}

impl PrimaryKeyTrait for PrimaryKey {
fn auto_increment() -> bool {
true
}
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
Bakery,
}

impl ColumnTrait for Column {
type EntityName = Entity;

fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::Name => ColumnType::String(None).def(),
Self::BakeryId => ColumnType::Integer.def(),
}
}
}

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
.from(Column::BakeryId)
.to(super::bakery::Column::Id)
.into(),
}
}
}

impl Related<super::bakery::Entity> for Entity {
fn to() -> RelationDef {
Relation::Bakery.def()
}
}

impl Related<super::cake::Entity> for Entity {
fn to() -> RelationDef {
super::cakes_bakers::Relation::Cake.def()
}

fn via() -> Option<RelationDef> {
Some(super::cakes_bakers::Relation::Baker.def().rev())
}
}

impl ActiveModelBehavior for ActiveModel {}
84 changes: 84 additions & 0 deletions tests/bakery_chain/bakery.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use sea_orm::entity::prelude::*;

#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;

impl EntityName for Entity {
fn table_name(&self) -> &str {
"bakery"
}
}

#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
pub struct Model {
pub id: i32,
pub name: String,
pub profit_margin: f64,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
Name,
ProfitMargin,
}

#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}

impl PrimaryKeyTrait for PrimaryKey {
fn auto_increment() -> bool {
true
}
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
Baker,
Order,
Cake,
}

impl ColumnTrait for Column {
type EntityName = Entity;

fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::Name => ColumnType::String(None).def(),
Self::ProfitMargin => ColumnType::Float.def(),
}
}
}

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::Baker => Entity::has_many(super::baker::Entity).into(),
Self::Order => Entity::has_many(super::order::Entity).into(),
Self::Cake => Entity::has_many(super::cake::Entity).into(),
}
}
}

impl Related<super::baker::Entity> for Entity {
fn to() -> RelationDef {
Relation::Baker.def()
}
}

impl Related<super::order::Entity> for Entity {
fn to() -> RelationDef {
Relation::Order.def()
}
}

impl Related<super::cake::Entity> for Entity {
fn to() -> RelationDef {
Relation::Cake.def()
}
}

impl ActiveModelBehavior for ActiveModel {}
1 change: 1 addition & 0 deletions tests/bakery_chain/bakery_chain_erd.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="Electron" modified="2021-06-30T11:15:47.471Z" agent="5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="CL5AmeQl6dz-rdIIukNg" version="14.6.13" type="device"><diagram id="R2lEEEUBdFMjLlhIrx00" name="Page-1">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</diagram></mxfile>
Binary file added tests/bakery_chain/bakery_chain_erd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 96 additions & 0 deletions tests/bakery_chain/cake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use rust_decimal::prelude::*;
use sea_orm::entity::prelude::*;

#[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity;

impl EntityName for Entity {
fn table_name(&self) -> &str {
"cake"
}
}

#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
pub struct Model {
pub id: i32,
pub name: String,
pub price: Decimal,
pub bakery_id: Option<i32>,
pub gluten_free: bool,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
pub enum Column {
Id,
Name,
Price,
BakeryId,
GlutenFree,
}

#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
pub enum PrimaryKey {
Id,
}

impl PrimaryKeyTrait for PrimaryKey {
fn auto_increment() -> bool {
true
}
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
Bakery,
Lineitem,
}

impl ColumnTrait for Column {
type EntityName = Entity;

fn def(&self) -> ColumnDef {
match self {
Self::Id => ColumnType::Integer.def(),
Self::Name => ColumnType::String(None).def(),
Self::Price => ColumnType::Decimal(Some((19, 4))).def(),
Self::BakeryId => ColumnType::Integer.def(),
Self::GlutenFree => ColumnType::Boolean.def(),
}
}
}

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
.from(Column::BakeryId)
.to(super::bakery::Column::Id)
.into(),
Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(),
}
}
}

impl Related<super::bakery::Entity> for Entity {
fn to() -> RelationDef {
Relation::Bakery.def()
}
}

impl Related<super::baker::Entity> for Entity {
fn to() -> RelationDef {
super::cakes_bakers::Relation::Baker.def()
}

fn via() -> Option<RelationDef> {
Some(super::cakes_bakers::Relation::Cake.def().rev())
}
}

impl Related<super::lineitem::Entity> for Entity {
fn to() -> RelationDef {
Relation::Lineitem.def()
}
}

impl ActiveModelBehavior for ActiveModel {}
Loading

0 comments on commit 883bd16

Please sign in to comment.