diff --git a/CHANGELOG.md b/CHANGELOG.md index eed3f853..e561dec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### New Features * Transactions Isolation level and Access mode https://github.com/SeaQL/sea-orm/pull/1230 +* [sea-orm-cli] Generate `#[serde(skip_deserializing)]` for primary key columns https://github.com/SeaQL/sea-orm/pull/846, https://github.com/SeaQL/sea-orm/pull/1186, https://github.com/SeaQL/sea-orm/pull/1318 +* [sea-orm-cli] Generate `#[serde(skip)]` for hidden columns https://github.com/SeaQL/sea-orm/pull/1171, https://github.com/SeaQL/sea-orm/pull/1320 +* [sea-orm-cli] Generate entity with extra derives and attributes for model struct https://github.com/SeaQL/sea-orm/pull/1124, https://github.com/SeaQL/sea-orm/pull/1321 ### Enhancements * Support Vector of enum for Postgres https://github.com/SeaQL/sea-orm/pull/1210 * Added `DatabaseConnection::close` https://github.com/SeaQL/sea-orm/pull/1236 +* Refactor schema module to expose functions for database alteration https://github.com/SeaQL/sea-orm/pull/1256 ### Upgrades @@ -22,11 +26,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### House Keeping -* Remove dependency when not needed https://github.com/SeaQL/sea-orm/pull/1213 +* Removed dependency when not needed https://github.com/SeaQL/sea-orm/pull/1213 +* Changed all version = "^x.y.z" into version = "x.y.z" and disabled default features and enable only the needed ones https://github.com/SeaQL/sea-orm/pull/1300 ### Bug Fixes * Fixes `DeriveColumn` (by qualifying `IdenStatic::as_str`) https://github.com/SeaQL/sea-orm/pull/1280 +* Prevent returning connections to pool with a positive transaction depth https://github.com/SeaQL/sea-orm/pull/1283 + +## 0.10.6 - Pending + +### Enhancements + +* Cast enum values when constructing update many query https://github.com/SeaQL/sea-orm/pull/1178 + +### Bug Fixes + +* [sea-orm-codegen] Skip implementing Related if the same related entity is being referenced by a conjunct relation https://github.com/SeaQL/sea-orm/pull/1298 +* [sea-orm-cli] CLI depends on codegen of the same version https://github.com/SeaQL/sea-orm/pull/1299/ ## 0.10.5 - 2022-12-02 diff --git a/Cargo.toml b/Cargo.toml index 1690ef5f..c42e36de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,41 +24,41 @@ name = "sea_orm" path = "src/lib.rs" [dependencies] -async-stream = { version = "^0.3", default-features = false } -async-trait = { version = "^0.1", default-features = false } -chrono = { version = "^0.4.20", default-features = false, optional = true } -time = { version = "^0.3", default-features = false, optional = true } -futures = { version = "^0.3", default-features = false, features = ["std"] } -log = { version = "^0.4", default-features = false } -tracing = { version = "^0.1", default-features = false, features = ["attributes", "log"] } -rust_decimal = { version = "^1", default-features = false, optional = true } -bigdecimal = { version = "^0.3", default-features = false, optional = true } -sea-orm-macros = { version = "^0.10.3", path = "sea-orm-macros", default-features = false, optional = true } -sea-query = { version = "^0.27.2", features = ["thread-safe"] } -sea-query-binder = { version = "^0.2.2", default-features = false, optional = true } -sea-strum = { version = "^0.23", default-features = false, features = ["derive", "sea-orm"] } -serde = { version = "^1.0", default-features = false } -serde_json = { version = "^1.0", default-features = false, optional = true } -sqlx = { version = "^0.6", default-features = false, optional = true } -uuid = { version = "^1", default-features = false, optional = true } +async-stream = { version = "0.3", default-features = false } +async-trait = { version = "0.1", default-features = false } +chrono = { version = "0.4.20", default-features = false, optional = true } +time = { version = "0.3", default-features = false, optional = true } +futures = { version = "0.3", default-features = false, features = ["std"] } +log = { version = "0.4", default-features = false } +tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] } +rust_decimal = { version = "1", default-features = false, optional = true } +bigdecimal = { version = "0.3", default-features = false, optional = true } +sea-orm-macros = { version = "0.10.3", path = "sea-orm-macros", default-features = false, optional = true } +sea-query = { version = "0.27.2", features = ["thread-safe"] } +sea-query-binder = { version = "0.2.2", default-features = false, optional = true } +sea-strum = { version = "0.23", default-features = false, features = ["derive", "sea-orm"] } +serde = { version = "1.0", default-features = false } +serde_json = { version = "1.0", default-features = false, optional = true } +sqlx = { version = "0.6", default-features = false, optional = true } +uuid = { version = "1", default-features = false, optional = true } ouroboros = { version = "0.15", default-features = false } -url = { version = "^2.2", default-features = false } -thiserror = { version = "^1", default-features = false } +url = { version = "2.2", default-features = false } +thiserror = { version = "1", default-features = false } [dev-dependencies] -smol = { version = "^1.2" } -smol-potat = { version = "^1.1" } -async-std = { version = "^1", features = ["attributes", "tokio1"] } -futures = { version = "^0.3" } -tokio = { version = "^1.6", features = ["full"] } +smol = { version = "1.2" } +smol-potat = { version = "1.1" } +async-std = { version = "1", features = ["attributes", "tokio1"] } +futures = { version = "0.3" } +tokio = { version = "1.6", features = ["full"] } actix-rt = { version = "2.2.0" } -maplit = { version = "^1" } -rust_decimal_macros = { version = "^1" } +maplit = { version = "1" } +rust_decimal_macros = { version = "1" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } sea-orm = { path = ".", features = ["mock", "debug-print", "tests-cfg", "postgres-array"] } -pretty_assertions = { version = "^0.7" } -time = { version = "^0.3", features = ["macros"] } -uuid = { version = "^1", features = ["v4"] } +pretty_assertions = { version = "0.7" } +time = { version = "0.3", features = ["macros"] } +uuid = { version = "1", features = ["v4"] } once_cell = "1.8" [features] diff --git a/build-tools/bump-version.sh b/build-tools/bump-version.sh index 5e1296fe..68062fbc 100644 --- a/build-tools/bump-version.sh +++ b/build-tools/bump-version.sh @@ -11,7 +11,7 @@ sleep 1 # Bump `sea-orm-cli` version cd sea-orm-cli sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml -sed -i 's/^sea-orm-codegen [^,]*,/sea-orm-codegen = { version = "\^'$1'",/' Cargo.toml +sed -i 's/^sea-orm-codegen [^,]*,/sea-orm-codegen = { version = "\='$1'",/' Cargo.toml git commit -am "sea-orm-cli $1" cd .. sleep 1 @@ -23,21 +23,21 @@ git commit -am "sea-orm-macros $1" cd .. sleep 1 sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml -sed -i 's/^sea-orm-macros [^,]*,/sea-orm-macros = { version = "\^'$1'",/' Cargo.toml +sed -i 's/^sea-orm-macros [^,]*,/sea-orm-macros = { version = "'$1'",/' Cargo.toml git commit -am "$1" # publish sea-orm sleep 1 # Bump `sea-orm-migration` version cd sea-orm-migration sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml -sed -i 's/^sea-orm-cli [^,]*,/sea-orm-cli = { version = "\^'$1'",/' Cargo.toml -sed -i 's/^sea-orm [^,]*,/sea-orm = { version = "\^'$1'",/' Cargo.toml +sed -i 's/^sea-orm-cli [^,]*,/sea-orm-cli = { version = "'$1'",/' Cargo.toml +sed -i 's/^sea-orm [^,]*,/sea-orm = { version = "'$1'",/' Cargo.toml git commit -am "sea-orm-migration $1" cd .. sleep 1 # Bump examples' dependency version cd examples -find . -depth -type f -name '*.toml' -exec sed -i 's/^version = "\^.*" # sea-orm version$/version = "\^'$1'" # sea-orm version/' {} \; -find . -depth -type f -name '*.toml' -exec sed -i 's/^version = "\^.*" # sea-orm-migration version$/version = "\^'$1'" # sea-orm-migration version/' {} \; +find . -depth -type f -name '*.toml' -exec sed -i 's/^version = ".*" # sea-orm version$/version = "'$1'" # sea-orm version/' {} \; +find . -depth -type f -name '*.toml' -exec sed -i 's/^version = ".*" # sea-orm-migration version$/version = "'$1'" # sea-orm-migration version/' {} \; git commit -am "update examples" \ No newline at end of file diff --git a/examples/actix3_example/api/Cargo.toml b/examples/actix3_example/api/Cargo.toml index 16160b49..fa61d230 100644 --- a/examples/actix3_example/api/Cargo.toml +++ b/examples/actix3_example/api/Cargo.toml @@ -11,8 +11,8 @@ actix-http = "2" actix-web = "3" actix-flash = "0.2" actix-files = "0.5" -futures = { version = "^0.3" } -futures-util = { version = "^0.3" } +futures = { version = "0.3" } +futures-util = { version = "0.3" } tera = "1.8.0" dotenvy = "0.15" listenfd = "0.3.3" diff --git a/examples/actix3_example/core/Cargo.toml b/examples/actix3_example/core/Cargo.toml index a64156f4..a23c5735 100644 --- a/examples/actix3_example/core/Cargo.toml +++ b/examples/actix3_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-async-std-native-tls", diff --git a/examples/actix3_example/entity/Cargo.toml b/examples/actix3_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/actix3_example/entity/Cargo.toml +++ b/examples/actix3_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/actix3_example/migration/Cargo.toml b/examples/actix3_example/migration/Cargo.toml index 5225de98..f8154785 100644 --- a/examples/actix3_example/migration/Cargo.toml +++ b/examples/actix3_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-async-std-native-tls", diff --git a/examples/actix_example/core/Cargo.toml b/examples/actix_example/core/Cargo.toml index abf5f22f..abee7f61 100644 --- a/examples/actix_example/core/Cargo.toml +++ b/examples/actix_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-async-std-native-tls", diff --git a/examples/actix_example/entity/Cargo.toml b/examples/actix_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/actix_example/entity/Cargo.toml +++ b/examples/actix_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/actix_example/migration/Cargo.toml b/examples/actix_example/migration/Cargo.toml index cff51ed5..84c70ff9 100644 --- a/examples/actix_example/migration/Cargo.toml +++ b/examples/actix_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-actix-native-tls", diff --git a/examples/axum_example/core/Cargo.toml b/examples/axum_example/core/Cargo.toml index ce086d64..b36b312f 100644 --- a/examples/axum_example/core/Cargo.toml +++ b/examples/axum_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-async-std-native-tls", diff --git a/examples/axum_example/entity/Cargo.toml b/examples/axum_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/axum_example/entity/Cargo.toml +++ b/examples/axum_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/axum_example/migration/Cargo.toml b/examples/axum_example/migration/Cargo.toml index fba8ba56..e5cc3d92 100644 --- a/examples/axum_example/migration/Cargo.toml +++ b/examples/axum_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/basic/Cargo.toml b/examples/basic/Cargo.toml index 9c53df39..4c36d6cc 100644 --- a/examples/basic/Cargo.toml +++ b/examples/basic/Cargo.toml @@ -8,9 +8,9 @@ edition = "2021" publish = false [dependencies] -async-std = { version = "^1.9", features = [ "attributes", "tokio1" ] } +async-std = { version = "1.9", features = [ "attributes", "tokio1" ] } sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-async-std-native-tls" ] } -serde_json = { version = "^1" } -futures = { version = "^0.3" } -async-stream = { version = "^0.3" } -futures-util = { version = "^0.3" } +serde_json = { version = "1" } +futures = { version = "0.3" } +async-stream = { version = "0.3" } +futures-util = { version = "0.3" } diff --git a/examples/graphql_example/api/Cargo.toml b/examples/graphql_example/api/Cargo.toml index a4fd78f4..aecf0466 100644 --- a/examples/graphql_example/api/Cargo.toml +++ b/examples/graphql_example/api/Cargo.toml @@ -8,8 +8,8 @@ publish = false [dependencies] graphql-example-core = { path = "../core" } tokio = { version = "1.0", features = ["full"] } -axum = "^0.5.1" +axum = "0.5.1" dotenvy = "0.15.0" -async-graphql-axum = "^4.0.6" +async-graphql-axum = "4.0.6" entity = { path = "../entity" } migration = { path = "../migration" } diff --git a/examples/graphql_example/core/Cargo.toml b/examples/graphql_example/core/Cargo.toml index 33293225..dad73749 100644 --- a/examples/graphql_example/core/Cargo.toml +++ b/examples/graphql_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-async-std-native-tls", diff --git a/examples/graphql_example/entity/Cargo.toml b/examples/graphql_example/entity/Cargo.toml index f041d507..58cf7b86 100644 --- a/examples/graphql_example/entity/Cargo.toml +++ b/examples/graphql_example/entity/Cargo.toml @@ -12,8 +12,8 @@ path = "src/lib.rs" serde = { version = "1", features = ["derive"] } [dependencies.async-graphql] -version = "^4.0.6" +version = "4.0.6" [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/graphql_example/migration/Cargo.toml b/examples/graphql_example/migration/Cargo.toml index 2b12363a..b5214319 100644 --- a/examples/graphql_example/migration/Cargo.toml +++ b/examples/graphql_example/migration/Cargo.toml @@ -10,11 +10,11 @@ path = "src/lib.rs" [dependencies] dotenvy = "0.15.0" -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/jsonrpsee_example/api/Cargo.toml b/examples/jsonrpsee_example/api/Cargo.toml index 7f84ecd3..9e98a03c 100644 --- a/examples/jsonrpsee_example/api/Cargo.toml +++ b/examples/jsonrpsee_example/api/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] jsonrpsee-example-core = { path = "../core" } -jsonrpsee = { version = "^0.8.0", features = ["full"] } +jsonrpsee = { version = "0.8.0", features = ["full"] } jsonrpsee-core = "0.9.0" tokio = { version = "1.8.0", features = ["full"] } serde = { version = "1", features = ["derive"] } diff --git a/examples/jsonrpsee_example/core/Cargo.toml b/examples/jsonrpsee_example/core/Cargo.toml index 23aeec82..023152c1 100644 --- a/examples/jsonrpsee_example/core/Cargo.toml +++ b/examples/jsonrpsee_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-tokio-native-tls", diff --git a/examples/jsonrpsee_example/entity/Cargo.toml b/examples/jsonrpsee_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/jsonrpsee_example/entity/Cargo.toml +++ b/examples/jsonrpsee_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/jsonrpsee_example/migration/Cargo.toml b/examples/jsonrpsee_example/migration/Cargo.toml index 6c0d82a0..246cf688 100644 --- a/examples/jsonrpsee_example/migration/Cargo.toml +++ b/examples/jsonrpsee_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/poem_example/core/Cargo.toml b/examples/poem_example/core/Cargo.toml index cacdfcb6..85691245 100644 --- a/examples/poem_example/core/Cargo.toml +++ b/examples/poem_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-async-std-native-tls", diff --git a/examples/poem_example/entity/Cargo.toml b/examples/poem_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/poem_example/entity/Cargo.toml +++ b/examples/poem_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/poem_example/migration/Cargo.toml b/examples/poem_example/migration/Cargo.toml index 6c0d82a0..246cf688 100644 --- a/examples/poem_example/migration/Cargo.toml +++ b/examples/poem_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/rocket_example/api/Cargo.toml b/examples/rocket_example/api/Cargo.toml index 2ce9ab89..4361c460 100644 --- a/examples/rocket_example/api/Cargo.toml +++ b/examples/rocket_example/api/Cargo.toml @@ -6,18 +6,18 @@ edition = "2021" publish = false [dependencies] -async-stream = { version = "^0.3" } +async-stream = { version = "0.3" } async-trait = { version = "0.1" } rocket-example-core = { path = "../core" } -futures = { version = "^0.3" } -futures-util = { version = "^0.3" } +futures = { version = "0.3" } +futures-util = { version = "0.3" } rocket = { version = "0.5.0-rc.1", features = [ "json", ] } rocket_dyn_templates = { version = "0.1.0-rc.1", features = [ "tera", ] } -serde_json = { version = "^1" } +serde_json = { version = "1" } entity = { path = "../entity" } migration = { path = "../migration" } tokio = "1.20.0" diff --git a/examples/rocket_example/core/Cargo.toml b/examples/rocket_example/core/Cargo.toml index ac255632..18740ac3 100644 --- a/examples/rocket_example/core/Cargo.toml +++ b/examples/rocket_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "runtime-tokio-native-tls", "sqlx-postgres", diff --git a/examples/rocket_example/entity/Cargo.toml b/examples/rocket_example/entity/Cargo.toml index aefe0beb..3cdacb0d 100644 --- a/examples/rocket_example/entity/Cargo.toml +++ b/examples/rocket_example/entity/Cargo.toml @@ -15,4 +15,4 @@ rocket = { version = "0.5.0-rc.1", features = [ [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/rocket_example/migration/Cargo.toml b/examples/rocket_example/migration/Cargo.toml index 2485d3c8..e195d535 100644 --- a/examples/rocket_example/migration/Cargo.toml +++ b/examples/rocket_example/migration/Cargo.toml @@ -10,11 +10,11 @@ path = "src/lib.rs" [dependencies] rocket = { version = "0.5.0-rc.1" } -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/rocket_okapi_example/api/Cargo.toml b/examples/rocket_okapi_example/api/Cargo.toml index 00ecdbaf..f2e78e17 100644 --- a/examples/rocket_okapi_example/api/Cargo.toml +++ b/examples/rocket_okapi_example/api/Cargo.toml @@ -6,18 +6,18 @@ edition = "2021" publish = false [dependencies] -async-stream = { version = "^0.3" } +async-stream = { version = "0.3" } async-trait = { version = "0.1" } rocket-example-core = { path = "../core" } -futures = { version = "^0.3" } -futures-util = { version = "^0.3" } +futures = { version = "0.3" } +futures-util = { version = "0.3" } rocket = { version = "0.5.0-rc.1", features = [ "json", ] } rocket_dyn_templates = { version = "0.1.0-rc.1", features = [ "tera", ] } -serde_json = { version = "^1" } +serde_json = { version = "1" } entity = { path = "../entity" } migration = { path = "../migration" } tokio = "1.20.0" diff --git a/examples/rocket_okapi_example/core/Cargo.toml b/examples/rocket_okapi_example/core/Cargo.toml index ac255632..18740ac3 100644 --- a/examples/rocket_okapi_example/core/Cargo.toml +++ b/examples/rocket_okapi_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "runtime-tokio-native-tls", "sqlx-postgres", diff --git a/examples/rocket_okapi_example/entity/Cargo.toml b/examples/rocket_okapi_example/entity/Cargo.toml index 42e3ed77..cea785eb 100644 --- a/examples/rocket_okapi_example/entity/Cargo.toml +++ b/examples/rocket_okapi_example/entity/Cargo.toml @@ -15,7 +15,7 @@ rocket = { version = "0.5.0-rc.1", features = [ [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version [dependencies.rocket_okapi] version = "0.8.0-rc.2" diff --git a/examples/rocket_okapi_example/migration/Cargo.toml b/examples/rocket_okapi_example/migration/Cargo.toml index 2485d3c8..e195d535 100644 --- a/examples/rocket_okapi_example/migration/Cargo.toml +++ b/examples/rocket_okapi_example/migration/Cargo.toml @@ -10,11 +10,11 @@ path = "src/lib.rs" [dependencies] rocket = { version = "0.5.0-rc.1" } -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/salvo_example/core/Cargo.toml b/examples/salvo_example/core/Cargo.toml index 6b70b51a..19ed3fa1 100644 --- a/examples/salvo_example/core/Cargo.toml +++ b/examples/salvo_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-tokio-native-tls", diff --git a/examples/salvo_example/entity/Cargo.toml b/examples/salvo_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/salvo_example/entity/Cargo.toml +++ b/examples/salvo_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/salvo_example/migration/Cargo.toml b/examples/salvo_example/migration/Cargo.toml index 6c0d82a0..246cf688 100644 --- a/examples/salvo_example/migration/Cargo.toml +++ b/examples/salvo_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-native-tls", diff --git a/examples/tonic_example/core/Cargo.toml b/examples/tonic_example/core/Cargo.toml index a502e2a5..553921f9 100644 --- a/examples/tonic_example/core/Cargo.toml +++ b/examples/tonic_example/core/Cargo.toml @@ -10,7 +10,7 @@ entity = { path = "../entity" } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version features = [ "debug-print", "runtime-tokio-rustls", diff --git a/examples/tonic_example/entity/Cargo.toml b/examples/tonic_example/entity/Cargo.toml index 95913392..d7f3caec 100644 --- a/examples/tonic_example/entity/Cargo.toml +++ b/examples/tonic_example/entity/Cargo.toml @@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] } [dependencies.sea-orm] path = "../../../" # remove this line in your own project -version = "^0.10.3" # sea-orm version +version = "0.10.3" # sea-orm version diff --git a/examples/tonic_example/migration/Cargo.toml b/examples/tonic_example/migration/Cargo.toml index e2f7eb90..50658028 100644 --- a/examples/tonic_example/migration/Cargo.toml +++ b/examples/tonic_example/migration/Cargo.toml @@ -9,11 +9,11 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] path = "../../../sea-orm-migration" # remove this line in your own project -version = "^0.10.3" # sea-orm-migration version +version = "0.10.3" # sea-orm-migration version features = [ # Enable following runtime and db backend features if you want to run migration via CLI # "runtime-tokio-rustls", diff --git a/issues/1143/Cargo.toml b/issues/1143/Cargo.toml index 6dae314c..a2583faa 100644 --- a/issues/1143/Cargo.toml +++ b/issues/1143/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" publish = false [dependencies] -serde = "^1" -tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] } +serde = "1" +tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } [dependencies.sea-orm] path = "../../" diff --git a/issues/1278/Cargo.toml b/issues/1278/Cargo.toml index 7be6742e..f9be346b 100644 --- a/issues/1278/Cargo.toml +++ b/issues/1278/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" publish = false [dependencies] -serde = "^1" -tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] } +serde = "1" +tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } [dependencies.sea-orm] path = "../../" diff --git a/issues/262/Cargo.toml b/issues/262/Cargo.toml index b397fb8a..6c9ce4e5 100644 --- a/issues/262/Cargo.toml +++ b/issues/262/Cargo.toml @@ -9,4 +9,4 @@ publish = false [dependencies] sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-async-std-native-tls", "debug-print" ] } -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } diff --git a/issues/319/Cargo.toml b/issues/319/Cargo.toml index a60859a4..2269214d 100644 --- a/issues/319/Cargo.toml +++ b/issues/319/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" publish = false [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } -serde = { version = "^1", features = ["derive"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } +serde = { version = "1", features = ["derive"] } sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", diff --git a/issues/630/Cargo.toml b/issues/630/Cargo.toml index 00409cb5..5d9dc1da 100644 --- a/issues/630/Cargo.toml +++ b/issues/630/Cargo.toml @@ -9,8 +9,8 @@ edition = "2021" publish = false [dependencies] -serde = "^1" -tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] } +serde = "1" +tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } [dependencies.sea-orm] path = "../../" diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index bac45ef8..547f23c0 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -31,17 +31,17 @@ path = "src/bin/sea.rs" required-features = ["cli", "codegen"] [dependencies] -clap = { version = "^3.2", features = ["env", "derive"], optional = true } -dotenvy = { version = "^0.15", optional = true } -async-std = { version = "^1.9", features = ["attributes", "tokio1"], optional = true } -sea-orm-codegen = { version = "^0.10.3", path = "../sea-orm-codegen", optional = true } -sea-schema = { version = "^0.10.2" } -sqlx = { version = "^0.6", default-features = false, features = ["mysql", "postgres"], optional = true } -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -tracing = { version = "0.1" } -url = "^2.2" -chrono = { version = "^0.4.20", default-features = false, features = ["clock"] } -regex = "1" +clap = { version = "3.2", default-features = false, features = ["std", "env", "derive"], optional = true } +dotenvy = { version = "0.15", default-features = false, optional = true } +async-std = { version = "1.9", default-features = false, features = ["attributes", "tokio1"], optional = true } +sea-orm-codegen = { version = "=0.10.3", path = "../sea-orm-codegen", default-features = false, optional = true } +sea-schema = { version = "0.10.2" } +sqlx = { version = "0.6", default-features = false, features = ["mysql", "postgres"], optional = true } +tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] } +tracing = { version = "0.1", default-features = false } +url = { version = "2.2", default-features = false } +chrono = { version = "0.4.20", default-features = false, features = ["clock"] } +regex = { version = "1", default-features = false } [dev-dependencies] smol = "1.2.5" diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index 1d797aa0..eafb433a 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -200,6 +200,21 @@ pub enum GenerateSubcommands { )] with_serde: String, + #[clap( + action, + long, + help = "Generate a serde field attribute, '#[serde(skip_deserializing)]', for the primary key fields to skip them during deserialization, this flag will be affective only when '--with-serde' is 'both' or 'deserialize'" + )] + serde_skip_deserializing_primary_key: bool, + + #[clap( + action, + long, + default_value = "false", + help = "Opt-in to add skip attributes to hidden columns (i.e. when 'with-serde' enabled and column name starts with an underscore)" + )] + serde_skip_hidden_column: bool, + #[clap( action, long, @@ -228,6 +243,24 @@ pub enum GenerateSubcommands { help = "Generate index file as `lib.rs` instead of `mod.rs`." )] lib: bool, + + #[clap( + value_parser, + long, + use_value_delimiter = true, + takes_value = true, + help = "Add extra derive macros to generated model structs (comma separated), ex. `--derives 'ts_rs::Ts'`" + )] + model_extra_derives: Vec, + + #[clap( + value_parser, + long, + use_value_delimiter = true, + takes_value = true, + help = r#"Add extra attributes to generated model struct, no need for `#[]` (comma separated), ex. `--attributes 'serde(rename_all = "camelCase")','ts(export)'`"# + )] + model_extra_attributes: Vec, }, } diff --git a/sea-orm-cli/src/commands/generate.rs b/sea-orm-cli/src/commands/generate.rs index 8117c852..1203e4f2 100644 --- a/sea-orm-cli/src/commands/generate.rs +++ b/sea-orm-cli/src/commands/generate.rs @@ -24,9 +24,13 @@ pub async fn run_generate_command( database_schema, database_url, with_serde, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, with_copy_enums, date_time_crate, lib, + model_extra_derives, + model_extra_attributes, } => { if verbose { let _ = tracing_subscriber::fmt() @@ -159,11 +163,15 @@ pub async fn run_generate_command( let writer_context = EntityWriterContext::new( expanded_format, - WithSerde::from_str(&with_serde).unwrap(), + WithSerde::from_str(&with_serde).expect("Invalid serde derive option"), with_copy_enums, date_time_crate.into(), schema_name, lib, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + model_extra_derives, + model_extra_attributes, ); let output = EntityTransformer::transform(table_stmts)?.generate(&writer_context); diff --git a/sea-orm-cli/src/commands/migrate.rs b/sea-orm-cli/src/commands/migrate.rs index 8931ea5b..c7fbaea5 100644 --- a/sea-orm-cli/src/commands/migrate.rs +++ b/sea-orm-cli/src/commands/migrate.rs @@ -101,7 +101,7 @@ pub fn run_migrate_init(migration_dir: &str) -> Result<(), Box> { write_file!("src/main.rs"); write_file!("Cargo.toml", "_Cargo.toml", |content: String| { let ver = format!( - "^{}.{}.0", + "{}.{}.0", env!("CARGO_PKG_VERSION_MAJOR"), env!("CARGO_PKG_VERSION_MINOR") ); diff --git a/sea-orm-cli/template/migration/_Cargo.toml b/sea-orm-cli/template/migration/_Cargo.toml index 03cb031e..2c674f23 100644 --- a/sea-orm-cli/template/migration/_Cargo.toml +++ b/sea-orm-cli/template/migration/_Cargo.toml @@ -9,7 +9,7 @@ name = "migration" path = "src/lib.rs" [dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] version = "" diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index 3bba86e0..0601dfbc 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -17,17 +17,12 @@ name = "sea_orm_codegen" path = "src/lib.rs" [dependencies] -sea-query = { version = "^0.27.1", features = ["thread-safe"] } -syn = { version = "^1", default-features = false, features = [ - "derive", - "parsing", - "proc-macro", - "printing", -] } -quote = "^1" -heck = "^0.3" -proc-macro2 = "^1" -tracing = { version = "0.1", features = ["log"] } +sea-query = { version = "0.27.1", default-features = false, features = ["thread-safe"] } +syn = { version = "1", default-features = false } +quote = { version = "1", default-features = false } +heck = { version = "0.3", default-features = false } +proc-macro2 = { version = "1", default-features = false } +tracing = { version = "0.1", default-features = false, features = ["log"] } [dev-dependencies] -pretty_assertions = { version = "^0.7" } +pretty_assertions = { version = "0.7" } diff --git a/sea-orm-codegen/src/entity/base_entity.rs b/sea-orm-codegen/src/entity/base_entity.rs index 85d19aa5..7a79f600 100644 --- a/sea-orm-codegen/src/entity/base_entity.rs +++ b/sea-orm-codegen/src/entity/base_entity.rs @@ -166,6 +166,24 @@ impl Entity { // if exist, return nothing .map_or(quote! {, Eq}, |_| quote! {}) } + + pub fn get_column_serde_attributes( + &self, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + ) -> Vec { + self.columns + .iter() + .map(|col| { + let is_primary_key = self.primary_keys.iter().any(|pk| pk.name == col.name); + col.get_serde_attribute( + is_primary_key, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + ) + }) + .collect() + } } #[cfg(test)] @@ -204,6 +222,7 @@ mod tests { on_update: Some(ForeignKeyAction::Cascade), self_referencing: false, num_suffix: 0, + impl_related: true, }, Relation { ref_table: "filling".to_owned(), @@ -214,6 +233,7 @@ mod tests { on_update: Some(ForeignKeyAction::Cascade), self_referencing: false, num_suffix: 0, + impl_related: true, }, ], conjunct_relations: vec![], diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index 298176f4..5e2a6f57 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -211,6 +211,25 @@ impl Column { } info } + + pub fn get_serde_attribute( + &self, + is_primary_key: bool, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + ) -> TokenStream { + if self.name.starts_with('_') && serde_skip_hidden_column { + quote! { + #[serde(skip)] + } + } else if serde_skip_deserializing_primary_key && is_primary_key { + quote! { + #[serde(skip_deserializing)] + } + } else { + quote! {} + } + } } impl From for Column { diff --git a/sea-orm-codegen/src/entity/relation.rs b/sea-orm-codegen/src/entity/relation.rs index 2c29eef9..ce7b9d82 100644 --- a/sea-orm-codegen/src/entity/relation.rs +++ b/sea-orm-codegen/src/entity/relation.rs @@ -23,6 +23,7 @@ pub struct Relation { pub(crate) on_delete: Option, pub(crate) self_referencing: bool, pub(crate) num_suffix: usize, + pub(crate) impl_related: bool, } impl Relation { @@ -178,6 +179,7 @@ impl From<&TableForeignKey> for Relation { on_update, self_referencing: false, num_suffix: 0, + impl_related: true, } } } @@ -199,6 +201,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }, Relation { ref_table: "filling".to_owned(), @@ -209,6 +212,7 @@ mod tests { on_update: Some(ForeignKeyAction::Cascade), self_referencing: false, num_suffix: 0, + impl_related: true, }, Relation { ref_table: "filling".to_owned(), @@ -219,6 +223,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }, ] } diff --git a/sea-orm-codegen/src/entity/transformer.rs b/sea-orm-codegen/src/entity/transformer.rs index 282d0393..53006cbe 100644 --- a/sea-orm-codegen/src/entity/transformer.rs +++ b/sea-orm-codegen/src/entity/transformer.rs @@ -197,13 +197,23 @@ impl EntityTransformer { } for (tbl_name, mut conjunct_relations) in conjunct_relations.into_iter() { if let Some(entity) = entities.get_mut(&tbl_name) { + for relation in entity.relations.iter_mut() { + // Skip `impl Related ... { fn to() ... }` implementation block, + // if the same related entity is being referenced by a conjunct relation + if conjunct_relations + .iter() + .any(|conjunct_relation| conjunct_relation.to == relation.ref_table) + { + relation.impl_related = false; + } + } entity.conjunct_relations.append(&mut conjunct_relations); } } Ok(EntityWriter { entities: entities - .into_iter() - .map(|(_, mut v)| { + .into_values() + .map(|mut v| { v.relations.sort_by(|a, b| a.ref_table.cmp(&b.ref_table)); v }) diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 6b62cac1..5da97365 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -43,6 +43,10 @@ pub struct EntityWriterContext { pub(crate) date_time_crate: DateTimeCrate, pub(crate) schema_name: Option, pub(crate) lib: bool, + pub(crate) serde_skip_hidden_column: bool, + pub(crate) serde_skip_deserializing_primary_key: bool, + pub(crate) model_extra_derives: TokenStream, + pub(crate) model_extra_attributes: TokenStream, } impl WithSerde { @@ -67,15 +71,44 @@ impl WithSerde { } } }; - if !extra_derive.is_empty() { extra_derive = quote! { , #extra_derive } } - extra_derive } } +/// Converts model_extra_derives argument to token stream +fn bonus_derive(model_extra_derives: Vec) -> TokenStream +where + T: Into, +{ + model_extra_derives + .into_iter() + .map(Into::::into) + .fold(TokenStream::default(), |acc, derive| { + let tokens: TokenStream = derive.parse().unwrap(); + quote! { #acc, #tokens } + }) +} + +/// convert attributes argument to token stream +fn bonus_attributes(attributes: Vec) -> TokenStream +where + T: Into, +{ + attributes.into_iter().map(Into::::into).fold( + TokenStream::default(), + |acc, attribute| { + let tokens: TokenStream = attribute.parse().unwrap(); + quote! { + #acc + #[#tokens] + } + }, + ) +} + impl FromStr for WithSerde { type Err = crate::Error; @@ -96,6 +129,7 @@ impl FromStr for WithSerde { } impl EntityWriterContext { + #[allow(clippy::too_many_arguments)] pub fn new( expanded_format: bool, with_serde: WithSerde, @@ -103,6 +137,10 @@ impl EntityWriterContext { date_time_crate: DateTimeCrate, schema_name: Option, lib: bool, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + model_extra_derives: Vec, + model_extra_attributes: Vec, ) -> Self { Self { expanded_format, @@ -111,6 +149,10 @@ impl EntityWriterContext { date_time_crate, schema_name, lib, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + model_extra_derives: bonus_derive(model_extra_derives), + model_extra_attributes: bonus_attributes(model_extra_attributes), } } } @@ -139,6 +181,15 @@ impl EntityWriter { .iter() .map(|column| column.get_info(&context.date_time_crate)) .collect::>(); + // Serde must be enabled to use this + let serde_skip_deserializing_primary_key = context + .serde_skip_deserializing_primary_key + && matches!(context.with_serde, WithSerde::Both | WithSerde::Deserialize); + let serde_skip_hidden_column = context.serde_skip_hidden_column + && matches!( + context.with_serde, + WithSerde::Both | WithSerde::Serialize | WithSerde::Deserialize + ); info!("Generating {}", entity_file); for info in column_info.iter() { @@ -153,6 +204,10 @@ impl EntityWriter { &context.with_serde, &context.date_time_crate, &context.schema_name, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + &context.model_extra_derives, + &context.model_extra_attributes, ) } else { Self::gen_compact_code_blocks( @@ -160,6 +215,10 @@ impl EntityWriter { &context.with_serde, &context.date_time_crate, &context.schema_name, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + &context.model_extra_derives, + &context.model_extra_attributes, ) }; Self::write(&mut lines, code_blocks); @@ -225,8 +284,8 @@ impl EntityWriter { lines.push("".to_owned()); let code_blocks = self .enums - .iter() - .map(|(_, active_enum)| active_enum.impl_active_enum(with_serde, with_copy_enums)) + .values() + .map(|active_enum| active_enum.impl_active_enum(with_serde, with_copy_enums)) .collect(); Self::write(&mut lines, code_blocks); OutputFile { @@ -254,11 +313,16 @@ impl EntityWriter { lines.push("".to_owned()); } + #[allow(clippy::too_many_arguments)] pub fn gen_expanded_code_blocks( entity: &Entity, with_serde: &WithSerde, date_time_crate: &DateTimeCrate, schema_name: &Option, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + model_extra_derives: &TokenStream, + model_extra_attributes: &TokenStream, ) -> Vec { let mut imports = Self::gen_import(with_serde); imports.extend(Self::gen_import_active_enum(entity)); @@ -266,7 +330,15 @@ impl EntityWriter { imports, Self::gen_entity_struct(), Self::gen_impl_entity_name(entity, schema_name), - Self::gen_model_struct(entity, with_serde, date_time_crate), + Self::gen_model_struct( + entity, + with_serde, + date_time_crate, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + model_extra_derives, + model_extra_attributes, + ), Self::gen_column_enum(entity), Self::gen_primary_key_enum(entity), Self::gen_impl_primary_key(entity, date_time_crate), @@ -280,17 +352,31 @@ impl EntityWriter { code_blocks } + #[allow(clippy::too_many_arguments)] pub fn gen_compact_code_blocks( entity: &Entity, with_serde: &WithSerde, date_time_crate: &DateTimeCrate, schema_name: &Option, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + model_extra_derives: &TokenStream, + model_extra_attributes: &TokenStream, ) -> Vec { let mut imports = Self::gen_import(with_serde); imports.extend(Self::gen_import_active_enum(entity)); let mut code_blocks = vec![ imports, - Self::gen_compact_model_struct(entity, with_serde, date_time_crate, schema_name), + Self::gen_compact_model_struct( + entity, + with_serde, + date_time_crate, + schema_name, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + model_extra_derives, + model_extra_attributes, + ), Self::gen_compact_relation_enum(entity), ]; code_blocks.extend(Self::gen_impl_related(entity)); @@ -312,14 +398,12 @@ impl EntityWriter { use serde::Serialize; } } - WithSerde::Deserialize => { quote! { #prelude_import use serde::Deserialize; } } - WithSerde::Both => { quote! { #prelude_import @@ -378,16 +462,28 @@ impl EntityWriter { entity: &Entity, with_serde: &WithSerde, date_time_crate: &DateTimeCrate, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + model_extra_derives: &TokenStream, + model_extra_attributes: &TokenStream, ) -> TokenStream { let column_names_snake_case = entity.get_column_names_snake_case(); let column_rs_types = entity.get_column_rs_types(date_time_crate); let if_eq_needed = entity.get_eq_needed(); + let serde_attributes = entity.get_column_serde_attributes( + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + ); let extra_derive = with_serde.extra_derive(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive)] + #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #model_extra_derives)] + #model_extra_attributes pub struct Model { - #(pub #column_names_snake_case: #column_rs_types,)* + #( + #serde_attributes + pub #column_names_snake_case: #column_rs_types, + )* } } } @@ -490,7 +586,7 @@ impl EntityWriter { entity .relations .iter() - .filter(|rel| !rel.self_referencing && rel.num_suffix == 0) + .filter(|rel| !rel.self_referencing && rel.num_suffix == 0 && rel.impl_related) .map(|rel| { let enum_name = rel.get_enum_name(); let module_name = rel.get_module_name(); @@ -561,11 +657,16 @@ impl EntityWriter { } } + #[allow(clippy::too_many_arguments)] pub fn gen_compact_model_struct( entity: &Entity, with_serde: &WithSerde, date_time_crate: &DateTimeCrate, schema_name: &Option, + serde_skip_deserializing_primary_key: bool, + serde_skip_hidden_column: bool, + model_extra_derives: &TokenStream, + model_extra_attributes: &TokenStream, ) -> TokenStream { let table_name = entity.table_name.as_str(); let column_names_snake_case = entity.get_column_names_snake_case(); @@ -581,11 +682,12 @@ impl EntityWriter { .iter() .map(|col| { let mut attrs: Punctuated<_, Comma> = Punctuated::new(); + let is_primary_key = primary_keys.contains(&col.name); if !col.is_snake_case_name() { let column_name = &col.name; attrs.push(quote! { column_name = #column_name }); } - if primary_keys.contains(&col.name) { + if is_primary_key { attrs.push(quote! { primary_key }); if !col.auto_increment { attrs.push(quote! { auto_increment = false }); @@ -600,20 +702,26 @@ impl EntityWriter { if col.unique { attrs.push(quote! { unique }); } + let mut ts = quote! {}; if !attrs.is_empty() { - let mut ts = TokenStream::new(); for (i, attr) in attrs.into_iter().enumerate() { if i > 0 { ts = quote! { #ts, }; } ts = quote! { #ts #attr }; } - quote! { - #[sea_orm(#ts)] - } - } else { - TokenStream::new() + ts = quote! { #[sea_orm(#ts)] }; } + let serde_attribute = col.get_serde_attribute( + is_primary_key, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + ); + ts = quote! { + #ts + #serde_attribute + }; + ts }) .collect(); let schema_name = match Self::gen_schema_name(schema_name) { @@ -625,11 +733,12 @@ impl EntityWriter { let extra_derive = with_serde.extra_derive(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive)] + #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive #model_extra_derives)] #[sea_orm( #schema_name table_name = #table_name )] + #model_extra_attributes pub struct Model { #( #attrs @@ -670,6 +779,7 @@ impl EntityWriter { #[cfg(test)] mod tests { use crate::{ + entity::writer::{bonus_attributes, bonus_derive}, Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation, RelationType, WithSerde, }; @@ -707,6 +817,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }], conjunct_relations: vec![ConjunctRelation { via: "cake_filling".to_owned(), @@ -744,6 +855,7 @@ mod tests { on_update: Some(ForeignKeyAction::Cascade), self_referencing: false, num_suffix: 0, + impl_related: true, }, Relation { ref_table: "filling".to_owned(), @@ -754,6 +866,7 @@ mod tests { on_update: Some(ForeignKeyAction::Cascade), self_referencing: false, num_suffix: 0, + impl_related: true, }, ], conjunct_relations: vec![], @@ -828,6 +941,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }, Relation { ref_table: "vendor".to_owned(), @@ -838,6 +952,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }, ], conjunct_relations: vec![], @@ -879,6 +994,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }], conjunct_relations: vec![], primary_keys: vec![PrimaryKey { @@ -990,6 +1106,7 @@ mod tests { on_update: None, self_referencing: true, num_suffix: 1, + impl_related: true, }, Relation { ref_table: "rust_keyword".to_owned(), @@ -1000,6 +1117,7 @@ mod tests { on_update: None, self_referencing: true, num_suffix: 2, + impl_related: true, }, Relation { ref_table: "fruit".to_owned(), @@ -1010,6 +1128,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 1, + impl_related: true, }, Relation { ref_table: "fruit".to_owned(), @@ -1020,6 +1139,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 2, + impl_related: true, }, Relation { ref_table: "cake".to_owned(), @@ -1030,6 +1150,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }, ], conjunct_relations: vec![], @@ -1071,6 +1192,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }], conjunct_relations: vec![ConjunctRelation { via: "cake_filling".to_owned(), @@ -1114,6 +1236,7 @@ mod tests { on_update: None, self_referencing: false, num_suffix: 0, + impl_related: true, }], conjunct_relations: vec![ConjunctRelation { via: "cake_filling".to_owned(), @@ -1247,7 +1370,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &None + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1263,7 +1390,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &Some("public".to_owned()) + &Some("public".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1279,7 +1410,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &Some("schema_name".to_owned()) + &Some("schema_name".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1331,7 +1466,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &None + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1347,7 +1486,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &Some("public".to_owned()) + &Some("public".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1363,7 +1506,11 @@ mod tests { entity, &crate::WithSerde::None, &crate::DateTimeCrate::Chrono, - &Some("schema_name".to_owned()) + &Some("schema_name".to_owned()), + false, + false, + &TokenStream::new(), + &TokenStream::new(), ) .into_iter() .skip(1) @@ -1385,76 +1532,241 @@ mod tests { assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); // Compact code blocks - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_none.rs").into(), - WithSerde::None, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_serialize.rs").into(), - WithSerde::Serialize, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_deserialize.rs").into(), - WithSerde::Deserialize, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_both.rs").into(), - WithSerde::Both, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_serde/cake_serialize.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Serialize, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_serde/cake_deserialize.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Deserialize, + &DateTimeCrate::Chrono, + &None, + true, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_both.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Both, + &DateTimeCrate::Chrono, + &None, + true, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); // Expanded code blocks + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_serde/cake_serialize.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Serialize, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_serde/cake_deserialize.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Deserialize, + &DateTimeCrate::Chrono, + &None, + true, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_both.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Both, + &DateTimeCrate::Chrono, + &None, + true, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + + Ok(()) + } + + #[test] + fn test_gen_with_derives() -> io::Result<()> { + let mut cake_entity = setup().get_mut(0).unwrap().clone(); + + assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); + + // Compact code blocks + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_derives/cake_none.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_derives/cake_one.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &bonus_derive(vec!["ts_rs::TS"]), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_derives/cake_multiple.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &bonus_derive(vec!["ts_rs::TS", "utoipa::ToSchema"]), + &TokenStream::new(), + )) + ); + + // Expanded code blocks + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_none.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_one.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &bonus_derive(vec!["ts_rs::TS"]), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_multiple.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &bonus_derive(vec!["ts_rs::TS", "utoipa::ToSchema"]), + &TokenStream::new(), + )) + ); + + // Make the `name` column of `cake` entity as hidden column + cake_entity.columns[1].name = "_name".into(); + assert_serde_variant_results( &cake_entity, &( - include_str!("../../tests/expanded_with_serde/cake_none.rs").into(), - WithSerde::None, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_serialize.rs").into(), + include_str!("../../tests/compact_with_serde/cake_serialize_with_hidden_column.rs"), WithSerde::Serialize, None, ), - Box::new(EntityWriter::gen_expanded_code_blocks), + Box::new(EntityWriter::gen_compact_code_blocks), )?; assert_serde_variant_results( &cake_entity, &( - include_str!("../../tests/expanded_with_serde/cake_deserialize.rs").into(), - WithSerde::Deserialize, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_both.rs").into(), - WithSerde::Both, + include_str!( + "../../tests/expanded_with_serde/cake_serialize_with_hidden_column.rs" + ), + WithSerde::Serialize, None, ), Box::new(EntityWriter::gen_expanded_code_blocks), @@ -1466,13 +1778,174 @@ mod tests { #[allow(clippy::type_complexity)] fn assert_serde_variant_results( cake_entity: &Entity, - entity_serde_variant: &(String, WithSerde, Option), + entity_serde_variant: &(&str, WithSerde, Option), generator: Box< - dyn Fn(&Entity, &WithSerde, &DateTimeCrate, &Option) -> Vec, + dyn Fn( + &Entity, + &WithSerde, + &DateTimeCrate, + &Option, + bool, + bool, + &TokenStream, + &TokenStream, + ) -> Vec, >, ) -> io::Result<()> { let mut reader = BufReader::new(entity_serde_variant.0.as_bytes()); let mut lines: Vec = Vec::new(); + let serde_skip_deserializing_primary_key = matches!( + entity_serde_variant.1, + WithSerde::Both | WithSerde::Deserialize + ); + let serde_skip_hidden_column = matches!(entity_serde_variant.1, WithSerde::Serialize); + + reader.read_until(b'\n', &mut Vec::new())?; + + let mut line = String::new(); + while reader.read_line(&mut line)? > 0 { + lines.push(line.to_owned()); + line.clear(); + } + let content = lines.join(""); + let expected: TokenStream = content.parse().unwrap(); + println!("{:?}", entity_serde_variant.1); + let generated = generator( + cake_entity, + &entity_serde_variant.1, + &DateTimeCrate::Chrono, + &entity_serde_variant.2, + serde_skip_deserializing_primary_key, + serde_skip_hidden_column, + &TokenStream::new(), + &TokenStream::new(), + ) + .into_iter() + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }); + + assert_eq!(expected.to_string(), generated.to_string()); + Ok(()) + } + + #[test] + fn test_gen_with_attributes() -> io::Result<()> { + let cake_entity = setup().get(0).unwrap().clone(); + + assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); + + // Compact code blocks + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_none.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_one.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#]), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_multiple.rs" + ))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#, "ts(export)"]), + )) + ); + + // Expanded code blocks + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_none.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &TokenStream::new(), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_one.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#]), + )) + ); + assert_eq!( + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_multiple.rs" + ))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &DateTimeCrate::Chrono, + &None, + false, + false, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#, "ts(export)"]), + )) + ); + + Ok(()) + } + + fn generated_to_string(generated: Vec) -> String { + generated + .into_iter() + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }) + .to_string() + } + + fn comparable_file_string(file: &str) -> io::Result { + let mut reader = BufReader::new(file.as_bytes()); + let mut lines: Vec = Vec::new(); reader.read_until(b'\n', &mut Vec::new())?; @@ -1483,19 +1956,7 @@ mod tests { } let content = lines.join(""); let expected: TokenStream = content.parse().unwrap(); - let generated = generator( - cake_entity, - &entity_serde_variant.1, - &DateTimeCrate::Chrono, - &entity_serde_variant.2, - ) - .into_iter() - .fold(TokenStream::new(), |mut acc, tok| { - acc.extend(tok); - acc - }); - assert_eq!(expected.to_string(), generated.to_string()); - Ok(()) + Ok(expected.to_string()) } } diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs new file mode 100644 index 00000000..795a3b9b --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs @@ -0,0 +1,37 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs new file mode 100644 index 00000000..d72ea6b2 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs new file mode 100644 index 00000000..11162ca1 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs @@ -0,0 +1,36 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +#[serde(rename_all = "camelCase")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs b/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs new file mode 100644 index 00000000..dd69de77 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, ts_rs::TS, utoipa::ToSchema)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_none.rs b/sea-orm-codegen/tests/compact_with_derives/cake_none.rs new file mode 100644 index 00000000..d72ea6b2 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_none.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_one.rs b/sea-orm-codegen/tests/compact_with_derives/cake_one.rs new file mode 100644 index 00000000..9a4aeaba --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_one.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, ts_rs::TS)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_serde/cake_both.rs b/sea-orm-codegen/tests/compact_with_serde/cake_both.rs index 54d3cd16..fa893a5c 100644 --- a/sea-orm-codegen/tests/compact_with_serde/cake_both.rs +++ b/sea-orm-codegen/tests/compact_with_serde/cake_both.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; #[sea_orm(table_name = "cake")] pub struct Model { #[sea_orm(primary_key)] + #[serde(skip_deserializing)] pub id: i32, #[sea_orm(column_type = "Text", nullable)] pub name: Option , diff --git a/sea-orm-codegen/tests/compact_with_serde/cake_deserialize.rs b/sea-orm-codegen/tests/compact_with_serde/cake_deserialize.rs index f11569e4..620bdf67 100644 --- a/sea-orm-codegen/tests/compact_with_serde/cake_deserialize.rs +++ b/sea-orm-codegen/tests/compact_with_serde/cake_deserialize.rs @@ -7,6 +7,7 @@ use serde::Deserialize; #[sea_orm(table_name = "cake")] pub struct Model { #[sea_orm(primary_key)] + #[serde(skip_deserializing)] pub id: i32, #[sea_orm(column_type = "Text", nullable)] pub name: Option , diff --git a/sea-orm-codegen/tests/compact_with_serde/cake_serialize_with_hidden_column.rs b/sea-orm-codegen/tests/compact_with_serde/cake_serialize_with_hidden_column.rs new file mode 100644 index 00000000..50aa9dcb --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_serde/cake_serialize_with_hidden_column.rs @@ -0,0 +1,37 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; +use serde::Serialize; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_name = "_name", column_type = "Text", nullable)] + #[serde(skip)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs new file mode 100644 index 00000000..5c498d83 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs @@ -0,0 +1,79 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs new file mode 100644 index 00000000..a540fad1 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs new file mode 100644 index 00000000..77da3181 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs @@ -0,0 +1,78 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs new file mode 100644 index 00000000..c04dfdd4 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq, ts_rs::TS, utoipa::ToSchema)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs new file mode 100644 index 00000000..a540fad1 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs new file mode 100644 index 00000000..a4ebdf82 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +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, Eq, ts_rs::TS)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_serde/cake_both.rs b/sea-orm-codegen/tests/expanded_with_serde/cake_both.rs index 924887b4..40c9e998 100644 --- a/sea-orm-codegen/tests/expanded_with_serde/cake_both.rs +++ b/sea-orm-codegen/tests/expanded_with_serde/cake_both.rs @@ -14,6 +14,7 @@ impl EntityName for Entity { #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize, Deserialize)] pub struct Model { + #[serde(skip_deserializing)] pub id: i32, pub name: Option , } diff --git a/sea-orm-codegen/tests/expanded_with_serde/cake_deserialize.rs b/sea-orm-codegen/tests/expanded_with_serde/cake_deserialize.rs index 88a7c3a9..ec201073 100644 --- a/sea-orm-codegen/tests/expanded_with_serde/cake_deserialize.rs +++ b/sea-orm-codegen/tests/expanded_with_serde/cake_deserialize.rs @@ -14,6 +14,7 @@ impl EntityName for Entity { #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Deserialize)] pub struct Model { + #[serde(skip_deserializing)] pub id: i32, pub name: Option , } diff --git a/sea-orm-codegen/tests/expanded_with_serde/cake_serialize_with_hidden_column.rs b/sea-orm-codegen/tests/expanded_with_serde/cake_serialize_with_hidden_column.rs new file mode 100644 index 00000000..74db3085 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_serde/cake_serialize_with_hidden_column.rs @@ -0,0 +1,80 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; +use serde::Serialize; + +#[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, Eq, Serialize)] +pub struct Model { + pub id: i32, + #[serde(skip)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + #[sea_orm(column_name = "_name")] + 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)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-macros/Cargo.toml b/sea-orm-macros/Cargo.toml index 05ccc7e8..adaefe21 100644 --- a/sea-orm-macros/Cargo.toml +++ b/sea-orm-macros/Cargo.toml @@ -18,15 +18,15 @@ path = "src/lib.rs" proc-macro = true [dependencies] -bae = "^0.1" -syn = { version = "^1", default-features = false, features = [ "full", "derive", "clone-impls", "parsing", "proc-macro", "printing", "extra-traits" ] } -quote = "^1" -heck = "^0.3" -proc-macro2 = "^1" +bae = { version = "0.1", default-features = false } +syn = { version = "1", default-features = false } +quote = { version = "1", default-features = false } +heck = { version = "0.3", default-features = false } +proc-macro2 = { version = "1", default-features = false } [dev-dependencies] sea-orm = { path = "../", features = ["macros"] } -serde = { version = "^1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } [features] postgres-array = [] diff --git a/sea-orm-migration/Cargo.toml b/sea-orm-migration/Cargo.toml index 72bd37cf..d1d96082 100644 --- a/sea-orm-migration/Cargo.toml +++ b/sea-orm-migration/Cargo.toml @@ -20,17 +20,17 @@ name = "sea_orm_migration" path = "src/lib.rs" [dependencies] -async-trait = { version = "^0.1" } -clap = { version = "^3.2", features = ["env", "derive"], optional = true } -dotenvy = { version = "^0.15", optional = true } -sea-orm = { version = "^0.10.3", path = "../", default-features = false, features = ["macros"] } -sea-orm-cli = { version = "^0.10.3", path = "../sea-orm-cli", default-features = false, optional = true } -sea-schema = { version = "^0.10.2" } -tracing = { version = "0.1", features = ["log"] } -tracing-subscriber = { version = "0.3", features = ["env-filter"] } +async-trait = { version = "0.1", default-features = false } +clap = { version = "3.2", default-features = false, features = ["std", "env", "derive"], optional = true } +dotenvy = { version = "0.15", default-features = false, optional = true } +sea-orm = { version = "0.10.3", path = "../", default-features = false, features = ["macros"] } +sea-orm-cli = { version = "0.10.3", path = "../sea-orm-cli", default-features = false, optional = true } +sea-schema = { version = "0.10.2" } +tracing = { version = "0.1", default-features = false, features = ["log"] } +tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] } [dev-dependencies] -async-std = { version = "^1", features = ["attributes", "tokio1"] } +async-std = { version = "1", features = ["attributes", "tokio1"] } [features] default = ["cli"] diff --git a/src/database/transaction.rs b/src/database/transaction.rs index bfb6f2bb..fa8d5775 100644 --- a/src/database/transaction.rs +++ b/src/database/transaction.rs @@ -174,9 +174,8 @@ impl DatabaseTransaction { /// Commit a transaction atomically #[instrument(level = "trace")] - #[allow(unreachable_code)] + #[allow(unreachable_code, unused_mut)] pub async fn commit(mut self) -> Result<(), DbErr> { - self.open = false; match *self.conn.lock().await { #[cfg(feature = "sqlx-mysql")] InnerConnection::MySql(ref mut c) => { @@ -201,14 +200,14 @@ impl DatabaseTransaction { c.commit(); } } + self.open = false; Ok(()) } /// rolls back a transaction in case error are encountered during the operation #[instrument(level = "trace")] - #[allow(unreachable_code)] + #[allow(unreachable_code, unused_mut)] pub async fn rollback(mut self) -> Result<(), DbErr> { - self.open = false; match *self.conn.lock().await { #[cfg(feature = "sqlx-mysql")] InnerConnection::MySql(ref mut c) => { @@ -233,6 +232,7 @@ impl DatabaseTransaction { c.rollback(); } } + self.open = false; Ok(()) } diff --git a/src/entity/relation.rs b/src/entity/relation.rs index 06e22a29..9e3c565e 100644 --- a/src/entity/relation.rs +++ b/src/entity/relation.rs @@ -1,6 +1,9 @@ -use crate::{EntityTrait, Identity, IdentityOf, Iterable, QuerySelect, Select}; +use crate::{unpack_table_ref, EntityTrait, Identity, IdentityOf, Iterable, QuerySelect, Select}; use core::marker::PhantomData; -use sea_query::{Alias, Condition, DynIden, JoinType, SeaRc, TableRef}; +use sea_query::{ + Alias, Condition, DynIden, ForeignKeyCreateStatement, JoinType, SeaRc, TableForeignKey, + TableRef, +}; use std::fmt::Debug; /// Defines the type of relationship @@ -309,6 +312,98 @@ where } } +macro_rules! set_foreign_key_stmt { + ( $relation: ident, $foreign_key: ident ) => { + let from_cols: Vec = match $relation.from_col { + Identity::Unary(o1) => vec![o1], + Identity::Binary(o1, o2) => vec![o1, o2], + Identity::Ternary(o1, o2, o3) => vec![o1, o2, o3], + } + .into_iter() + .map(|col| { + let col_name = col.to_string(); + $foreign_key.from_col(col); + col_name + }) + .collect(); + match $relation.to_col { + Identity::Unary(o1) => { + $foreign_key.to_col(o1); + } + Identity::Binary(o1, o2) => { + $foreign_key.to_col(o1); + $foreign_key.to_col(o2); + } + Identity::Ternary(o1, o2, o3) => { + $foreign_key.to_col(o1); + $foreign_key.to_col(o2); + $foreign_key.to_col(o3); + } + } + if let Some(action) = $relation.on_delete { + $foreign_key.on_delete(action); + } + if let Some(action) = $relation.on_update { + $foreign_key.on_update(action); + } + let name = if let Some(name) = $relation.fk_name { + name + } else { + let from_tbl = unpack_table_ref(&$relation.from_tbl); + format!("fk-{}-{}", from_tbl.to_string(), from_cols.join("-")) + }; + $foreign_key.name(&name); + }; +} + +impl From for ForeignKeyCreateStatement { + fn from(relation: RelationDef) -> Self { + let mut foreign_key_stmt = Self::new(); + set_foreign_key_stmt!(relation, foreign_key_stmt); + foreign_key_stmt + .from_tbl(unpack_table_ref(&relation.from_tbl)) + .to_tbl(unpack_table_ref(&relation.to_tbl)) + .take() + } +} + +/// Creates a column definition for example to update a table. +/// ``` +/// use sea_query::{Alias, IntoIden, MysqlQueryBuilder, TableAlterStatement, TableRef}; +/// use sea_orm::{EnumIter, Iden, Identity, PrimaryKeyTrait, RelationDef, RelationTrait, RelationType}; +/// +/// let relation = RelationDef { +/// rel_type: RelationType::HasOne, +/// from_tbl: TableRef::Table(Alias::new("foo").into_iden()), +/// to_tbl: TableRef::Table(Alias::new("bar").into_iden()), +/// from_col: Identity::Unary(Alias::new("bar_id").into_iden()), +/// to_col: Identity::Unary(Alias::new("bar_id").into_iden()), +/// is_owner: false, +/// on_delete: None, +/// on_update: None, +/// on_condition: None, +/// fk_name: Some("foo-bar".to_string()), +/// }; +/// +/// let mut alter_table = TableAlterStatement::new() +/// .table(TableRef::Table(Alias::new("foo").into_iden())) +/// .add_foreign_key(&mut relation.into()).take(); +/// assert_eq!( +/// alter_table.to_string(MysqlQueryBuilder::default()), +/// "ALTER TABLE `foo` ADD CONSTRAINT `foo-bar` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`)" +/// ); +/// ``` +impl From for TableForeignKey { + fn from(relation: RelationDef) -> Self { + let mut foreign_key = Self::new(); + set_foreign_key_stmt!(relation, foreign_key); + foreign_key + .from_tbl(unpack_table_ref(&relation.from_tbl)) + .to_tbl(unpack_table_ref(&relation.to_tbl)) + .take() + } +} + #[cfg(test)] mod tests { use crate::{ diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs index 60811323..f56d8a32 100644 --- a/src/executor/paginator.rs +++ b/src/executor/paginator.rs @@ -45,8 +45,8 @@ where let query = self .query .clone() - .limit(self.page_size as u64) - .offset((self.page_size * page) as u64) + .limit(self.page_size) + .offset(self.page_size * page) .to_owned(); let builder = self.db.get_database_backend(); let stmt = builder.build(&query); diff --git a/src/query/update.rs b/src/query/update.rs index b5d404a0..8d5de747 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -189,7 +189,8 @@ where for col in E::Column::iter() { let av = model.get(col); if av.is_set() { - self.query.value(col, av.unwrap()); + let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col); + self.query.value(col, expr); } } self @@ -207,7 +208,7 @@ where #[cfg(test)] mod tests { - use crate::tests_cfg::{cake, fruit}; + use crate::tests_cfg::{cake, fruit, lunch_set, sea_orm_active_enums::Tea}; use crate::{entity::*, query::*, DbBackend}; use sea_query::{Expr, Value}; @@ -294,4 +295,33 @@ mod tests { r#"UPDATE "fruit" SET "id" = 3 WHERE "fruit"."id" = 2"#, ); } + + #[test] + fn update_7() { + assert_eq!( + Update::many(lunch_set::Entity) + .set(lunch_set::ActiveModel { + tea: Set(Tea::EverydayTea), + ..Default::default() + }) + .filter(lunch_set::Column::Tea.eq(Tea::BreakfastTea)) + .build(DbBackend::Postgres) + .to_string(), + r#"UPDATE "lunch_set" SET "tea" = CAST('EverydayTea' AS tea) WHERE "lunch_set"."tea" = CAST('BreakfastTea' AS tea)"#, + ); + } + + #[test] + fn update_8() { + assert_eq!( + Update::one(lunch_set::ActiveModel { + id: Unchanged(1), + tea: Set(Tea::EverydayTea), + ..Default::default() + }) + .build(DbBackend::Postgres) + .to_string(), + r#"UPDATE "lunch_set" SET "tea" = CAST('EverydayTea' AS tea) WHERE "lunch_set"."id" = 1"#, + ); + } } diff --git a/src/schema/entity.rs b/src/schema/entity.rs index 28bca9d5..c1d23d83 100644 --- a/src/schema/entity.rs +++ b/src/schema/entity.rs @@ -1,10 +1,10 @@ use crate::{ - unpack_table_ref, ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, Identity, - Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, RelationTrait, Schema, + ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, Iterable, PrimaryKeyToColumn, + PrimaryKeyTrait, RelationTrait, Schema, }; use sea_query::{ extension::postgres::{Type, TypeCreateStatement}, - ColumnDef, ForeignKeyCreateStatement, Iden, Index, IndexCreateStatement, TableCreateStatement, + ColumnDef, Iden, Index, IndexCreateStatement, TableCreateStatement, }; impl Schema { @@ -40,6 +40,51 @@ impl Schema { { create_index_from_entity(entity, self.backend) } + + /// Creates a column definition for example to update a table. + /// ``` + /// use crate::sea_orm::IdenStatic; + /// use sea_orm::{ + /// ActiveModelBehavior, ColumnDef, ColumnTrait, ColumnType, DbBackend, EntityName, + /// EntityTrait, EnumIter, PrimaryKeyTrait, RelationDef, RelationTrait, Schema, + /// }; + /// use sea_orm_macros::{DeriveEntityModel, DerivePrimaryKey}; + /// use sea_query::{MysqlQueryBuilder, TableAlterStatement}; + /// + /// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] + /// #[sea_orm(table_name = "posts")] + /// pub struct Model { + /// #[sea_orm(primary_key)] + /// pub id: u32, + /// pub title: String, + /// } + /// + /// #[derive(Copy, Clone, Debug, EnumIter)] + /// pub enum Relation {} + /// impl RelationTrait for Relation { + /// fn def(&self) -> RelationDef { + /// panic!("No RelationDef") + /// } + /// } + /// impl ActiveModelBehavior for ActiveModel {} + /// + /// let schema = Schema::new(DbBackend::MySql); + /// + /// let mut alter_table = TableAlterStatement::new() + /// .table(Entity) + /// .add_column(&mut schema.get_column_def::(Column::Title)) + /// .take(); + /// assert_eq!( + /// alter_table.to_string(MysqlQueryBuilder::default()), + /// "ALTER TABLE `posts` ADD COLUMN `title` varchar(255) NOT NULL" + /// ); + /// ``` + pub fn get_column_def(&self, column: E::Column) -> ColumnDef + where + E: EntityTrait, + { + column_def_from_entity_column::(column, self.backend) + } } pub(crate) fn create_enum_from_active_enum(backend: DbBackend) -> TypeCreateStatement @@ -117,39 +162,7 @@ where let mut stmt = TableCreateStatement::new(); for column in E::Column::iter() { - let orm_column_def = column.def(); - let types = match orm_column_def.col_type { - ColumnType::Enum { name, variants } => match backend { - DbBackend::MySql => { - let variants: Vec = variants.iter().map(|v| v.to_string()).collect(); - ColumnType::Custom(format!("ENUM('{}')", variants.join("', '"))) - } - DbBackend::Postgres => ColumnType::Custom(name.to_string()), - DbBackend::Sqlite => ColumnType::Text, - } - .into(), - _ => 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(); - } - if let Some(value) = orm_column_def.default_value { - column_def.default(value); - } - for primary_key in E::PrimaryKey::iter() { - if column.to_string() == primary_key.into_column().to_string() { - if E::PrimaryKey::auto_increment() { - column_def.auto_increment(); - } - if E::PrimaryKey::iter().count() == 1 { - column_def.primary_key(); - } - } - } + let mut column_def = column_def_from_entity_column::(column, backend); stmt.col(&mut column_def); } @@ -166,57 +179,52 @@ where 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); - let from_cols: Vec = match relation.from_col { - Identity::Unary(o1) => vec![o1], - Identity::Binary(o1, o2) => vec![o1, o2], - Identity::Ternary(o1, o2, o3) => vec![o1, o2, o3], - } - .into_iter() - .map(|col| { - let col_name = col.to_string(); - foreign_key_stmt.from_col(col); - col_name - }) - .collect(); - 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); - } - 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); - } - let name = if let Some(name) = relation.fk_name { - name - } else { - format!("fk-{}-{}", from_tbl.to_string(), from_cols.join("-")) - }; - stmt.foreign_key( - foreign_key_stmt - .name(&name) - .from_tbl(from_tbl) - .to_tbl(to_tbl), - ); + stmt.foreign_key(&mut relation.into()); } stmt.table(entity.table_ref()).take() } +fn column_def_from_entity_column(column: E::Column, backend: DbBackend) -> ColumnDef +where + E: EntityTrait, +{ + let orm_column_def = column.def(); + let types = match orm_column_def.col_type { + ColumnType::Enum { name, variants } => match backend { + DbBackend::MySql => { + let variants: Vec = variants.iter().map(|v| v.to_string()).collect(); + ColumnType::Custom(format!("ENUM('{}')", variants.join("', '"))) + } + DbBackend::Postgres => ColumnType::Custom(name.to_string()), + DbBackend::Sqlite => ColumnType::Text, + } + .into(), + _ => 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(); + } + if let Some(value) = orm_column_def.default_value { + column_def.default(value); + } + for primary_key in E::PrimaryKey::iter() { + if column.to_string() == primary_key.into_column().to_string() { + if E::PrimaryKey::auto_increment() { + column_def.auto_increment(); + } + if E::PrimaryKey::iter().count() == 1 { + column_def.primary_key(); + } + } + } + column_def +} + #[cfg(test)] mod tests { use crate::{sea_query::*, tests_cfg::*, DbBackend, EntityName, Schema}; diff --git a/tests/common/features/event_trigger.rs b/tests/common/features/event_trigger.rs new file mode 100644 index 00000000..cea0a806 --- /dev/null +++ b/tests/common/features/event_trigger.rs @@ -0,0 +1,70 @@ +use sea_orm::entity::prelude::*; +use sea_orm::{ + sea_query::{ArrayType, ColumnType, SeaRc, ValueType}, + TryGetError, TryGetable, +}; + +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[sea_orm(table_name = "event_trigger")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub events: Events, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Event(pub String); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Events(pub Vec); + +impl From for Value { + fn from(events: Events) -> Self { + let Events(events) = events; + Value::Array( + ArrayType::String, + Some(Box::new( + events + .into_iter() + .map(|Event(s)| Value::String(Some(Box::new(s)))) + .collect(), + )), + ) + } +} + +impl TryGetable for Events { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + let vec: Vec = res.try_get(pre, col).map_err(TryGetError::DbErr)?; + Ok(Events(vec.into_iter().map(Event).collect())) + } +} + +impl ValueType for Events { + fn try_from(v: Value) -> Result { + let value: Option> = + v.expect("This Value::Array should consist of Value::String"); + let vec = match value { + Some(v) => v.into_iter().map(Event).collect(), + None => vec![], + }; + Ok(Events(vec)) + } + + fn type_name() -> String { + stringify!(Events).to_owned() + } + + fn array_type() -> ArrayType { + ArrayType::String + } + + fn column_type() -> ColumnType { + ColumnType::Array(SeaRc::new(Box::new(ColumnType::String(None)))) + } +} diff --git a/tests/common/features/mod.rs b/tests/common/features/mod.rs index ea6a39bc..420c162c 100644 --- a/tests/common/features/mod.rs +++ b/tests/common/features/mod.rs @@ -4,6 +4,7 @@ pub mod applog; pub mod byte_primary_key; pub mod collection; pub mod custom_active_model; +pub mod event_trigger; pub mod insert_default; pub mod json_struct; pub mod json_vec; @@ -21,6 +22,7 @@ pub use active_enum_child::Entity as ActiveEnumChild; pub use applog::Entity as Applog; pub use byte_primary_key::Entity as BytePrimaryKey; pub use collection::Entity as Collection; +pub use event_trigger::Entity as EventTrigger; pub use insert_default::Entity as InsertDefault; pub use json_struct::Entity as JsonStruct; pub use json_vec::Entity as JsonVec; diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 13ca8c23..c50683be 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -45,6 +45,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { if DbBackend::Postgres == db_backend { create_collection_table(db).await?; + create_event_trigger_table(db).await?; } Ok(()) @@ -411,3 +412,23 @@ pub async fn create_pi_table(db: &DbConn) -> Result { create_table(db, &stmt, Pi).await } + +pub async fn create_event_trigger_table(db: &DbConn) -> Result { + let stmt = sea_query::Table::create() + .table(event_trigger::Entity) + .col( + ColumnDef::new(event_trigger::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(event_trigger::Column::Events) + .array(sea_query::ColumnType::String(None)) + .not_null(), + ) + .to_owned(); + + create_table(db, &stmt, EventTrigger).await +} diff --git a/tests/event_trigger_tests.rs b/tests/event_trigger_tests.rs new file mode 100644 index 00000000..2d8712c5 --- /dev/null +++ b/tests/event_trigger_tests.rs @@ -0,0 +1,48 @@ +pub mod common; + +pub use common::{ + features::{ + event_trigger::{Event, Events}, + *, + }, + setup::*, + TestContext, +}; +use pretty_assertions::assert_eq; +use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection}; + +#[sea_orm_macros::test] +#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("event_trigger_tests").await; + create_tables(&ctx.db).await?; + insert_event_trigger(&ctx.db).await?; + ctx.delete().await; + + Ok(()) +} + +pub async fn insert_event_trigger(db: &DatabaseConnection) -> Result<(), DbErr> { + let event_trigger = event_trigger::Model { + id: 1, + events: Events( + ["A", "B", "C"] + .into_iter() + .map(|s| Event(s.to_owned())) + .collect(), + ), + }; + + let result = event_trigger.clone().into_active_model().insert(db).await?; + + assert_eq!(result, event_trigger); + + let model = event_trigger::Entity::find() + .filter(event_trigger::Column::Id.eq(event_trigger.id)) + .one(db) + .await?; + + assert_eq!(model, Some(event_trigger)); + + Ok(()) +} diff --git a/tests/parallel_tests.rs b/tests/parallel_tests.rs index 8eb18dbd..73dae78e 100644 --- a/tests/parallel_tests.rs +++ b/tests/parallel_tests.rs @@ -27,8 +27,8 @@ pub async fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> { key: "markup".to_owned(), value: "1.18".to_owned(), bytes: vec![1, 2, 3], - date: Some(Date::from_ymd(2021, 9, 27)), - time: Some(Time::from_hms(11, 32, 55)), + date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()), + time: Some(Time::from_hms_opt(11, 32, 55).unwrap()), }, metadata::Model { uuid: Uuid::new_v4(), @@ -36,8 +36,8 @@ pub async fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> { key: "exchange_rate".to_owned(), value: "0.78".to_owned(), bytes: vec![1, 2, 3], - date: Some(Date::from_ymd(2021, 9, 27)), - time: Some(Time::from_hms(11, 32, 55)), + date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()), + time: Some(Time::from_hms_opt(11, 32, 55).unwrap()), }, metadata::Model { uuid: Uuid::new_v4(), diff --git a/tests/self_join_tests.rs b/tests/self_join_tests.rs index 0c85a070..d4e86034 100644 --- a/tests/self_join_tests.rs +++ b/tests/self_join_tests.rs @@ -23,7 +23,7 @@ pub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> { let model = self_join::Model { uuid: Uuid::new_v4(), uuid_ref: None, - time: Some(Time::from_hms(1, 00, 00)), + time: Some(Time::from_hms_opt(1, 00, 00).unwrap()), }; model.clone().into_active_model().insert(db).await?; @@ -31,7 +31,7 @@ pub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> { let linked_model = self_join::Model { uuid: Uuid::new_v4(), uuid_ref: Some(model.clone().uuid), - time: Some(Time::from_hms(2, 00, 00)), + time: Some(Time::from_hms_opt(2, 00, 00).unwrap()), }; linked_model.clone().into_active_model().insert(db).await?; @@ -39,7 +39,7 @@ pub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> { let not_linked_model = self_join::Model { uuid: Uuid::new_v4(), uuid_ref: None, - time: Some(Time::from_hms(3, 00, 00)), + time: Some(Time::from_hms_opt(3, 00, 00).unwrap()), }; not_linked_model diff --git a/tests/uuid_tests.rs b/tests/uuid_tests.rs index 20df5085..b0d07772 100644 --- a/tests/uuid_tests.rs +++ b/tests/uuid_tests.rs @@ -28,8 +28,8 @@ pub async fn insert_metadata(db: &DatabaseConnection) -> Result<(), DbErr> { key: "markup".to_owned(), value: "1.18".to_owned(), bytes: vec![1, 2, 3], - date: Some(Date::from_ymd(2021, 9, 27)), - time: Some(Time::from_hms(11, 32, 55)), + date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()), + time: Some(Time::from_hms_opt(11, 32, 55).unwrap()), }; let result = metadata.clone().into_active_model().insert(db).await?; @@ -65,8 +65,8 @@ pub async fn create_and_update_metadata(db: &DatabaseConnection) -> Result<(), D key: "markup".to_owned(), value: "1.18".to_owned(), bytes: vec![1, 2, 3], - date: Some(Date::from_ymd(2021, 9, 27)), - time: Some(Time::from_hms(11, 32, 55)), + date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()), + time: Some(Time::from_hms_opt(11, 32, 55).unwrap()), }; let res = Metadata::insert(metadata.clone().into_active_model())