From 37d390e5005e58a128e9862fb8835a3bc88f41da Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Fri, 17 Sep 2021 19:04:18 +0800 Subject: [PATCH 01/25] WIP --- Cargo.toml | 2 +- sea-orm-macros/src/derives/entity_model.rs | 5 +++- src/entity/column.rs | 3 ++ tests/common/bakery_chain/log.rs | 21 +++++++++++++ tests/common/bakery_chain/metadata.rs | 1 - tests/common/bakery_chain/mod.rs | 2 ++ tests/common/setup/mod.rs | 1 + tests/common/setup/schema.rs | 22 ++++++++++++++ tests/timestamp_tests.rs | 35 ++++++++++++++++++++++ 9 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/common/bakery_chain/log.rs create mode 100644 tests/timestamp_tests.rs diff --git a/Cargo.toml b/Cargo.toml index 3641e030..67084e66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.2", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.16.1", features = ["thread-safe"] } +sea-query = { version = "^0.16.2", git = "https://github.com/SeaQL/sea-query.git", branch = "pg-driver-timestamp-tz", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 768d3b7c..c34c43f7 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -172,9 +172,12 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res "bool" => quote! { Boolean }, "NaiveDate" => quote! { Date }, "NaiveTime" => quote! { Time }, - "DateTime" | "NaiveDateTime" | "DateTimeWithTimeZone" => { + "DateTime" | "NaiveDateTime" => { quote! { DateTime } } + "DateTimeWithTimeZone" => { + quote! { TimestampWithTimeZone } + } "Uuid" => quote! { Uuid }, "Json" => quote! { Json }, "Decimal" => quote! { Decimal }, diff --git a/src/entity/column.rs b/src/entity/column.rs index 6e871f4d..26d8ec0e 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -24,6 +24,7 @@ pub enum ColumnType { Decimal(Option<(u32, u32)>), DateTime, Timestamp, + TimestampWithTimeZone, Time, Date, Binary, @@ -278,6 +279,7 @@ impl From for sea_query::ColumnType { ColumnType::Decimal(s) => sea_query::ColumnType::Decimal(s), ColumnType::DateTime => sea_query::ColumnType::DateTime(None), ColumnType::Timestamp => sea_query::ColumnType::Timestamp(None), + ColumnType::TimestampWithTimeZone => sea_query::ColumnType::TimestampWithTimeZone(None), ColumnType::Time => sea_query::ColumnType::Time(None), ColumnType::Date => sea_query::ColumnType::Date, ColumnType::Binary => sea_query::ColumnType::Binary(None), @@ -309,6 +311,7 @@ impl From for ColumnType { sea_query::ColumnType::Decimal(s) => Self::Decimal(s), sea_query::ColumnType::DateTime(_) => Self::DateTime, sea_query::ColumnType::Timestamp(_) => Self::Timestamp, + sea_query::ColumnType::TimestampWithTimeZone(_) => Self::TimestampWithTimeZone, sea_query::ColumnType::Time(_) => Self::Time, sea_query::ColumnType::Date => Self::Date, sea_query::ColumnType::Binary(_) => Self::Binary, diff --git a/tests/common/bakery_chain/log.rs b/tests/common/bakery_chain/log.rs new file mode 100644 index 00000000..c483e41b --- /dev/null +++ b/tests/common/bakery_chain/log.rs @@ -0,0 +1,21 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "log")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub json: Json, + pub created_at: DateTimeWithTimeZone, +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation {} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + unreachable!() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/bakery_chain/metadata.rs b/tests/common/bakery_chain/metadata.rs index 69579492..2585b2db 100644 --- a/tests/common/bakery_chain/metadata.rs +++ b/tests/common/bakery_chain/metadata.rs @@ -1,5 +1,4 @@ use sea_orm::entity::prelude::*; -use uuid::Uuid; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "metadata")] diff --git a/tests/common/bakery_chain/mod.rs b/tests/common/bakery_chain/mod.rs index 3282766d..dc145d36 100644 --- a/tests/common/bakery_chain/mod.rs +++ b/tests/common/bakery_chain/mod.rs @@ -4,6 +4,7 @@ pub mod cake; pub mod cakes_bakers; pub mod customer; pub mod lineitem; +pub mod log; pub mod metadata; pub mod order; @@ -13,5 +14,6 @@ pub use super::cake::Entity as Cake; pub use super::cakes_bakers::Entity as CakesBakers; pub use super::customer::Entity as Customer; pub use super::lineitem::Entity as Lineitem; +pub use super::log::Entity as Log; pub use super::metadata::Entity as Metadata; pub use super::order::Entity as Order; diff --git a/tests/common/setup/mod.rs b/tests/common/setup/mod.rs index 74e35b45..d982b2b7 100644 --- a/tests/common/setup/mod.rs +++ b/tests/common/setup/mod.rs @@ -53,6 +53,7 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection { schema::create_cakes_bakers_table(&db).await.unwrap(); schema::create_lineitem_table(&db).await.unwrap(); schema::create_metadata_table(&db).await.unwrap(); + schema::create_log_table(&db).await.unwrap(); db } diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index 78947c36..bbb09a0a 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -286,3 +286,25 @@ pub async fn create_metadata_table(db: &DbConn) -> Result { create_table(db, &stmt, Metadata).await } + +pub async fn create_log_table(db: &DbConn) -> Result { + let stmt = sea_query::Table::create() + .table(log::Entity) + .if_not_exists() + .col( + ColumnDef::new(log::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(log::Column::Json).json().not_null()) + .col( + ColumnDef::new(log::Column::CreatedAt) + .timestamp_with_time_zone() + .not_null(), + ) + .to_owned(); + + create_table(db, &stmt, Log).await +} diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs new file mode 100644 index 00000000..e1f145ca --- /dev/null +++ b/tests/timestamp_tests.rs @@ -0,0 +1,35 @@ +pub mod common; + +pub use common::{bakery_chain::*, setup::*, TestContext}; +use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; + +#[sea_orm_macros::test] +#[cfg(feature = "sqlx-postgres")] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await; + + create_log(&ctx.db).await?; + + ctx.delete().await; + + Ok(()) +} + +pub async fn create_log(db: &DatabaseConnection) -> Result<(), DbErr> { + let log = log::Model { + id: 1, + json: Json::String("HI".to_owned()), + created_at: "2021-09-17T17:50:20+08:00".parse().unwrap(), + }; + + let res = Log::insert(log.clone().into_active_model()) + .exec(db) + .await?; + + assert_eq!(log.id.clone(), res.last_insert_id); + assert_eq!(Log::find().one(db).await?, Some(log.clone())); + + assert!(false); + + Ok(()) +} From 6435b51d097c64ed4361d31d410be8aa2fa43e0b Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Fri, 17 Sep 2021 21:45:45 +0800 Subject: [PATCH 02/25] Remove unused assert --- tests/timestamp_tests.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs index e1f145ca..6f863b2b 100644 --- a/tests/timestamp_tests.rs +++ b/tests/timestamp_tests.rs @@ -29,7 +29,5 @@ pub async fn create_log(db: &DatabaseConnection) -> Result<(), DbErr> { assert_eq!(log.id.clone(), res.last_insert_id); assert_eq!(Log::find().one(db).await?, Some(log.clone())); - assert!(false); - Ok(()) } From ffb0f1f07dc76492414681de48fe2f4d4394a679 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Fri, 17 Sep 2021 21:57:16 +0800 Subject: [PATCH 03/25] Codegen supports `ColumnType::TimestampWithTimeZone` --- sea-orm-cli/Cargo.toml | 2 +- sea-orm-codegen/src/entity/column.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index 484b6efb..3f21d157 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -22,7 +22,7 @@ clap = { version = "^2.33.3" } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes" ] } sea-orm-codegen = { version = "^0.2.0", path = "../sea-orm-codegen" } -sea-schema = { version = "^0.2.8", git = "https://github.com/SeaQL/sea-schema.git", default-features = false, features = [ +sea-schema = { version = "^0.2.8", git = "https://github.com/SeaQL/sea-schema.git", branch = "pg-timestamp-tz", default-features = false, features = [ "debug-print", "sqlx-mysql", "sqlx-postgres", diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index dfec4b8e..2bab8766 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -38,6 +38,7 @@ impl Column { ColumnType::Double(_) => "f64", ColumnType::Json | ColumnType::JsonBinary => "Json", ColumnType::DateTime(_) | ColumnType::Timestamp(_) => "DateTime", + ColumnType::TimestampWithTimeZone(_) => "DateTimeWithTimeZone", ColumnType::Decimal(_) | ColumnType::Money(_) => "Decimal", ColumnType::Uuid => "Uuid", ColumnType::Binary(_) => "Vec", From b1b5f95c1db231fe41bb4a486991b884c58c9459 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 22:21:54 +0800 Subject: [PATCH 04/25] Unit tests --- src/entity/base_entity.rs | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs index e09fa0a8..6f770162 100644 --- a/src/entity/base_entity.rs +++ b/src/entity/base_entity.rs @@ -541,3 +541,58 @@ pub trait EntityTrait: EntityName { Delete::many(Self::default()) } } + +#[cfg(test)] +mod tests { + #[test] + #[cfg(feature = "macros")] + fn entity_model_1() { + use crate::entity::*; + + mod hello { + use crate as sea_orm; + use crate::entity::prelude::*; + + #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] + #[sea_orm(table_name = "hello")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + assert_eq!(hello::Entity.table_name(), "hello"); + assert_eq!(hello::Entity.schema_name(), None); + } + + #[test] + #[cfg(feature = "macros")] + fn entity_model_2() { + use crate::entity::*; + + mod hello { + use crate as sea_orm; + use crate::entity::prelude::*; + + #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] + #[sea_orm(table_name = "hello", schema_name = "world")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + assert_eq!(hello::Entity.table_name(), "hello"); + assert_eq!(hello::Entity.schema_name(), Some("world")); + } +} From e7ec68f4c1795ffab6d9bbd7904873938abeee9d Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:06:41 +0800 Subject: [PATCH 05/25] Correct Rust type to ColumnType mapping --- sea-orm-macros/src/derives/entity_model.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 768d3b7c..43f87524 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -165,8 +165,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res "String" | "&str" => quote! { String(None) }, "u8" | "i8" => quote! { TinyInteger }, "u16" | "i16" => quote! { SmallInteger }, - "u32" | "u64" | "i32" | "i64" => quote! { Integer }, - "u128" | "i128" => quote! { BigInteger }, + "u32" | "i32" => quote! { Integer }, + "u64" | "i64" => quote! { BigInteger }, "f32" => quote! { Float }, "f64" => quote! { Double }, "bool" => quote! { Boolean }, From e36be13611348514019adb65b6f5d3b8db27a028 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:27:14 +0800 Subject: [PATCH 06/25] Bump dependency version --- Cargo.toml | 2 +- sea-orm-cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67084e66..6a503773 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.2", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.16.2", git = "https://github.com/SeaQL/sea-query.git", branch = "pg-driver-timestamp-tz", features = ["thread-safe"] } +sea-query = { version = "^0.16.3", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index 3f21d157..464f0c29 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -22,7 +22,7 @@ clap = { version = "^2.33.3" } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes" ] } sea-orm-codegen = { version = "^0.2.0", path = "../sea-orm-codegen" } -sea-schema = { version = "^0.2.8", git = "https://github.com/SeaQL/sea-schema.git", branch = "pg-timestamp-tz", default-features = false, features = [ +sea-schema = { version = "^0.2.8", default-features = false, features = [ "debug-print", "sqlx-mysql", "sqlx-postgres", From 903fda0e879a385015921349f371f466076441ff Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:39:58 +0800 Subject: [PATCH 07/25] sea-orm-codegen 0.2.2 --- sea-orm-codegen/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index de38c992..f871fd5b 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sea-orm-codegen" -version = "0.2.0" +version = "0.2.2" authors = ["Billy Chan "] edition = "2018" description = "Code Generator for SeaORM" From 1977d69202cfc8fb68f9f207cf7192973a490aee Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:40:53 +0800 Subject: [PATCH 08/25] sea-orm-cli 0.2.2 --- sea-orm-cli/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index 464f0c29..09e20546 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "sea-orm-cli" -version = "0.2.0" +version = "0.2.2" authors = [ "Billy Chan " ] edition = "2018" description = "Command line utility for SeaORM" @@ -21,7 +21,7 @@ path = "src/main.rs" clap = { version = "^2.33.3" } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes" ] } -sea-orm-codegen = { version = "^0.2.0", path = "../sea-orm-codegen" } +sea-orm-codegen = { version = "^0.2.2", path = "../sea-orm-codegen" } sea-schema = { version = "^0.2.8", default-features = false, features = [ "debug-print", "sqlx-mysql", From 89c73597593c2ada6474934f371e91e049241411 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:47:48 +0800 Subject: [PATCH 09/25] sea-orm-macros 0.2.2 --- sea-orm-macros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sea-orm-macros/Cargo.toml b/sea-orm-macros/Cargo.toml index 27ea856e..2e869316 100644 --- a/sea-orm-macros/Cargo.toml +++ b/sea-orm-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sea-orm-macros" -version = "0.2.0" +version = "0.2.2" authors = [ "Billy Chan " ] edition = "2018" description = "Derive macros for SeaORM" From 6ce040bbbaa47a046207d225b3330fdb7a49f60e Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Fri, 17 Sep 2021 23:49:55 +0800 Subject: [PATCH 10/25] Bump sea-orm-macros --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6a503773..908c6a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ futures = { version = "^0.3" } futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } -sea-orm-macros = { version = "^0.2", path = "sea-orm-macros", optional = true } +sea-orm-macros = { version = "^0.2.2", path = "sea-orm-macros", optional = true } sea-query = { version = "^0.16.3", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } From 28b7542ca96faad0d1894cceb69ff1cb5f1211b7 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 01:42:38 +0800 Subject: [PATCH 11/25] 0.2.2 --- CHANGELOG.md | 14 ++++++++++++++ Cargo.toml | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bea7112..b7757fb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## 0.2.2 - 2021-09-18 + +- [[#105]] Compact entity format +- [[#132]] Add ActiveModel `insert` & `update` +- [[#129]] Add `set` method to `UpdateMany` +- [[#118]] Initial lock support +- [[#167]] Add `FromQueryResult::find_by_statement` + +[#105]: https://github.com/SeaQL/sea-orm/issues/105 +[#132]: https://github.com/SeaQL/sea-orm/issues/132 +[#129]: https://github.com/SeaQL/sea-orm/issues/129 +[#118]: https://github.com/SeaQL/sea-orm/issues/118 +[#167]: https://github.com/SeaQL/sea-orm/issues/167 + ## 0.2.1 - 2021-09-04 - Update dependencies diff --git a/Cargo.toml b/Cargo.toml index 908c6a69..3e5a9682 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "sea-orm-macros", "sea-orm-codegen"] [package] name = "sea-orm" -version = "0.2.1" +version = "0.2.2" authors = ["Chris Tsang "] edition = "2018" description = "🐚 An async & dynamic ORM for Rust" From 56dd19ef75557dffa250ec4135ee08eb556e88f4 Mon Sep 17 00:00:00 2001 From: Muhannad Alrusayni Date: Fri, 17 Sep 2021 21:59:38 +0300 Subject: [PATCH 12/25] Impl TryGetableMany for diffrent types of generices --- src/executor/query.rs | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/executor/query.rs b/src/executor/query.rs index ba8c8169..5bb1661b 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -314,29 +314,50 @@ where } } -impl TryGetableMany for (T, T) +impl TryGetableMany for (A, B) where - T: TryGetable, + A: TryGetable, + B: TryGetable, { fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result { try_get_many_with_slice_len_of(2, cols)?; Ok(( - T::try_get(res, pre, &cols[0])?, - T::try_get(res, pre, &cols[1])?, + A::try_get(res, pre, &cols[0])?, + B::try_get(res, pre, &cols[1])?, )) } } -impl TryGetableMany for (T, T, T) +impl TryGetableMany for (A, B, C) where - T: TryGetable, + A: TryGetable, + B: TryGetable, + C: TryGetable, { fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result { try_get_many_with_slice_len_of(3, cols)?; Ok(( - T::try_get(res, pre, &cols[0])?, - T::try_get(res, pre, &cols[1])?, - T::try_get(res, pre, &cols[2])?, + A::try_get(res, pre, &cols[0])?, + B::try_get(res, pre, &cols[1])?, + C::try_get(res, pre, &cols[2])?, + )) + } +} + +impl TryGetableMany for (A, B, C, D) +where + A: TryGetable, + B: TryGetable, + C: TryGetable, + D: TryGetable, +{ + fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result { + try_get_many_with_slice_len_of(4, cols)?; + Ok(( + A::try_get(res, pre, &cols[0])?, + B::try_get(res, pre, &cols[1])?, + C::try_get(res, pre, &cols[2])?, + D::try_get(res, pre, &cols[3])?, )) } } From 77bc11e1e5b0d3da2108ed715080ea3b69bae1b9 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 03:10:07 +0800 Subject: [PATCH 13/25] Use compact entity format for Rocket example --- examples/rocket_example/src/main.rs | 6 +- examples/rocket_example/src/post.rs | 58 ++----------------- .../rocket_example/templates/edit.html.tera | 6 ++ .../rocket_example/templates/new.html.tera | 6 ++ 4 files changed, 21 insertions(+), 55 deletions(-) diff --git a/examples/rocket_example/src/main.rs b/examples/rocket_example/src/main.rs index 1a275200..87899d84 100644 --- a/examples/rocket_example/src/main.rs +++ b/examples/rocket_example/src/main.rs @@ -10,7 +10,7 @@ use rocket::{Build, Request, Rocket}; use rocket_db_pools::{sqlx, Connection, Database}; use rocket_dyn_templates::{context, Template}; -use sea_orm::entity::*; +use sea_orm::{entity::*, query::*}; mod pool; use pool::RocketDbPool; @@ -81,7 +81,9 @@ async fn list( ) -> Template { let page = page.unwrap_or(0); let posts_per_page = posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE); - let paginator = Post::find().paginate(&conn, posts_per_page); + let paginator = Post::find() + .order_by_asc(post::Column::Id) + .paginate(&conn, posts_per_page); let num_pages = paginator.num_pages().await.ok().unwrap(); let posts = paginator diff --git a/examples/rocket_example/src/post.rs b/examples/rocket_example/src/post.rs index 0bce0e7a..9a56e271 100644 --- a/examples/rocket_example/src/post.rs +++ b/examples/rocket_example/src/post.rs @@ -1,65 +1,17 @@ use rocket::serde::{Deserialize, Serialize}; use sea_orm::entity::prelude::*; -#[derive(Copy, Clone, Default, Debug, DeriveEntity, Deserialize, Serialize)] -#[serde(crate = "rocket::serde")] -pub struct Entity; - -impl EntityName for Entity { - fn table_name(&self) -> &str { - "posts" - } -} - -#[derive( - Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Deserialize, Serialize, FromForm, -)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, FromForm)] #[serde(crate = "rocket::serde")] +#[sea_orm(table_name = "posts")] pub struct Model { - #[serde(skip_deserializing, skip_serializing_if = "Option::is_none")] - pub id: Option, + #[sea_orm(primary_key)] + pub id: i32, pub title: String, pub text: String, } -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - Id, - Title, - Text, -} - -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - Id, -} - -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - - fn auto_increment() -> bool { - true - } -} - -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation {} -impl ColumnTrait for Column { - type EntityName = Entity; - - fn def(&self) -> ColumnDef { - match self { - Self::Id => ColumnType::Integer.def(), - Self::Title => ColumnType::String(None).def(), - Self::Text => ColumnType::String(None).def(), - } - } -} - -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - panic!() - } -} impl ActiveModelBehavior for ActiveModel {} diff --git a/examples/rocket_example/templates/edit.html.tera b/examples/rocket_example/templates/edit.html.tera index 47882e65..2ccb81a1 100644 --- a/examples/rocket_example/templates/edit.html.tera +++ b/examples/rocket_example/templates/edit.html.tera @@ -5,6 +5,12 @@
+ New Post
+ Date: Sat, 18 Sep 2021 03:37:27 +0800 Subject: [PATCH 14/25] Simplify Cargo --- examples/rocket_example/Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/rocket_example/Cargo.toml b/examples/rocket_example/Cargo.toml index 0dfab575..120c7290 100644 --- a/examples/rocket_example/Cargo.toml +++ b/examples/rocket_example/Cargo.toml @@ -23,11 +23,6 @@ rocket_dyn_templates = { git = "https://github.com/SergioBenitez/Rocket.git", fe sea-orm = { path = "../../", version = "^0.2", features = ["macros"], default-features = false } serde_json = { version = "^1" } -[dependencies.sqlx] -version = "^0.5" -default-features = false -features = ["macros", "offline", "migrate"] - [features] default = ["sqlx-postgres"] sqlx-mysql = ["sea-orm/sqlx-mysql", "rocket_db_pools/sqlx_mysql"] From 3bf26a758a0ed6464ff48c08e2363155e1c82072 Mon Sep 17 00:00:00 2001 From: Muhannad Alrusayni Date: Fri, 17 Sep 2021 22:41:49 +0300 Subject: [PATCH 15/25] impl `TryFromU64` for tuples types --- src/executor/query.rs | 73 +++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/src/executor/query.rs b/src/executor/query.rs index 5bb1661b..ec8178a7 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -391,15 +391,27 @@ macro_rules! try_from_u64_err { } } }; -} -macro_rules! try_from_u64_tuple { - ( $type: ty ) => { - try_from_u64_err!(($type, $type)); - try_from_u64_err!(($type, $type, $type)); + ( $($gen_type: ident),* ) => { + impl<$( $gen_type, )*> TryFromU64 for ($( $gen_type, )*) + where + $( $gen_type: TryFromU64, )* + { + fn try_from_u64(_: u64) -> Result { + Err(DbErr::Exec(format!( + "{} cannot be converted from u64", + stringify!(($($gen_type,)*)) + ))) + } + } }; } +// impl TryFromU64 for tuples with generic types +try_from_u64_err!(A, B); +try_from_u64_err!(A, B, C); +try_from_u64_err!(A, B, C, D); + macro_rules! try_from_u64_numeric { ( $type: ty ) => { impl TryFromU64 for $type { @@ -414,7 +426,6 @@ macro_rules! try_from_u64_numeric { }) } } - try_from_u64_tuple!($type); }; } @@ -434,19 +445,49 @@ macro_rules! try_from_u64_string { Ok(n.to_string()) } } - try_from_u64_tuple!($type); }; } try_from_u64_string!(String); -macro_rules! try_from_u64_dummy { - ( $type: ty ) => { - try_from_u64_err!($type); - try_from_u64_err!(($type, $type)); - try_from_u64_err!(($type, $type, $type)); - }; -} - #[cfg(feature = "with-uuid")] -try_from_u64_dummy!(uuid::Uuid); +try_from_u64_err!(uuid::Uuid); + +// impl TryFromU64 for (A, B) +// where +// A: TryFromU64, +// B: TryFromU64, +// { +// fn try_from_u64(_: u64) -> Result { +// Err(DbErr::Exec( +// "(A, B) cannot be converted from u64".to_owned(), +// )) +// } +// } + +// impl TryFromU64 for (A, B, C) +// where +// A: TryFromU64, +// B: TryFromU64, +// C: TryFromU64, +// { +// fn try_from_u64(_: u64) -> Result { +// Err(DbErr::Exec( +// "(A, B, C) cannot be converted from u64".to_owned(), +// )) +// } +// } + +// impl TryFromU64 for (A, B, C, D) +// where +// A: TryFromU64, +// B: TryFromU64, +// C: TryFromU64, +// D: TryFromU64, +// { +// fn try_from_u64(_: u64) -> Result { +// Err(DbErr::Exec( +// "(A, B, C, D) cannot be converted from u64".to_owned(), +// )) +// } +// } From 15db5d293325ddf738a1d00b13b3c274863c25d9 Mon Sep 17 00:00:00 2001 From: Muhannad Alrusayni Date: Fri, 17 Sep 2021 22:45:05 +0300 Subject: [PATCH 16/25] clean up some comments --- src/executor/query.rs | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/src/executor/query.rs b/src/executor/query.rs index ec8178a7..ae09f97c 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -452,42 +452,3 @@ try_from_u64_string!(String); #[cfg(feature = "with-uuid")] try_from_u64_err!(uuid::Uuid); - -// impl TryFromU64 for (A, B) -// where -// A: TryFromU64, -// B: TryFromU64, -// { -// fn try_from_u64(_: u64) -> Result { -// Err(DbErr::Exec( -// "(A, B) cannot be converted from u64".to_owned(), -// )) -// } -// } - -// impl TryFromU64 for (A, B, C) -// where -// A: TryFromU64, -// B: TryFromU64, -// C: TryFromU64, -// { -// fn try_from_u64(_: u64) -> Result { -// Err(DbErr::Exec( -// "(A, B, C) cannot be converted from u64".to_owned(), -// )) -// } -// } - -// impl TryFromU64 for (A, B, C, D) -// where -// A: TryFromU64, -// B: TryFromU64, -// C: TryFromU64, -// D: TryFromU64, -// { -// fn try_from_u64(_: u64) -> Result { -// Err(DbErr::Exec( -// "(A, B, C, D) cannot be converted from u64".to_owned(), -// )) -// } -// } From fc769a89df029f478202543d9abc09d211b5e217 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 15:17:23 +0800 Subject: [PATCH 17/25] Refactor timestamp test --- tests/common/bakery_chain/{log.rs => applog.rs} | 10 ++-------- tests/common/bakery_chain/mod.rs | 4 ++-- tests/common/setup/schema.rs | 10 +++++----- tests/timestamp_tests.rs | 12 +++++------- 4 files changed, 14 insertions(+), 22 deletions(-) rename tests/common/bakery_chain/{log.rs => applog.rs} (62%) diff --git a/tests/common/bakery_chain/log.rs b/tests/common/bakery_chain/applog.rs similarity index 62% rename from tests/common/bakery_chain/log.rs rename to tests/common/bakery_chain/applog.rs index c483e41b..03b06d61 100644 --- a/tests/common/bakery_chain/log.rs +++ b/tests/common/bakery_chain/applog.rs @@ -1,7 +1,7 @@ use sea_orm::entity::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] -#[sea_orm(table_name = "log")] +#[sea_orm(table_name = "applog")] pub struct Model { #[sea_orm(primary_key)] pub id: i32, @@ -9,13 +9,7 @@ pub struct Model { pub created_at: DateTimeWithTimeZone, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation {} -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - unreachable!() - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/bakery_chain/mod.rs b/tests/common/bakery_chain/mod.rs index dc145d36..36f2a16e 100644 --- a/tests/common/bakery_chain/mod.rs +++ b/tests/common/bakery_chain/mod.rs @@ -1,19 +1,19 @@ +pub mod applog; pub mod baker; pub mod bakery; pub mod cake; pub mod cakes_bakers; pub mod customer; pub mod lineitem; -pub mod log; pub mod metadata; pub mod order; +pub use super::applog::Entity as Applog; pub use super::baker::Entity as Baker; pub use super::bakery::Entity as Bakery; pub use super::cake::Entity as Cake; pub use super::cakes_bakers::Entity as CakesBakers; pub use super::customer::Entity as Customer; pub use super::lineitem::Entity as Lineitem; -pub use super::log::Entity as Log; pub use super::metadata::Entity as Metadata; pub use super::order::Entity as Order; diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index bbb09a0a..d2f3b818 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -289,22 +289,22 @@ pub async fn create_metadata_table(db: &DbConn) -> Result { pub async fn create_log_table(db: &DbConn) -> Result { let stmt = sea_query::Table::create() - .table(log::Entity) + .table(applog::Entity) .if_not_exists() .col( - ColumnDef::new(log::Column::Id) + ColumnDef::new(applog::Column::Id) .integer() .not_null() .auto_increment() .primary_key(), ) - .col(ColumnDef::new(log::Column::Json).json().not_null()) + .col(ColumnDef::new(applog::Column::Json).json().not_null()) .col( - ColumnDef::new(log::Column::CreatedAt) + ColumnDef::new(applog::Column::CreatedAt) .timestamp_with_time_zone() .not_null(), ) .to_owned(); - create_table(db, &stmt, Log).await + create_table(db, &stmt, Applog).await } diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs index 6f863b2b..1897323c 100644 --- a/tests/timestamp_tests.rs +++ b/tests/timestamp_tests.rs @@ -7,27 +7,25 @@ use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; #[cfg(feature = "sqlx-postgres")] async fn main() -> Result<(), DbErr> { let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await; - - create_log(&ctx.db).await?; - + create_applog(&ctx.db).await?; ctx.delete().await; Ok(()) } -pub async fn create_log(db: &DatabaseConnection) -> Result<(), DbErr> { - let log = log::Model { +pub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> { + let log = applog::Model { id: 1, json: Json::String("HI".to_owned()), created_at: "2021-09-17T17:50:20+08:00".parse().unwrap(), }; - let res = Log::insert(log.clone().into_active_model()) + let res = Applog::insert(log.clone().into_active_model()) .exec(db) .await?; assert_eq!(log.id.clone(), res.last_insert_id); - assert_eq!(Log::find().one(db).await?, Some(log.clone())); + assert_eq!(Applog::find().one(db).await?, Some(log.clone())); Ok(()) } From 558cf5904a7ee1c1c74d80d8fd373917e2622083 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 15:40:47 +0800 Subject: [PATCH 18/25] Test suite: drop table if exists, instead of create table if not exists --- src/schema/entity.rs | 3 +-- tests/common/setup/schema.rs | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/schema/entity.rs b/src/schema/entity.rs index 7582aaee..a95b7047 100644 --- a/src/schema/entity.rs +++ b/src/schema/entity.rs @@ -116,7 +116,7 @@ where ); } - stmt.table(entity).if_not_exists().take() + stmt.table(entity).take() } #[cfg(test)] @@ -130,7 +130,6 @@ mod tests { Schema::create_table_from_entity(CakeFillingPrice).to_string(MysqlQueryBuilder), Table::create() .table(CakeFillingPrice) - .if_not_exists() .col( ColumnDef::new(cake_filling_price::Column::CakeId) .integer() diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index d2f3b818..a1cc61bc 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -1,18 +1,28 @@ pub use super::super::bakery_chain::*; use pretty_assertions::assert_eq; use sea_orm::{error::*, sea_query, DbConn, EntityTrait, ExecResult, Schema}; -use sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement}; +use sea_query::{ + Alias, ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement, +}; async fn create_table( db: &DbConn, - stmt: &TableCreateStatement, + create: &TableCreateStatement, entity: E, ) -> Result where E: EntityTrait, { let builder = db.get_database_backend(); - let stmt = builder.build(stmt); + let stmt = builder.build( + Table::drop() + .table(Alias::new(create.get_table_name().unwrap().as_ref())) + .if_exists() + .cascade(), + ); + db.execute(stmt).await?; + + let stmt = builder.build(create); assert_eq!( builder.build(&Schema::create_table_from_entity(entity)), stmt @@ -23,7 +33,6 @@ where pub async fn create_bakery_table(db: &DbConn) -> Result { let stmt = Table::create() .table(bakery::Entity) - .if_not_exists() .col( ColumnDef::new(bakery::Column::Id) .integer() @@ -45,7 +54,6 @@ pub async fn create_bakery_table(db: &DbConn) -> Result { pub async fn create_baker_table(db: &DbConn) -> Result { let stmt = Table::create() .table(baker::Entity) - .if_not_exists() .col( ColumnDef::new(baker::Column::Id) .integer() @@ -76,7 +84,6 @@ pub async fn create_baker_table(db: &DbConn) -> Result { pub async fn create_customer_table(db: &DbConn) -> Result { let stmt = Table::create() .table(customer::Entity) - .if_not_exists() .col( ColumnDef::new(customer::Column::Id) .integer() @@ -94,7 +101,6 @@ pub async fn create_customer_table(db: &DbConn) -> Result { pub async fn create_order_table(db: &DbConn) -> Result { let stmt = Table::create() .table(order::Entity) - .if_not_exists() .col( ColumnDef::new(order::Column::Id) .integer() @@ -142,7 +148,6 @@ pub async fn create_order_table(db: &DbConn) -> Result { pub async fn create_lineitem_table(db: &DbConn) -> Result { let stmt = Table::create() .table(lineitem::Entity) - .if_not_exists() .col( ColumnDef::new(lineitem::Column::Id) .integer() @@ -194,7 +199,6 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result { pub async fn create_cakes_bakers_table(db: &DbConn) -> Result { let stmt = Table::create() .table(cakes_bakers::Entity) - .if_not_exists() .col( ColumnDef::new(cakes_bakers::Column::CakeId) .integer() @@ -235,7 +239,6 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result pub async fn create_cake_table(db: &DbConn) -> Result { let stmt = Table::create() .table(cake::Entity) - .if_not_exists() .col( ColumnDef::new(cake::Column::Id) .integer() @@ -272,7 +275,6 @@ pub async fn create_cake_table(db: &DbConn) -> Result { pub async fn create_metadata_table(db: &DbConn) -> Result { let stmt = sea_query::Table::create() .table(metadata::Entity) - .if_not_exists() .col( ColumnDef::new(metadata::Column::Uuid) .uuid() @@ -290,7 +292,6 @@ pub async fn create_metadata_table(db: &DbConn) -> Result { pub async fn create_log_table(db: &DbConn) -> Result { let stmt = sea_query::Table::create() .table(applog::Entity) - .if_not_exists() .col( ColumnDef::new(applog::Column::Id) .integer() From 68787d14125f365a22d6208941ab4d96e10ba847 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 15:47:59 +0800 Subject: [PATCH 19/25] Refactor uuid test --- tests/common/bakery_chain/metadata.rs | 8 +------- tests/{primary_key_tests.rs => uuid_tests.rs} | 5 +---- 2 files changed, 2 insertions(+), 11 deletions(-) rename tests/{primary_key_tests.rs => uuid_tests.rs} (91%) diff --git a/tests/common/bakery_chain/metadata.rs b/tests/common/bakery_chain/metadata.rs index 2585b2db..95a7a48b 100644 --- a/tests/common/bakery_chain/metadata.rs +++ b/tests/common/bakery_chain/metadata.rs @@ -10,13 +10,7 @@ pub struct Model { pub bytes: Vec, } -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation {} -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - unreachable!() - } -} - impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/primary_key_tests.rs b/tests/uuid_tests.rs similarity index 91% rename from tests/primary_key_tests.rs rename to tests/uuid_tests.rs index 06b2a13a..e58daca4 100644 --- a/tests/primary_key_tests.rs +++ b/tests/uuid_tests.rs @@ -2,7 +2,6 @@ pub mod common; pub use common::{bakery_chain::*, setup::*, TestContext}; use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; -use uuid::Uuid; #[sea_orm_macros::test] #[cfg(any( @@ -11,10 +10,8 @@ use uuid::Uuid; feature = "sqlx-postgres" ))] async fn main() -> Result<(), DbErr> { - let ctx = TestContext::new("bakery_chain_schema_primary_key_tests").await; - + let ctx = TestContext::new("bakery_chain_schema_uuid_tests").await; create_metadata(&ctx.db).await?; - ctx.delete().await; Ok(()) From 0a19db6977c89804b19381a9496533efbf15bdd2 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 16:16:33 +0800 Subject: [PATCH 20/25] Fix SQLite test suite --- tests/common/setup/schema.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index a1cc61bc..64f31dfe 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -1,6 +1,6 @@ pub use super::super::bakery_chain::*; use pretty_assertions::assert_eq; -use sea_orm::{error::*, sea_query, DbConn, EntityTrait, ExecResult, Schema}; +use sea_orm::{error::*, sea_query, DbBackend, DbConn, EntityTrait, ExecResult, Schema}; use sea_query::{ Alias, ColumnDef, ForeignKey, ForeignKeyAction, Index, Table, TableCreateStatement, }; @@ -14,13 +14,15 @@ where E: EntityTrait, { let builder = db.get_database_backend(); - let stmt = builder.build( - Table::drop() - .table(Alias::new(create.get_table_name().unwrap().as_ref())) - .if_exists() - .cascade(), - ); - db.execute(stmt).await?; + if builder != DbBackend::Sqlite { + let stmt = builder.build( + Table::drop() + .table(Alias::new(create.get_table_name().unwrap().as_ref())) + .if_exists() + .cascade(), + ); + db.execute(stmt).await?; + } let stmt = builder.build(create); assert_eq!( From 3001fca4661f8718412b6d6197d8de0347b21a73 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 16:37:07 +0800 Subject: [PATCH 21/25] Refactor basic test --- tests/basic.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/basic.rs b/tests/basic.rs index d617ba17..a0763d45 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -2,22 +2,21 @@ pub mod common; pub use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, Database, DbConn}; -// DATABASE_URL="sqlite::memory:" cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic +// cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic #[sea_orm_macros::test] #[cfg(feature = "sqlx-sqlite")] -async fn main() { - use std::env; - let base_url = env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_owned()); +async fn main() -> Result<(), DbErr> { + let base_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_owned()); - let db: DbConn = Database::connect(&base_url).await.unwrap(); + let db: DbConn = Database::connect(&base_url).await?; + setup_schema(&db).await?; + crud_cake(&db).await?; - setup_schema(&db).await; - - crud_cake(&db).await.unwrap(); + Ok(()) } #[cfg(feature = "sqlx-sqlite")] -async fn setup_schema(db: &DbConn) { +async fn setup_schema(db: &DbConn) -> Result<(), DbErr> { use sea_query::*; let stmt = sea_query::Table::create() @@ -33,8 +32,10 @@ async fn setup_schema(db: &DbConn) { .to_owned(); let builder = db.get_database_backend(); - let result = db.execute(builder.build(&stmt)).await; + let result = db.execute(builder.build(&stmt)).await?; println!("Create table cake: {:?}", result); + + Ok(()) } #[cfg(feature = "sqlx-sqlite")] From 8443f566cf68c404595c2790b7338df4400cfa46 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 17:44:43 +0800 Subject: [PATCH 22/25] Tokio example --- examples/tokio/Cargo.toml | 2 +- examples/tokio/src/cake.rs | 51 +++----------------------------------- 2 files changed, 5 insertions(+), 48 deletions(-) diff --git a/examples/tokio/Cargo.toml b/examples/tokio/Cargo.toml index b1124aad..3178ddc4 100644 --- a/examples/tokio/Cargo.toml +++ b/examples/tokio/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" publish = false [dependencies] -sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-tokio-native-tls" ] } +sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-tokio-native-tls", "debug-print" ] } tokio = { version = "1", features = ["full"] } env_logger = { version = "^0.9" } log = { version = "^0.4" } diff --git a/examples/tokio/src/cake.rs b/examples/tokio/src/cake.rs index 21b83331..cd23fb08 100644 --- a/examples/tokio/src/cake.rs +++ b/examples/tokio/src/cake.rs @@ -1,57 +1,14 @@ 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)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "cake")] pub struct Model { + #[sea_orm(primary_key)] pub id: i32, pub name: String, } -#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] -pub enum Column { - Id, - Name, -} - -#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] -pub enum PrimaryKey { - Id, -} - -impl PrimaryKeyTrait for PrimaryKey { - type ValueType = i32; - - fn auto_increment() -> bool { - true - } -} - -#[derive(Copy, Clone, Debug, EnumIter)] +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation {} -impl ColumnTrait for Column { - type EntityName = Entity; - - fn def(&self) -> ColumnDef { - match self { - Self::Id => ColumnType::Integer.def(), - Self::Name => ColumnType::String(None).def(), - } - } -} - -impl RelationTrait for Relation { - fn def(&self) -> RelationDef { - unreachable!() - } -} - impl ActiveModelBehavior for ActiveModel {} From 84594114dc8c038c09ac9dc61a3ddfd15cbac231 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 20:15:20 +0800 Subject: [PATCH 23/25] Readme --- tests/common/bakery_chain/Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/common/bakery_chain/Readme.md b/tests/common/bakery_chain/Readme.md index 1b5bf076..91d8006a 100644 --- a/tests/common/bakery_chain/Readme.md +++ b/tests/common/bakery_chain/Readme.md @@ -1,3 +1,5 @@ # Schema for SeaORM test suite +![Entity Relation Diagram](bakery_chain_erd.png) + ERD generated by DataGrip. \ No newline at end of file From 27807f3f6cefda824221f9f834b50e36d95eaf65 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 18 Sep 2021 21:45:28 +0800 Subject: [PATCH 24/25] Fix DeriveEntityModel Decimal mapping --- sea-orm-macros/src/derives/entity_model.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 2bba86ae..f0772763 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -180,7 +180,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res } "Uuid" => quote! { Uuid }, "Json" => quote! { Json }, - "Decimal" => quote! { Decimal }, + "Decimal" => quote! { Decimal(None) }, "Vec" => quote! { Binary }, _ => { return Err(Error::new( From 3093cd2035beb365b178c60793593d6dbc104752 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 15 Sep 2021 12:27:32 +0800 Subject: [PATCH 25/25] DatabaseConnection impl Sync, Send and Clone --- src/database/connection.rs | 13 +++++++++++++ src/driver/sqlx_mysql.rs | 2 +- src/driver/sqlx_postgres.rs | 2 +- src/driver/sqlx_sqlite.rs | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/database/connection.rs b/src/database/connection.rs index 6a39b240..995dde9d 100644 --- a/src/database/connection.rs +++ b/src/database/connection.rs @@ -1,6 +1,7 @@ use crate::{error::*, ExecResult, QueryResult, Statement, StatementBuilder}; use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryBuilder, SqliteQueryBuilder}; +#[cfg_attr(not(feature = "mock"), derive(Clone))] pub enum DatabaseConnection { #[cfg(feature = "sqlx-mysql")] SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection), @@ -143,3 +144,15 @@ impl DbBackend { } } } + +#[cfg(test)] +mod tests { + use crate::DatabaseConnection; + + #[test] + fn assert_database_connection_traits() { + fn assert_send_sync() {} + + assert_send_sync::(); + } +} diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index e91df037..be590b6e 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -13,7 +13,7 @@ use super::sqlx_common::*; #[derive(Debug)] pub struct SqlxMySqlConnector; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SqlxMySqlPoolConnection { pool: MySqlPool, } diff --git a/src/driver/sqlx_postgres.rs b/src/driver/sqlx_postgres.rs index 086dc995..e7b9032a 100644 --- a/src/driver/sqlx_postgres.rs +++ b/src/driver/sqlx_postgres.rs @@ -13,7 +13,7 @@ use super::sqlx_common::*; #[derive(Debug)] pub struct SqlxPostgresConnector; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SqlxPostgresPoolConnection { pool: PgPool, } diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index 5fa4bdcd..bd6f0399 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -13,7 +13,7 @@ use super::sqlx_common::*; #[derive(Debug)] pub struct SqlxSqliteConnector; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SqlxSqlitePoolConnection { pool: SqlitePool, }