Merge branch 'master' into linked-api
This commit is contained in:
commit
8cde6e46e4
@ -32,7 +32,7 @@ futures = { version = "^0.3" }
|
|||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "^0.3" }
|
||||||
rust_decimal = { version = "^1", optional = true }
|
rust_decimal = { version = "^1", optional = true }
|
||||||
sea-orm-macros = { version = "^0.1.1", optional = true }
|
sea-orm-macros = { version = "^0.1.1", optional = true }
|
||||||
sea-query = { version = "^0.15", features = ["thread-safe"] }
|
sea-query = { version = "^0.16", features = ["thread-safe"] }
|
||||||
sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
|
sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
sqlx = { version = "^0.5", optional = true }
|
sqlx = { version = "^0.5", optional = true }
|
||||||
@ -50,6 +50,7 @@ actix-rt = { version = "2.2.0" }
|
|||||||
maplit = { version = "^1" }
|
maplit = { version = "^1" }
|
||||||
rust_decimal_macros = { version = "^1" }
|
rust_decimal_macros = { version = "^1" }
|
||||||
sea-orm = { path = ".", features = ["debug-print"] }
|
sea-orm = { path = ".", features = ["debug-print"] }
|
||||||
|
pretty_assertions = { version = "^0.7" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
debug-print = []
|
debug-print = []
|
||||||
|
@ -55,21 +55,21 @@ pub trait EntityTrait: EntityName {
|
|||||||
where
|
where
|
||||||
R: EntityTrait,
|
R: EntityTrait,
|
||||||
{
|
{
|
||||||
RelationBuilder::new(RelationType::HasOne, Self::default(), related)
|
RelationBuilder::new(RelationType::HasOne, Self::default(), related, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_one<R>(_: R) -> RelationBuilder<Self, R>
|
fn has_one<R>(_: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
R: EntityTrait + Related<Self>,
|
R: EntityTrait + Related<Self>,
|
||||||
{
|
{
|
||||||
RelationBuilder::from_rel(RelationType::HasOne, R::to().rev())
|
RelationBuilder::from_rel(RelationType::HasOne, R::to().rev(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_many<R>(_: R) -> RelationBuilder<Self, R>
|
fn has_many<R>(_: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
R: EntityTrait + Related<Self>,
|
R: EntityTrait + Related<Self>,
|
||||||
{
|
{
|
||||||
RelationBuilder::from_rel(RelationType::HasMany, R::to().rev())
|
RelationBuilder::from_rel(RelationType::HasMany, R::to().rev(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct select statement to find one / all models
|
/// Construct select statement to find one / all models
|
||||||
|
@ -6,6 +6,7 @@ mod model;
|
|||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
mod primary_key;
|
mod primary_key;
|
||||||
mod relation;
|
mod relation;
|
||||||
|
mod schema;
|
||||||
|
|
||||||
pub use active_model::*;
|
pub use active_model::*;
|
||||||
pub use base_entity::*;
|
pub use base_entity::*;
|
||||||
@ -15,3 +16,4 @@ pub use model::*;
|
|||||||
// pub use prelude::*;
|
// pub use prelude::*;
|
||||||
pub use primary_key::*;
|
pub use primary_key::*;
|
||||||
pub use relation::*;
|
pub use relation::*;
|
||||||
|
pub use schema::*;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||||
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, Linked,
|
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden,
|
||||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related,
|
IdenStatic, Linked, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult,
|
||||||
RelationDef, RelationTrait, Select, Value,
|
Related, RelationDef, RelationTrait, Select, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "with-json")]
|
#[cfg(feature = "with-json")]
|
||||||
|
@ -9,6 +9,8 @@ pub enum RelationType {
|
|||||||
HasMany,
|
HasMany,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ForeignKeyAction = sea_query::ForeignKeyAction;
|
||||||
|
|
||||||
pub trait RelationTrait: Iterable + Debug + 'static {
|
pub trait RelationTrait: Iterable + Debug + 'static {
|
||||||
fn def(&self) -> RelationDef;
|
fn def(&self) -> RelationDef;
|
||||||
}
|
}
|
||||||
@ -50,6 +52,9 @@ pub struct RelationDef {
|
|||||||
pub to_tbl: TableRef,
|
pub to_tbl: TableRef,
|
||||||
pub from_col: Identity,
|
pub from_col: Identity,
|
||||||
pub to_col: Identity,
|
pub to_col: Identity,
|
||||||
|
pub is_owner: bool,
|
||||||
|
pub on_delete: Option<ForeignKeyAction>,
|
||||||
|
pub on_update: Option<ForeignKeyAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RelationBuilder<E, R>
|
pub struct RelationBuilder<E, R>
|
||||||
@ -63,6 +68,9 @@ where
|
|||||||
to_tbl: TableRef,
|
to_tbl: TableRef,
|
||||||
from_col: Option<Identity>,
|
from_col: Option<Identity>,
|
||||||
to_col: Option<Identity>,
|
to_col: Option<Identity>,
|
||||||
|
is_owner: bool,
|
||||||
|
on_delete: Option<ForeignKeyAction>,
|
||||||
|
on_update: Option<ForeignKeyAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelationDef {
|
impl RelationDef {
|
||||||
@ -74,6 +82,9 @@ impl RelationDef {
|
|||||||
to_tbl: self.from_tbl,
|
to_tbl: self.from_tbl,
|
||||||
from_col: self.to_col,
|
from_col: self.to_col,
|
||||||
to_col: self.from_col,
|
to_col: self.from_col,
|
||||||
|
is_owner: !self.is_owner,
|
||||||
|
on_delete: self.on_delete,
|
||||||
|
on_update: self.on_update,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +94,7 @@ where
|
|||||||
E: EntityTrait,
|
E: EntityTrait,
|
||||||
R: EntityTrait,
|
R: EntityTrait,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(rel_type: RelationType, from: E, to: R) -> Self {
|
pub(crate) fn new(rel_type: RelationType, from: E, to: R, is_owner: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
entities: PhantomData,
|
entities: PhantomData,
|
||||||
rel_type,
|
rel_type,
|
||||||
@ -91,10 +102,13 @@ where
|
|||||||
to_tbl: to.table_ref(),
|
to_tbl: to.table_ref(),
|
||||||
from_col: None,
|
from_col: None,
|
||||||
to_col: None,
|
to_col: None,
|
||||||
|
is_owner,
|
||||||
|
on_delete: None,
|
||||||
|
on_update: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_rel(rel_type: RelationType, rel: RelationDef) -> Self {
|
pub(crate) fn from_rel(rel_type: RelationType, rel: RelationDef, is_owner: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
entities: PhantomData,
|
entities: PhantomData,
|
||||||
rel_type,
|
rel_type,
|
||||||
@ -102,6 +116,9 @@ where
|
|||||||
to_tbl: rel.to_tbl,
|
to_tbl: rel.to_tbl,
|
||||||
from_col: Some(rel.from_col),
|
from_col: Some(rel.from_col),
|
||||||
to_col: Some(rel.to_col),
|
to_col: Some(rel.to_col),
|
||||||
|
is_owner,
|
||||||
|
on_delete: None,
|
||||||
|
on_update: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +137,16 @@ where
|
|||||||
self.to_col = Some(identifier.identity_of());
|
self.to_col = Some(identifier.identity_of());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_delete(mut self, action: ForeignKeyAction) -> Self {
|
||||||
|
self.on_delete = Some(action);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_update(mut self, action: ForeignKeyAction) -> Self {
|
||||||
|
self.on_update = Some(action);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, R> From<RelationBuilder<E, R>> for RelationDef
|
impl<E, R> From<RelationBuilder<E, R>> for RelationDef
|
||||||
@ -134,6 +161,9 @@ where
|
|||||||
to_tbl: b.to_tbl,
|
to_tbl: b.to_tbl,
|
||||||
from_col: b.from_col.unwrap(),
|
from_col: b.from_col.unwrap(),
|
||||||
to_col: b.to_col.unwrap(),
|
to_col: b.to_col.unwrap(),
|
||||||
|
is_owner: b.is_owner,
|
||||||
|
on_delete: b.on_delete,
|
||||||
|
on_update: b.on_update,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
161
src/entity/schema.rs
Normal file
161
src/entity/schema.rs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
use crate::{
|
||||||
|
unpack_table_ref, ColumnTrait, EntityTrait, Identity, Iterable, PrimaryKeyToColumn,
|
||||||
|
PrimaryKeyTrait, RelationTrait,
|
||||||
|
};
|
||||||
|
use sea_query::{ColumnDef, ForeignKeyCreateStatement, Iden, Index, TableCreateStatement};
|
||||||
|
|
||||||
|
pub fn entity_to_table_create_statement<E>(entity: E) -> TableCreateStatement
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
let mut stmt = TableCreateStatement::new();
|
||||||
|
|
||||||
|
for column in E::Column::iter() {
|
||||||
|
let orm_column_def = column.def();
|
||||||
|
let types = orm_column_def.col_type.into();
|
||||||
|
let mut column_def = ColumnDef::new_with_type(column, types);
|
||||||
|
if !orm_column_def.null {
|
||||||
|
column_def.not_null();
|
||||||
|
}
|
||||||
|
if orm_column_def.unique {
|
||||||
|
column_def.unique_key();
|
||||||
|
}
|
||||||
|
for primary_key in E::PrimaryKey::iter() {
|
||||||
|
if column.to_string() == primary_key.into_column().to_string()
|
||||||
|
&& E::PrimaryKey::auto_increment()
|
||||||
|
{
|
||||||
|
column_def.auto_increment();
|
||||||
|
if E::PrimaryKey::iter().count() == 1 {
|
||||||
|
column_def.primary_key();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if orm_column_def.indexed {
|
||||||
|
stmt.index(
|
||||||
|
Index::create()
|
||||||
|
.name(&format!(
|
||||||
|
"idx-{}-{}",
|
||||||
|
entity.to_string(),
|
||||||
|
column.to_string()
|
||||||
|
))
|
||||||
|
.table(entity)
|
||||||
|
.col(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
stmt.col(&mut column_def);
|
||||||
|
}
|
||||||
|
|
||||||
|
if E::PrimaryKey::iter().count() > 1 {
|
||||||
|
let mut idx_pk = Index::create();
|
||||||
|
for primary_key in E::PrimaryKey::iter() {
|
||||||
|
idx_pk.col(primary_key);
|
||||||
|
}
|
||||||
|
stmt.primary_key(idx_pk.name(&format!("pk-{}", entity.to_string())).primary());
|
||||||
|
}
|
||||||
|
|
||||||
|
for relation in E::Relation::iter() {
|
||||||
|
let relation = relation.def();
|
||||||
|
if relation.is_owner {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut foreign_key_stmt = ForeignKeyCreateStatement::new();
|
||||||
|
let from_tbl = unpack_table_ref(&relation.from_tbl);
|
||||||
|
let to_tbl = unpack_table_ref(&relation.to_tbl);
|
||||||
|
match relation.from_col {
|
||||||
|
Identity::Unary(o1) => {
|
||||||
|
foreign_key_stmt.from_col(o1);
|
||||||
|
}
|
||||||
|
Identity::Binary(o1, o2) => {
|
||||||
|
foreign_key_stmt.from_col(o1);
|
||||||
|
foreign_key_stmt.from_col(o2);
|
||||||
|
}
|
||||||
|
Identity::Ternary(o1, o2, o3) => {
|
||||||
|
foreign_key_stmt.from_col(o1);
|
||||||
|
foreign_key_stmt.from_col(o2);
|
||||||
|
foreign_key_stmt.from_col(o3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match relation.to_col {
|
||||||
|
Identity::Unary(o1) => {
|
||||||
|
foreign_key_stmt.to_col(o1);
|
||||||
|
}
|
||||||
|
Identity::Binary(o1, o2) => {
|
||||||
|
foreign_key_stmt.to_col(o1);
|
||||||
|
foreign_key_stmt.to_col(o2);
|
||||||
|
}
|
||||||
|
crate::Identity::Ternary(o1, o2, o3) => {
|
||||||
|
foreign_key_stmt.to_col(o1);
|
||||||
|
foreign_key_stmt.to_col(o2);
|
||||||
|
foreign_key_stmt.to_col(o3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(action) = relation.on_delete {
|
||||||
|
foreign_key_stmt.on_delete(action);
|
||||||
|
}
|
||||||
|
if let Some(action) = relation.on_update {
|
||||||
|
foreign_key_stmt.on_update(action);
|
||||||
|
}
|
||||||
|
stmt.foreign_key(
|
||||||
|
foreign_key_stmt
|
||||||
|
.name(&format!(
|
||||||
|
"fk-{}-{}",
|
||||||
|
from_tbl.to_string(),
|
||||||
|
to_tbl.to_string()
|
||||||
|
))
|
||||||
|
.from_tbl(from_tbl)
|
||||||
|
.to_tbl(to_tbl),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.table(entity).if_not_exists().take()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{entity_to_table_create_statement, tests_cfg::*};
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
use sea_query::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_entity_to_table_create_statement() {
|
||||||
|
assert_eq!(
|
||||||
|
entity_to_table_create_statement(CakeFillingPrice).to_string(MysqlQueryBuilder),
|
||||||
|
Table::create()
|
||||||
|
.table(CakeFillingPrice)
|
||||||
|
.if_not_exists()
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(cake_filling_price::Column::CakeId)
|
||||||
|
.integer()
|
||||||
|
.not_null()
|
||||||
|
)
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(cake_filling_price::Column::FillingId)
|
||||||
|
.integer()
|
||||||
|
.not_null()
|
||||||
|
)
|
||||||
|
.col(
|
||||||
|
ColumnDef::new(cake_filling_price::Column::Price)
|
||||||
|
.decimal()
|
||||||
|
.not_null()
|
||||||
|
)
|
||||||
|
.primary_key(
|
||||||
|
Index::create()
|
||||||
|
.name("pk-cake_filling_price")
|
||||||
|
.col(cake_filling_price::Column::CakeId)
|
||||||
|
.col(cake_filling_price::Column::FillingId)
|
||||||
|
.primary()
|
||||||
|
)
|
||||||
|
.foreign_key(
|
||||||
|
ForeignKeyCreateStatement::new()
|
||||||
|
.name("fk-cake_filling_price-cake_filling")
|
||||||
|
.from_tbl(CakeFillingPrice)
|
||||||
|
.from_col(cake_filling_price::Column::CakeId)
|
||||||
|
.from_col(cake_filling_price::Column::FillingId)
|
||||||
|
.to_tbl(CakeFilling)
|
||||||
|
.to_col(cake_filling::Column::CakeId)
|
||||||
|
.to_col(cake_filling::Column::FillingId)
|
||||||
|
)
|
||||||
|
.to_string(MysqlQueryBuilder)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -264,9 +264,12 @@ impl TryGetable for Decimal {
|
|||||||
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))?;
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))?;
|
||||||
use rust_decimal::prelude::FromPrimitive;
|
use rust_decimal::prelude::FromPrimitive;
|
||||||
match val {
|
match val {
|
||||||
Some(v) => Decimal::from_f64(v)
|
Some(v) => Decimal::from_f64(v).ok_or_else(|| {
|
||||||
.ok_or_else(|| TryGetError::DbErr(DbErr::Query("Failed to convert f64 into Decimal".to_owned()))),
|
TryGetError::DbErr(DbErr::Query(
|
||||||
None => Err(TryGetError::Null)
|
"Failed to convert f64 into Decimal".to_owned(),
|
||||||
|
))
|
||||||
|
}),
|
||||||
|
None => Err(TryGetError::Null),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
|
@ -294,7 +294,7 @@ fn join_condition(rel: RelationDef) -> SimpleExpr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unpack_table_ref(table_ref: &TableRef) -> DynIden {
|
pub(crate) fn unpack_table_ref(table_ref: &TableRef) -> DynIden {
|
||||||
match table_ref {
|
match table_ref {
|
||||||
TableRef::Table(tbl) => SeaRc::clone(tbl),
|
TableRef::Table(tbl) => SeaRc::clone(tbl),
|
||||||
TableRef::SchemaTable(_, tbl) => SeaRc::clone(tbl),
|
TableRef::SchemaTable(_, tbl) => SeaRc::clone(tbl),
|
||||||
|
@ -49,7 +49,7 @@ impl ColumnTrait for Column {
|
|||||||
Self::Id => ColumnType::Integer.def(),
|
Self::Id => ColumnType::Integer.def(),
|
||||||
Self::Name => ColumnType::String(None).def(),
|
Self::Name => ColumnType::String(None).def(),
|
||||||
Self::ContactDetails => ColumnType::Json.def(),
|
Self::ContactDetails => ColumnType::Json.def(),
|
||||||
Self::BakeryId => ColumnType::Integer.def(),
|
Self::BakeryId => ColumnType::Integer.def().null(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +60,8 @@ impl RelationTrait for Relation {
|
|||||||
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
||||||
.from(Column::BakeryId)
|
.from(Column::BakeryId)
|
||||||
.to(super::bakery::Column::Id)
|
.to(super::bakery::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl ColumnTrait for Column {
|
|||||||
match self {
|
match self {
|
||||||
Self::Id => ColumnType::Integer.def(),
|
Self::Id => ColumnType::Integer.def(),
|
||||||
Self::Name => ColumnType::String(None).def(),
|
Self::Name => ColumnType::String(None).def(),
|
||||||
Self::ProfitMargin => ColumnType::Float.def(),
|
Self::ProfitMargin => ColumnType::Double.def(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,9 @@ impl ColumnTrait for Column {
|
|||||||
Self::Id => ColumnType::Integer.def(),
|
Self::Id => ColumnType::Integer.def(),
|
||||||
Self::Name => ColumnType::String(None).def(),
|
Self::Name => ColumnType::String(None).def(),
|
||||||
Self::Price => ColumnType::Decimal(Some((19, 4))).def(),
|
Self::Price => ColumnType::Decimal(Some((19, 4))).def(),
|
||||||
Self::BakeryId => ColumnType::Integer.def(),
|
Self::BakeryId => ColumnType::Integer.def().null(),
|
||||||
Self::GlutenFree => ColumnType::Boolean.def(),
|
Self::GlutenFree => ColumnType::Boolean.def(),
|
||||||
Self::Serial => ColumnType::String(None).def(),
|
Self::Serial => ColumnType::Uuid.def(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +67,8 @@ impl RelationTrait for Relation {
|
|||||||
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
||||||
.from(Column::BakeryId)
|
.from(Column::BakeryId)
|
||||||
.to(super::bakery::Column::Id)
|
.to(super::bakery::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(),
|
Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(),
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,14 @@ impl RelationTrait for Relation {
|
|||||||
Self::Cake => Entity::belongs_to(super::cake::Entity)
|
Self::Cake => Entity::belongs_to(super::cake::Entity)
|
||||||
.from(Column::CakeId)
|
.from(Column::CakeId)
|
||||||
.to(super::cake::Column::Id)
|
.to(super::cake::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
Self::Baker => Entity::belongs_to(super::baker::Entity)
|
Self::Baker => Entity::belongs_to(super::baker::Entity)
|
||||||
.from(Column::BakerId)
|
.from(Column::BakerId)
|
||||||
.to(super::baker::Column::Id)
|
.to(super::baker::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ impl ColumnTrait for Column {
|
|||||||
match self {
|
match self {
|
||||||
Self::Id => ColumnType::Integer.def(),
|
Self::Id => ColumnType::Integer.def(),
|
||||||
Self::Name => ColumnType::String(None).def(),
|
Self::Name => ColumnType::String(None).def(),
|
||||||
Self::Notes => ColumnType::Text.def(),
|
Self::Notes => ColumnType::Text.def().null(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,14 @@ impl RelationTrait for Relation {
|
|||||||
Self::Order => Entity::belongs_to(super::order::Entity)
|
Self::Order => Entity::belongs_to(super::order::Entity)
|
||||||
.from(Column::OrderId)
|
.from(Column::OrderId)
|
||||||
.to(super::order::Column::Id)
|
.to(super::order::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
Self::Cake => Entity::belongs_to(super::cake::Entity)
|
Self::Cake => Entity::belongs_to(super::cake::Entity)
|
||||||
.from(Column::CakeId)
|
.from(Column::CakeId)
|
||||||
.to(super::cake::Column::Id)
|
.to(super::cake::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,14 @@ impl RelationTrait for Relation {
|
|||||||
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
Self::Bakery => Entity::belongs_to(super::bakery::Entity)
|
||||||
.from(Column::BakeryId)
|
.from(Column::BakeryId)
|
||||||
.to(super::bakery::Column::Id)
|
.to(super::bakery::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
Self::Customer => Entity::belongs_to(super::customer::Entity)
|
Self::Customer => Entity::belongs_to(super::customer::Entity)
|
||||||
.from(Column::CustomerId)
|
.from(Column::CustomerId)
|
||||||
.to(super::customer::Column::Id)
|
.to(super::customer::Column::Id)
|
||||||
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
.into(),
|
.into(),
|
||||||
Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(),
|
Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(),
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
use sea_orm::{error::*, sea_query, DbConn, ExecResult};
|
use pretty_assertions::assert_eq;
|
||||||
use sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, TableCreateStatement};
|
use sea_orm::{
|
||||||
|
entity_to_table_create_statement, error::*, sea_query, DbConn, EntityTrait, ExecResult,
|
||||||
|
};
|
||||||
|
use sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement};
|
||||||
|
|
||||||
pub use super::super::bakery_chain::*;
|
pub use super::super::bakery_chain::*;
|
||||||
|
|
||||||
async fn create_table(db: &DbConn, stmt: &TableCreateStatement) -> Result<ExecResult, DbErr> {
|
async fn create_table<E>(
|
||||||
|
db: &DbConn,
|
||||||
|
stmt: &TableCreateStatement,
|
||||||
|
entity: E,
|
||||||
|
) -> Result<ExecResult, DbErr>
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
let builder = db.get_database_backend();
|
let builder = db.get_database_backend();
|
||||||
db.execute(builder.build(stmt)).await
|
let stmt = builder.build(stmt);
|
||||||
|
assert_eq!(
|
||||||
|
builder.build(&entity_to_table_create_statement(entity)),
|
||||||
|
stmt
|
||||||
|
);
|
||||||
|
db.execute(stmt).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(bakery::Entity)
|
.table(bakery::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -27,16 +42,17 @@ pub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Bakery).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(baker::Entity)
|
.table(baker::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
ColumnDef::new(baker::Column::Id)
|
ColumnDef::new(baker::Column::Id)
|
||||||
.integer()
|
.integer()
|
||||||
|
.not_null()
|
||||||
.auto_increment()
|
.auto_increment()
|
||||||
.primary_key(),
|
.primary_key(),
|
||||||
)
|
)
|
||||||
@ -49,7 +65,7 @@ pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
.col(ColumnDef::new(baker::Column::BakeryId).integer())
|
.col(ColumnDef::new(baker::Column::BakeryId).integer())
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_baker_bakery")
|
.name("fk-baker-bakery")
|
||||||
.from(baker::Entity, baker::Column::BakeryId)
|
.from(baker::Entity, baker::Column::BakeryId)
|
||||||
.to(bakery::Entity, bakery::Column::Id)
|
.to(bakery::Entity, bakery::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -57,11 +73,11 @@ pub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Baker).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(customer::Entity)
|
.table(customer::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -75,11 +91,11 @@ pub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
.col(ColumnDef::new(customer::Column::Notes).text())
|
.col(ColumnDef::new(customer::Column::Notes).text())
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Customer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(order::Entity)
|
.table(order::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -107,7 +123,7 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_order_bakery")
|
.name("fk-order-bakery")
|
||||||
.from(order::Entity, order::Column::BakeryId)
|
.from(order::Entity, order::Column::BakeryId)
|
||||||
.to(bakery::Entity, bakery::Column::Id)
|
.to(bakery::Entity, bakery::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -115,7 +131,7 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_order_customer")
|
.name("fk-order-customer")
|
||||||
.from(order::Entity, order::Column::CustomerId)
|
.from(order::Entity, order::Column::CustomerId)
|
||||||
.to(customer::Entity, customer::Column::Id)
|
.to(customer::Entity, customer::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -123,11 +139,11 @@ pub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Order).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(lineitem::Entity)
|
.table(lineitem::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -159,7 +175,7 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_lineitem_order")
|
.name("fk-lineitem-order")
|
||||||
.from(lineitem::Entity, lineitem::Column::OrderId)
|
.from(lineitem::Entity, lineitem::Column::OrderId)
|
||||||
.to(order::Entity, order::Column::Id)
|
.to(order::Entity, order::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -167,7 +183,7 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_lineitem_cake")
|
.name("fk-lineitem-cake")
|
||||||
.from(lineitem::Entity, lineitem::Column::CakeId)
|
.from(lineitem::Entity, lineitem::Column::CakeId)
|
||||||
.to(cake::Entity, cake::Column::Id)
|
.to(cake::Entity, cake::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -175,11 +191,11 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Lineitem).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(cakes_bakers::Entity)
|
.table(cakes_bakers::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -194,12 +210,13 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
|||||||
)
|
)
|
||||||
.primary_key(
|
.primary_key(
|
||||||
Index::create()
|
Index::create()
|
||||||
|
.name("pk-cakes_bakers")
|
||||||
.col(cakes_bakers::Column::CakeId)
|
.col(cakes_bakers::Column::CakeId)
|
||||||
.col(cakes_bakers::Column::BakerId),
|
.col(cakes_bakers::Column::BakerId),
|
||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_cakes_bakers_cake")
|
.name("fk-cakes_bakers-cake")
|
||||||
.from(cakes_bakers::Entity, cakes_bakers::Column::CakeId)
|
.from(cakes_bakers::Entity, cakes_bakers::Column::CakeId)
|
||||||
.to(cake::Entity, cake::Column::Id)
|
.to(cake::Entity, cake::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -207,7 +224,7 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
|||||||
)
|
)
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_cakes_bakers_baker")
|
.name("fk-cakes_bakers-baker")
|
||||||
.from(cakes_bakers::Entity, cakes_bakers::Column::BakerId)
|
.from(cakes_bakers::Entity, cakes_bakers::Column::BakerId)
|
||||||
.to(baker::Entity, baker::Column::Id)
|
.to(baker::Entity, baker::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -215,11 +232,11 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
|||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, CakesBakers).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let stmt = sea_query::Table::create()
|
let stmt = Table::create()
|
||||||
.table(cake::Entity)
|
.table(cake::Entity)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(
|
.col(
|
||||||
@ -238,7 +255,7 @@ pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
.col(ColumnDef::new(cake::Column::BakeryId).integer())
|
.col(ColumnDef::new(cake::Column::BakeryId).integer())
|
||||||
.foreign_key(
|
.foreign_key(
|
||||||
ForeignKey::create()
|
ForeignKey::create()
|
||||||
.name("FK_cake_bakery")
|
.name("fk-cake-bakery")
|
||||||
.from(cake::Entity, cake::Column::BakeryId)
|
.from(cake::Entity, cake::Column::BakeryId)
|
||||||
.to(bakery::Entity, bakery::Column::Id)
|
.to(bakery::Entity, bakery::Column::Id)
|
||||||
.on_delete(ForeignKeyAction::Cascade)
|
.on_delete(ForeignKeyAction::Cascade)
|
||||||
@ -252,5 +269,5 @@ pub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
.col(ColumnDef::new(cake::Column::Serial).uuid().not_null())
|
.col(ColumnDef::new(cake::Column::Serial).uuid().not_null())
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &stmt).await
|
create_table(db, &stmt, Cake).await
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user