Merge branch 'master' into select-into-tuple
This commit is contained in:
commit
2f00a8757d
19
CHANGELOG.md
19
CHANGELOG.md
@ -10,11 +10,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### New Features
|
### New Features
|
||||||
|
|
||||||
* Transactions Isolation level and Access mode https://github.com/SeaQL/sea-orm/pull/1230
|
* 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
|
### Enhancements
|
||||||
|
|
||||||
* Support Vector of enum for Postgres https://github.com/SeaQL/sea-orm/pull/1210
|
* 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
|
* 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
|
### Upgrades
|
||||||
|
|
||||||
@ -22,11 +26,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
### House Keeping
|
### 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
|
### Bug Fixes
|
||||||
|
|
||||||
* Fixes `DeriveColumn` (by qualifying `IdenStatic::as_str`) https://github.com/SeaQL/sea-orm/pull/1280
|
* 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
|
## 0.10.5 - 2022-12-02
|
||||||
|
|
||||||
|
58
Cargo.toml
58
Cargo.toml
@ -24,41 +24,41 @@ name = "sea_orm"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-stream = { version = "^0.3", default-features = false }
|
async-stream = { version = "0.3", default-features = false }
|
||||||
async-trait = { version = "^0.1", default-features = false }
|
async-trait = { version = "0.1", default-features = false }
|
||||||
chrono = { version = "^0.4.20", default-features = false, optional = true }
|
chrono = { version = "0.4.20", default-features = false, optional = true }
|
||||||
time = { version = "^0.3", default-features = false, optional = true }
|
time = { version = "0.3", default-features = false, optional = true }
|
||||||
futures = { version = "^0.3", default-features = false, features = ["std"] }
|
futures = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
log = { version = "^0.4", default-features = false }
|
log = { version = "0.4", default-features = false }
|
||||||
tracing = { version = "^0.1", default-features = false, features = ["attributes", "log"] }
|
tracing = { version = "0.1", default-features = false, features = ["attributes", "log"] }
|
||||||
rust_decimal = { version = "^1", default-features = false, optional = true }
|
rust_decimal = { version = "1", default-features = false, optional = true }
|
||||||
bigdecimal = { version = "^0.3", 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-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 = { version = "0.27.2", features = ["thread-safe"] }
|
||||||
sea-query-binder = { version = "^0.2.2", default-features = false, optional = true }
|
sea-query-binder = { version = "0.2.2", default-features = false, optional = true }
|
||||||
sea-strum = { version = "^0.23", default-features = false, features = ["derive", "sea-orm"] }
|
sea-strum = { version = "0.23", default-features = false, features = ["derive", "sea-orm"] }
|
||||||
serde = { version = "^1.0", default-features = false }
|
serde = { version = "1.0", default-features = false }
|
||||||
serde_json = { version = "^1.0", default-features = false, optional = true }
|
serde_json = { version = "1.0", default-features = false, optional = true }
|
||||||
sqlx = { version = "^0.6", default-features = false, optional = true }
|
sqlx = { version = "0.6", default-features = false, optional = true }
|
||||||
uuid = { version = "^1", default-features = false, optional = true }
|
uuid = { version = "1", default-features = false, optional = true }
|
||||||
ouroboros = { version = "0.15", default-features = false }
|
ouroboros = { version = "0.15", default-features = false }
|
||||||
url = { version = "^2.2", default-features = false }
|
url = { version = "2.2", default-features = false }
|
||||||
thiserror = { version = "^1", default-features = false }
|
thiserror = { version = "1", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
smol = { version = "^1.2" }
|
smol = { version = "1.2" }
|
||||||
smol-potat = { version = "^1.1" }
|
smol-potat = { version = "1.1" }
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "0.3" }
|
||||||
tokio = { version = "^1.6", features = ["full"] }
|
tokio = { version = "1.6", features = ["full"] }
|
||||||
actix-rt = { version = "2.2.0" }
|
actix-rt = { version = "2.2.0" }
|
||||||
maplit = { version = "^1" }
|
maplit = { version = "1" }
|
||||||
rust_decimal_macros = { version = "^1" }
|
rust_decimal_macros = { version = "1" }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
sea-orm = { path = ".", features = ["mock", "debug-print", "tests-cfg", "postgres-array"] }
|
sea-orm = { path = ".", features = ["mock", "debug-print", "tests-cfg", "postgres-array"] }
|
||||||
pretty_assertions = { version = "^0.7" }
|
pretty_assertions = { version = "0.7" }
|
||||||
time = { version = "^0.3", features = ["macros"] }
|
time = { version = "0.3", features = ["macros"] }
|
||||||
uuid = { version = "^1", features = ["v4"] }
|
uuid = { version = "1", features = ["v4"] }
|
||||||
once_cell = "1.8"
|
once_cell = "1.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -11,7 +11,7 @@ sleep 1
|
|||||||
# Bump `sea-orm-cli` version
|
# Bump `sea-orm-cli` version
|
||||||
cd sea-orm-cli
|
cd sea-orm-cli
|
||||||
sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml
|
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"
|
git commit -am "sea-orm-cli $1"
|
||||||
cd ..
|
cd ..
|
||||||
sleep 1
|
sleep 1
|
||||||
@ -23,21 +23,21 @@ git commit -am "sea-orm-macros $1"
|
|||||||
cd ..
|
cd ..
|
||||||
sleep 1
|
sleep 1
|
||||||
sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml
|
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
|
git commit -am "$1" # publish sea-orm
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# Bump `sea-orm-migration` version
|
# Bump `sea-orm-migration` version
|
||||||
cd sea-orm-migration
|
cd sea-orm-migration
|
||||||
sed -i 's/^version.*$/version = "'$1'"/' Cargo.toml
|
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-cli [^,]*,/sea-orm-cli = { version = "'$1'",/' Cargo.toml
|
||||||
sed -i 's/^sea-orm [^,]*,/sea-orm = { version = "\^'$1'",/' Cargo.toml
|
sed -i 's/^sea-orm [^,]*,/sea-orm = { version = "'$1'",/' Cargo.toml
|
||||||
git commit -am "sea-orm-migration $1"
|
git commit -am "sea-orm-migration $1"
|
||||||
cd ..
|
cd ..
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# Bump examples' dependency version
|
# Bump examples' dependency version
|
||||||
cd examples
|
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 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-migration version$/version = "'$1'" # sea-orm-migration version/' {} \;
|
||||||
git commit -am "update examples"
|
git commit -am "update examples"
|
@ -11,8 +11,8 @@ actix-http = "2"
|
|||||||
actix-web = "3"
|
actix-web = "3"
|
||||||
actix-flash = "0.2"
|
actix-flash = "0.2"
|
||||||
actix-files = "0.5"
|
actix-files = "0.5"
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "0.3" }
|
||||||
tera = "1.8.0"
|
tera = "1.8.0"
|
||||||
dotenvy = "0.15"
|
dotenvy = "0.15"
|
||||||
listenfd = "0.3.3"
|
listenfd = "0.3.3"
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-async-std-native-tls",
|
# "runtime-async-std-native-tls",
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-actix-native-tls",
|
# "runtime-actix-native-tls",
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -8,9 +8,9 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[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" ] }
|
sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-async-std-native-tls" ] }
|
||||||
serde_json = { version = "^1" }
|
serde_json = { version = "1" }
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "0.3" }
|
||||||
async-stream = { version = "^0.3" }
|
async-stream = { version = "0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "0.3" }
|
||||||
|
@ -8,8 +8,8 @@ publish = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
graphql-example-core = { path = "../core" }
|
graphql-example-core = { path = "../core" }
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
axum = "^0.5.1"
|
axum = "0.5.1"
|
||||||
dotenvy = "0.15.0"
|
dotenvy = "0.15.0"
|
||||||
async-graphql-axum = "^4.0.6"
|
async-graphql-axum = "4.0.6"
|
||||||
entity = { path = "../entity" }
|
entity = { path = "../entity" }
|
||||||
migration = { path = "../migration" }
|
migration = { path = "../migration" }
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -12,8 +12,8 @@ path = "src/lib.rs"
|
|||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
[dependencies.async-graphql]
|
[dependencies.async-graphql]
|
||||||
version = "^4.0.6"
|
version = "4.0.6"
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -10,11 +10,11 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dotenvy = "0.15.0"
|
dotenvy = "0.15.0"
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -6,7 +6,7 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee-example-core = { path = "../core" }
|
jsonrpsee-example-core = { path = "../core" }
|
||||||
jsonrpsee = { version = "^0.8.0", features = ["full"] }
|
jsonrpsee = { version = "0.8.0", features = ["full"] }
|
||||||
jsonrpsee-core = "0.9.0"
|
jsonrpsee-core = "0.9.0"
|
||||||
tokio = { version = "1.8.0", features = ["full"] }
|
tokio = { version = "1.8.0", features = ["full"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-tokio-native-tls",
|
"runtime-tokio-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -6,18 +6,18 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-stream = { version = "^0.3" }
|
async-stream = { version = "0.3" }
|
||||||
async-trait = { version = "0.1" }
|
async-trait = { version = "0.1" }
|
||||||
rocket-example-core = { path = "../core" }
|
rocket-example-core = { path = "../core" }
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "0.3" }
|
||||||
rocket = { version = "0.5.0-rc.1", features = [
|
rocket = { version = "0.5.0-rc.1", features = [
|
||||||
"json",
|
"json",
|
||||||
] }
|
] }
|
||||||
rocket_dyn_templates = { version = "0.1.0-rc.1", features = [
|
rocket_dyn_templates = { version = "0.1.0-rc.1", features = [
|
||||||
"tera",
|
"tera",
|
||||||
] }
|
] }
|
||||||
serde_json = { version = "^1" }
|
serde_json = { version = "1" }
|
||||||
entity = { path = "../entity" }
|
entity = { path = "../entity" }
|
||||||
migration = { path = "../migration" }
|
migration = { path = "../migration" }
|
||||||
tokio = "1.20.0"
|
tokio = "1.20.0"
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"runtime-tokio-native-tls",
|
"runtime-tokio-native-tls",
|
||||||
"sqlx-postgres",
|
"sqlx-postgres",
|
||||||
|
@ -15,4 +15,4 @@ rocket = { version = "0.5.0-rc.1", features = [
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -10,11 +10,11 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = { version = "0.5.0-rc.1" }
|
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]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -6,18 +6,18 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-stream = { version = "^0.3" }
|
async-stream = { version = "0.3" }
|
||||||
async-trait = { version = "0.1" }
|
async-trait = { version = "0.1" }
|
||||||
rocket-example-core = { path = "../core" }
|
rocket-example-core = { path = "../core" }
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "0.3" }
|
||||||
rocket = { version = "0.5.0-rc.1", features = [
|
rocket = { version = "0.5.0-rc.1", features = [
|
||||||
"json",
|
"json",
|
||||||
] }
|
] }
|
||||||
rocket_dyn_templates = { version = "0.1.0-rc.1", features = [
|
rocket_dyn_templates = { version = "0.1.0-rc.1", features = [
|
||||||
"tera",
|
"tera",
|
||||||
] }
|
] }
|
||||||
serde_json = { version = "^1" }
|
serde_json = { version = "1" }
|
||||||
entity = { path = "../entity" }
|
entity = { path = "../entity" }
|
||||||
migration = { path = "../migration" }
|
migration = { path = "../migration" }
|
||||||
tokio = "1.20.0"
|
tokio = "1.20.0"
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"runtime-tokio-native-tls",
|
"runtime-tokio-native-tls",
|
||||||
"sqlx-postgres",
|
"sqlx-postgres",
|
||||||
|
@ -15,7 +15,7 @@ rocket = { version = "0.5.0-rc.1", features = [
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
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]
|
[dependencies.rocket_okapi]
|
||||||
version = "0.8.0-rc.2"
|
version = "0.8.0-rc.2"
|
||||||
|
@ -10,11 +10,11 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = { version = "0.5.0-rc.1" }
|
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]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-tokio-native-tls",
|
"runtime-tokio-native-tls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-native-tls",
|
# "runtime-tokio-native-tls",
|
||||||
|
@ -10,7 +10,7 @@ entity = { path = "../entity" }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
features = [
|
features = [
|
||||||
"debug-print",
|
"debug-print",
|
||||||
"runtime-tokio-rustls",
|
"runtime-tokio-rustls",
|
||||||
|
@ -13,4 +13,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../../" # remove this line in your own project
|
path = "../../../" # remove this line in your own project
|
||||||
version = "^0.10.3" # sea-orm version
|
version = "0.10.3" # sea-orm version
|
||||||
|
@ -9,11 +9,11 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
path = "../../../sea-orm-migration" # remove this line in your own project
|
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 = [
|
features = [
|
||||||
# Enable following runtime and db backend features if you want to run migration via CLI
|
# Enable following runtime and db backend features if you want to run migration via CLI
|
||||||
# "runtime-tokio-rustls",
|
# "runtime-tokio-rustls",
|
||||||
|
@ -8,8 +8,8 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "^1"
|
serde = "1"
|
||||||
tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] }
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../"
|
path = "../../"
|
||||||
|
@ -8,8 +8,8 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "^1"
|
serde = "1"
|
||||||
tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] }
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../"
|
path = "../../"
|
||||||
|
@ -9,4 +9,4 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sea-orm = { path = "../../", features = [ "sqlx-all", "runtime-async-std-native-tls", "debug-print" ] }
|
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"] }
|
||||||
|
@ -8,8 +8,8 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
serde = { version = "^1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
sea-orm = { path = "../../", features = [
|
sea-orm = { path = "../../", features = [
|
||||||
"sqlx-mysql",
|
"sqlx-mysql",
|
||||||
"runtime-async-std-native-tls",
|
"runtime-async-std-native-tls",
|
||||||
|
@ -9,8 +9,8 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "^1"
|
serde = "1"
|
||||||
tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] }
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
path = "../../"
|
path = "../../"
|
||||||
|
@ -31,17 +31,17 @@ path = "src/bin/sea.rs"
|
|||||||
required-features = ["cli", "codegen"]
|
required-features = ["cli", "codegen"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "^3.2", features = ["env", "derive"], optional = true }
|
clap = { version = "3.2", default-features = false, features = ["std", "env", "derive"], optional = true }
|
||||||
dotenvy = { version = "^0.15", optional = true }
|
dotenvy = { version = "0.15", default-features = false, optional = true }
|
||||||
async-std = { version = "^1.9", features = ["attributes", "tokio1"], 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", optional = true }
|
sea-orm-codegen = { version = "=0.10.3", path = "../sea-orm-codegen", default-features = false, optional = true }
|
||||||
sea-schema = { version = "^0.10.2" }
|
sea-schema = { version = "0.10.2" }
|
||||||
sqlx = { version = "^0.6", default-features = false, features = ["mysql", "postgres"], optional = true }
|
sqlx = { version = "0.6", default-features = false, features = ["mysql", "postgres"], optional = true }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] }
|
||||||
tracing = { version = "0.1" }
|
tracing = { version = "0.1", default-features = false }
|
||||||
url = "^2.2"
|
url = { version = "2.2", default-features = false }
|
||||||
chrono = { version = "^0.4.20", default-features = false, features = ["clock"] }
|
chrono = { version = "0.4.20", default-features = false, features = ["clock"] }
|
||||||
regex = "1"
|
regex = { version = "1", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
smol = "1.2.5"
|
smol = "1.2.5"
|
||||||
|
@ -200,6 +200,21 @@ pub enum GenerateSubcommands {
|
|||||||
)]
|
)]
|
||||||
with_serde: String,
|
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(
|
#[clap(
|
||||||
action,
|
action,
|
||||||
long,
|
long,
|
||||||
@ -228,6 +243,24 @@ pub enum GenerateSubcommands {
|
|||||||
help = "Generate index file as `lib.rs` instead of `mod.rs`."
|
help = "Generate index file as `lib.rs` instead of `mod.rs`."
|
||||||
)]
|
)]
|
||||||
lib: bool,
|
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<String>,
|
||||||
|
|
||||||
|
#[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<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,13 @@ pub async fn run_generate_command(
|
|||||||
database_schema,
|
database_schema,
|
||||||
database_url,
|
database_url,
|
||||||
with_serde,
|
with_serde,
|
||||||
|
serde_skip_deserializing_primary_key,
|
||||||
|
serde_skip_hidden_column,
|
||||||
with_copy_enums,
|
with_copy_enums,
|
||||||
date_time_crate,
|
date_time_crate,
|
||||||
lib,
|
lib,
|
||||||
|
model_extra_derives,
|
||||||
|
model_extra_attributes,
|
||||||
} => {
|
} => {
|
||||||
if verbose {
|
if verbose {
|
||||||
let _ = tracing_subscriber::fmt()
|
let _ = tracing_subscriber::fmt()
|
||||||
@ -159,11 +163,15 @@ pub async fn run_generate_command(
|
|||||||
|
|
||||||
let writer_context = EntityWriterContext::new(
|
let writer_context = EntityWriterContext::new(
|
||||||
expanded_format,
|
expanded_format,
|
||||||
WithSerde::from_str(&with_serde).unwrap(),
|
WithSerde::from_str(&with_serde).expect("Invalid serde derive option"),
|
||||||
with_copy_enums,
|
with_copy_enums,
|
||||||
date_time_crate.into(),
|
date_time_crate.into(),
|
||||||
schema_name,
|
schema_name,
|
||||||
lib,
|
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);
|
let output = EntityTransformer::transform(table_stmts)?.generate(&writer_context);
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ pub fn run_migrate_init(migration_dir: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
write_file!("src/main.rs");
|
write_file!("src/main.rs");
|
||||||
write_file!("Cargo.toml", "_Cargo.toml", |content: String| {
|
write_file!("Cargo.toml", "_Cargo.toml", |content: String| {
|
||||||
let ver = format!(
|
let ver = format!(
|
||||||
"^{}.{}.0",
|
"{}.{}.0",
|
||||||
env!("CARGO_PKG_VERSION_MAJOR"),
|
env!("CARGO_PKG_VERSION_MAJOR"),
|
||||||
env!("CARGO_PKG_VERSION_MINOR")
|
env!("CARGO_PKG_VERSION_MINOR")
|
||||||
);
|
);
|
||||||
|
@ -9,7 +9,7 @@ name = "migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[dependencies.sea-orm-migration]
|
[dependencies.sea-orm-migration]
|
||||||
version = "<sea-orm-migration-version>"
|
version = "<sea-orm-migration-version>"
|
||||||
|
@ -17,17 +17,12 @@ name = "sea_orm_codegen"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sea-query = { version = "^0.27.1", features = ["thread-safe"] }
|
sea-query = { version = "0.27.1", default-features = false, features = ["thread-safe"] }
|
||||||
syn = { version = "^1", default-features = false, features = [
|
syn = { version = "1", default-features = false }
|
||||||
"derive",
|
quote = { version = "1", default-features = false }
|
||||||
"parsing",
|
heck = { version = "0.3", default-features = false }
|
||||||
"proc-macro",
|
proc-macro2 = { version = "1", default-features = false }
|
||||||
"printing",
|
tracing = { version = "0.1", default-features = false, features = ["log"] }
|
||||||
] }
|
|
||||||
quote = "^1"
|
|
||||||
heck = "^0.3"
|
|
||||||
proc-macro2 = "^1"
|
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { version = "^0.7" }
|
pretty_assertions = { version = "0.7" }
|
||||||
|
@ -166,6 +166,24 @@ impl Entity {
|
|||||||
// if exist, return nothing
|
// if exist, return nothing
|
||||||
.map_or(quote! {, Eq}, |_| quote! {})
|
.map_or(quote! {, Eq}, |_| quote! {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_column_serde_attributes(
|
||||||
|
&self,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
) -> Vec<TokenStream> {
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
@ -204,6 +222,7 @@ mod tests {
|
|||||||
on_update: Some(ForeignKeyAction::Cascade),
|
on_update: Some(ForeignKeyAction::Cascade),
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "filling".to_owned(),
|
ref_table: "filling".to_owned(),
|
||||||
@ -214,6 +233,7 @@ mod tests {
|
|||||||
on_update: Some(ForeignKeyAction::Cascade),
|
on_update: Some(ForeignKeyAction::Cascade),
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
conjunct_relations: vec![],
|
conjunct_relations: vec![],
|
||||||
|
@ -211,6 +211,25 @@ impl Column {
|
|||||||
}
|
}
|
||||||
info
|
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<ColumnDef> for Column {
|
impl From<ColumnDef> for Column {
|
||||||
|
@ -23,6 +23,7 @@ pub struct Relation {
|
|||||||
pub(crate) on_delete: Option<ForeignKeyAction>,
|
pub(crate) on_delete: Option<ForeignKeyAction>,
|
||||||
pub(crate) self_referencing: bool,
|
pub(crate) self_referencing: bool,
|
||||||
pub(crate) num_suffix: usize,
|
pub(crate) num_suffix: usize,
|
||||||
|
pub(crate) impl_related: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Relation {
|
impl Relation {
|
||||||
@ -178,6 +179,7 @@ impl From<&TableForeignKey> for Relation {
|
|||||||
on_update,
|
on_update,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,6 +201,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "filling".to_owned(),
|
ref_table: "filling".to_owned(),
|
||||||
@ -209,6 +212,7 @@ mod tests {
|
|||||||
on_update: Some(ForeignKeyAction::Cascade),
|
on_update: Some(ForeignKeyAction::Cascade),
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "filling".to_owned(),
|
ref_table: "filling".to_owned(),
|
||||||
@ -219,6 +223,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -197,13 +197,23 @@ impl EntityTransformer {
|
|||||||
}
|
}
|
||||||
for (tbl_name, mut conjunct_relations) in conjunct_relations.into_iter() {
|
for (tbl_name, mut conjunct_relations) in conjunct_relations.into_iter() {
|
||||||
if let Some(entity) = entities.get_mut(&tbl_name) {
|
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);
|
entity.conjunct_relations.append(&mut conjunct_relations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(EntityWriter {
|
Ok(EntityWriter {
|
||||||
entities: entities
|
entities: entities
|
||||||
.into_iter()
|
.into_values()
|
||||||
.map(|(_, mut v)| {
|
.map(|mut v| {
|
||||||
v.relations.sort_by(|a, b| a.ref_table.cmp(&b.ref_table));
|
v.relations.sort_by(|a, b| a.ref_table.cmp(&b.ref_table));
|
||||||
v
|
v
|
||||||
})
|
})
|
||||||
|
@ -43,6 +43,10 @@ pub struct EntityWriterContext {
|
|||||||
pub(crate) date_time_crate: DateTimeCrate,
|
pub(crate) date_time_crate: DateTimeCrate,
|
||||||
pub(crate) schema_name: Option<String>,
|
pub(crate) schema_name: Option<String>,
|
||||||
pub(crate) lib: bool,
|
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 {
|
impl WithSerde {
|
||||||
@ -67,15 +71,44 @@ impl WithSerde {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !extra_derive.is_empty() {
|
if !extra_derive.is_empty() {
|
||||||
extra_derive = quote! { , #extra_derive }
|
extra_derive = quote! { , #extra_derive }
|
||||||
}
|
}
|
||||||
|
|
||||||
extra_derive
|
extra_derive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts model_extra_derives argument to token stream
|
||||||
|
fn bonus_derive<T>(model_extra_derives: Vec<T>) -> TokenStream
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
model_extra_derives
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::<String>::into)
|
||||||
|
.fold(TokenStream::default(), |acc, derive| {
|
||||||
|
let tokens: TokenStream = derive.parse().unwrap();
|
||||||
|
quote! { #acc, #tokens }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// convert attributes argument to token stream
|
||||||
|
fn bonus_attributes<T>(attributes: Vec<T>) -> TokenStream
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
attributes.into_iter().map(Into::<String>::into).fold(
|
||||||
|
TokenStream::default(),
|
||||||
|
|acc, attribute| {
|
||||||
|
let tokens: TokenStream = attribute.parse().unwrap();
|
||||||
|
quote! {
|
||||||
|
#acc
|
||||||
|
#[#tokens]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for WithSerde {
|
impl FromStr for WithSerde {
|
||||||
type Err = crate::Error;
|
type Err = crate::Error;
|
||||||
|
|
||||||
@ -96,6 +129,7 @@ impl FromStr for WithSerde {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EntityWriterContext {
|
impl EntityWriterContext {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
expanded_format: bool,
|
expanded_format: bool,
|
||||||
with_serde: WithSerde,
|
with_serde: WithSerde,
|
||||||
@ -103,6 +137,10 @@ impl EntityWriterContext {
|
|||||||
date_time_crate: DateTimeCrate,
|
date_time_crate: DateTimeCrate,
|
||||||
schema_name: Option<String>,
|
schema_name: Option<String>,
|
||||||
lib: bool,
|
lib: bool,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: Vec<String>,
|
||||||
|
model_extra_attributes: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
expanded_format,
|
expanded_format,
|
||||||
@ -111,6 +149,10 @@ impl EntityWriterContext {
|
|||||||
date_time_crate,
|
date_time_crate,
|
||||||
schema_name,
|
schema_name,
|
||||||
lib,
|
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()
|
.iter()
|
||||||
.map(|column| column.get_info(&context.date_time_crate))
|
.map(|column| column.get_info(&context.date_time_crate))
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
// 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);
|
info!("Generating {}", entity_file);
|
||||||
for info in column_info.iter() {
|
for info in column_info.iter() {
|
||||||
@ -153,6 +204,10 @@ impl EntityWriter {
|
|||||||
&context.with_serde,
|
&context.with_serde,
|
||||||
&context.date_time_crate,
|
&context.date_time_crate,
|
||||||
&context.schema_name,
|
&context.schema_name,
|
||||||
|
serde_skip_deserializing_primary_key,
|
||||||
|
serde_skip_hidden_column,
|
||||||
|
&context.model_extra_derives,
|
||||||
|
&context.model_extra_attributes,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Self::gen_compact_code_blocks(
|
Self::gen_compact_code_blocks(
|
||||||
@ -160,6 +215,10 @@ impl EntityWriter {
|
|||||||
&context.with_serde,
|
&context.with_serde,
|
||||||
&context.date_time_crate,
|
&context.date_time_crate,
|
||||||
&context.schema_name,
|
&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);
|
Self::write(&mut lines, code_blocks);
|
||||||
@ -225,8 +284,8 @@ impl EntityWriter {
|
|||||||
lines.push("".to_owned());
|
lines.push("".to_owned());
|
||||||
let code_blocks = self
|
let code_blocks = self
|
||||||
.enums
|
.enums
|
||||||
.iter()
|
.values()
|
||||||
.map(|(_, active_enum)| active_enum.impl_active_enum(with_serde, with_copy_enums))
|
.map(|active_enum| active_enum.impl_active_enum(with_serde, with_copy_enums))
|
||||||
.collect();
|
.collect();
|
||||||
Self::write(&mut lines, code_blocks);
|
Self::write(&mut lines, code_blocks);
|
||||||
OutputFile {
|
OutputFile {
|
||||||
@ -254,11 +313,16 @@ impl EntityWriter {
|
|||||||
lines.push("".to_owned());
|
lines.push("".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn gen_expanded_code_blocks(
|
pub fn gen_expanded_code_blocks(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
date_time_crate: &DateTimeCrate,
|
date_time_crate: &DateTimeCrate,
|
||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> Vec<TokenStream> {
|
) -> Vec<TokenStream> {
|
||||||
let mut imports = Self::gen_import(with_serde);
|
let mut imports = Self::gen_import(with_serde);
|
||||||
imports.extend(Self::gen_import_active_enum(entity));
|
imports.extend(Self::gen_import_active_enum(entity));
|
||||||
@ -266,7 +330,15 @@ impl EntityWriter {
|
|||||||
imports,
|
imports,
|
||||||
Self::gen_entity_struct(),
|
Self::gen_entity_struct(),
|
||||||
Self::gen_impl_entity_name(entity, schema_name),
|
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_column_enum(entity),
|
||||||
Self::gen_primary_key_enum(entity),
|
Self::gen_primary_key_enum(entity),
|
||||||
Self::gen_impl_primary_key(entity, date_time_crate),
|
Self::gen_impl_primary_key(entity, date_time_crate),
|
||||||
@ -280,17 +352,31 @@ impl EntityWriter {
|
|||||||
code_blocks
|
code_blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn gen_compact_code_blocks(
|
pub fn gen_compact_code_blocks(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
date_time_crate: &DateTimeCrate,
|
date_time_crate: &DateTimeCrate,
|
||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> Vec<TokenStream> {
|
) -> Vec<TokenStream> {
|
||||||
let mut imports = Self::gen_import(with_serde);
|
let mut imports = Self::gen_import(with_serde);
|
||||||
imports.extend(Self::gen_import_active_enum(entity));
|
imports.extend(Self::gen_import_active_enum(entity));
|
||||||
let mut code_blocks = vec![
|
let mut code_blocks = vec![
|
||||||
imports,
|
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),
|
Self::gen_compact_relation_enum(entity),
|
||||||
];
|
];
|
||||||
code_blocks.extend(Self::gen_impl_related(entity));
|
code_blocks.extend(Self::gen_impl_related(entity));
|
||||||
@ -312,14 +398,12 @@ impl EntityWriter {
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WithSerde::Deserialize => {
|
WithSerde::Deserialize => {
|
||||||
quote! {
|
quote! {
|
||||||
#prelude_import
|
#prelude_import
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WithSerde::Both => {
|
WithSerde::Both => {
|
||||||
quote! {
|
quote! {
|
||||||
#prelude_import
|
#prelude_import
|
||||||
@ -378,16 +462,28 @@ impl EntityWriter {
|
|||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
date_time_crate: &DateTimeCrate,
|
date_time_crate: &DateTimeCrate,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let column_names_snake_case = entity.get_column_names_snake_case();
|
let column_names_snake_case = entity.get_column_names_snake_case();
|
||||||
let column_rs_types = entity.get_column_rs_types(date_time_crate);
|
let column_rs_types = entity.get_column_rs_types(date_time_crate);
|
||||||
let if_eq_needed = entity.get_eq_needed();
|
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();
|
let extra_derive = with_serde.extra_derive();
|
||||||
|
|
||||||
quote! {
|
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 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
|
entity
|
||||||
.relations
|
.relations
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|rel| !rel.self_referencing && rel.num_suffix == 0)
|
.filter(|rel| !rel.self_referencing && rel.num_suffix == 0 && rel.impl_related)
|
||||||
.map(|rel| {
|
.map(|rel| {
|
||||||
let enum_name = rel.get_enum_name();
|
let enum_name = rel.get_enum_name();
|
||||||
let module_name = rel.get_module_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(
|
pub fn gen_compact_model_struct(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
date_time_crate: &DateTimeCrate,
|
date_time_crate: &DateTimeCrate,
|
||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
|
serde_skip_deserializing_primary_key: bool,
|
||||||
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let table_name = entity.table_name.as_str();
|
let table_name = entity.table_name.as_str();
|
||||||
let column_names_snake_case = entity.get_column_names_snake_case();
|
let column_names_snake_case = entity.get_column_names_snake_case();
|
||||||
@ -581,11 +682,12 @@ impl EntityWriter {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|col| {
|
.map(|col| {
|
||||||
let mut attrs: Punctuated<_, Comma> = Punctuated::new();
|
let mut attrs: Punctuated<_, Comma> = Punctuated::new();
|
||||||
|
let is_primary_key = primary_keys.contains(&col.name);
|
||||||
if !col.is_snake_case_name() {
|
if !col.is_snake_case_name() {
|
||||||
let column_name = &col.name;
|
let column_name = &col.name;
|
||||||
attrs.push(quote! { column_name = #column_name });
|
attrs.push(quote! { column_name = #column_name });
|
||||||
}
|
}
|
||||||
if primary_keys.contains(&col.name) {
|
if is_primary_key {
|
||||||
attrs.push(quote! { primary_key });
|
attrs.push(quote! { primary_key });
|
||||||
if !col.auto_increment {
|
if !col.auto_increment {
|
||||||
attrs.push(quote! { auto_increment = false });
|
attrs.push(quote! { auto_increment = false });
|
||||||
@ -600,20 +702,26 @@ impl EntityWriter {
|
|||||||
if col.unique {
|
if col.unique {
|
||||||
attrs.push(quote! { unique });
|
attrs.push(quote! { unique });
|
||||||
}
|
}
|
||||||
|
let mut ts = quote! {};
|
||||||
if !attrs.is_empty() {
|
if !attrs.is_empty() {
|
||||||
let mut ts = TokenStream::new();
|
|
||||||
for (i, attr) in attrs.into_iter().enumerate() {
|
for (i, attr) in attrs.into_iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
ts = quote! { #ts, };
|
ts = quote! { #ts, };
|
||||||
}
|
}
|
||||||
ts = quote! { #ts #attr };
|
ts = quote! { #ts #attr };
|
||||||
}
|
}
|
||||||
quote! {
|
ts = quote! { #[sea_orm(#ts)] };
|
||||||
#[sea_orm(#ts)]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TokenStream::new()
|
|
||||||
}
|
}
|
||||||
|
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();
|
.collect();
|
||||||
let schema_name = match Self::gen_schema_name(schema_name) {
|
let schema_name = match Self::gen_schema_name(schema_name) {
|
||||||
@ -625,11 +733,12 @@ impl EntityWriter {
|
|||||||
let extra_derive = with_serde.extra_derive();
|
let extra_derive = with_serde.extra_derive();
|
||||||
|
|
||||||
quote! {
|
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(
|
#[sea_orm(
|
||||||
#schema_name
|
#schema_name
|
||||||
table_name = #table_name
|
table_name = #table_name
|
||||||
)]
|
)]
|
||||||
|
#model_extra_attributes
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#(
|
#(
|
||||||
#attrs
|
#attrs
|
||||||
@ -670,6 +779,7 @@ impl EntityWriter {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
entity::writer::{bonus_attributes, bonus_derive},
|
||||||
Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation,
|
Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation,
|
||||||
RelationType, WithSerde,
|
RelationType, WithSerde,
|
||||||
};
|
};
|
||||||
@ -707,6 +817,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
}],
|
}],
|
||||||
conjunct_relations: vec![ConjunctRelation {
|
conjunct_relations: vec![ConjunctRelation {
|
||||||
via: "cake_filling".to_owned(),
|
via: "cake_filling".to_owned(),
|
||||||
@ -744,6 +855,7 @@ mod tests {
|
|||||||
on_update: Some(ForeignKeyAction::Cascade),
|
on_update: Some(ForeignKeyAction::Cascade),
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "filling".to_owned(),
|
ref_table: "filling".to_owned(),
|
||||||
@ -754,6 +866,7 @@ mod tests {
|
|||||||
on_update: Some(ForeignKeyAction::Cascade),
|
on_update: Some(ForeignKeyAction::Cascade),
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
conjunct_relations: vec![],
|
conjunct_relations: vec![],
|
||||||
@ -828,6 +941,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "vendor".to_owned(),
|
ref_table: "vendor".to_owned(),
|
||||||
@ -838,6 +952,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
conjunct_relations: vec![],
|
conjunct_relations: vec![],
|
||||||
@ -879,6 +994,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
}],
|
}],
|
||||||
conjunct_relations: vec![],
|
conjunct_relations: vec![],
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
@ -990,6 +1106,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: true,
|
self_referencing: true,
|
||||||
num_suffix: 1,
|
num_suffix: 1,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "rust_keyword".to_owned(),
|
ref_table: "rust_keyword".to_owned(),
|
||||||
@ -1000,6 +1117,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: true,
|
self_referencing: true,
|
||||||
num_suffix: 2,
|
num_suffix: 2,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "fruit".to_owned(),
|
ref_table: "fruit".to_owned(),
|
||||||
@ -1010,6 +1128,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 1,
|
num_suffix: 1,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "fruit".to_owned(),
|
ref_table: "fruit".to_owned(),
|
||||||
@ -1020,6 +1139,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 2,
|
num_suffix: 2,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
Relation {
|
Relation {
|
||||||
ref_table: "cake".to_owned(),
|
ref_table: "cake".to_owned(),
|
||||||
@ -1030,6 +1150,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
conjunct_relations: vec![],
|
conjunct_relations: vec![],
|
||||||
@ -1071,6 +1192,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
}],
|
}],
|
||||||
conjunct_relations: vec![ConjunctRelation {
|
conjunct_relations: vec![ConjunctRelation {
|
||||||
via: "cake_filling".to_owned(),
|
via: "cake_filling".to_owned(),
|
||||||
@ -1114,6 +1236,7 @@ mod tests {
|
|||||||
on_update: None,
|
on_update: None,
|
||||||
self_referencing: false,
|
self_referencing: false,
|
||||||
num_suffix: 0,
|
num_suffix: 0,
|
||||||
|
impl_related: true,
|
||||||
}],
|
}],
|
||||||
conjunct_relations: vec![ConjunctRelation {
|
conjunct_relations: vec![ConjunctRelation {
|
||||||
via: "cake_filling".to_owned(),
|
via: "cake_filling".to_owned(),
|
||||||
@ -1247,7 +1370,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&None
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1263,7 +1390,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&Some("public".to_owned())
|
&Some("public".to_owned()),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1279,7 +1410,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&Some("schema_name".to_owned())
|
&Some("schema_name".to_owned()),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1331,7 +1466,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&None
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1347,7 +1486,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&Some("public".to_owned())
|
&Some("public".to_owned()),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1363,7 +1506,11 @@ mod tests {
|
|||||||
entity,
|
entity,
|
||||||
&crate::WithSerde::None,
|
&crate::WithSerde::None,
|
||||||
&crate::DateTimeCrate::Chrono,
|
&crate::DateTimeCrate::Chrono,
|
||||||
&Some("schema_name".to_owned())
|
&Some("schema_name".to_owned()),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1385,76 +1532,241 @@ mod tests {
|
|||||||
assert_eq!(cake_entity.get_table_name_snake_case(), "cake");
|
assert_eq!(cake_entity.get_table_name_snake_case(), "cake");
|
||||||
|
|
||||||
// Compact code blocks
|
// Compact code blocks
|
||||||
assert_serde_variant_results(
|
assert_eq!(
|
||||||
&cake_entity,
|
comparable_file_string(include_str!("../../tests/compact_with_serde/cake_none.rs"))?,
|
||||||
&(
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
include_str!("../../tests/compact_with_serde/cake_none.rs").into(),
|
&cake_entity,
|
||||||
WithSerde::None,
|
&WithSerde::None,
|
||||||
None,
|
&DateTimeCrate::Chrono,
|
||||||
),
|
&None,
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
false,
|
||||||
)?;
|
false,
|
||||||
assert_serde_variant_results(
|
&TokenStream::new(),
|
||||||
&cake_entity,
|
&TokenStream::new(),
|
||||||
&(
|
))
|
||||||
include_str!("../../tests/compact_with_serde/cake_serialize.rs").into(),
|
);
|
||||||
WithSerde::Serialize,
|
assert_eq!(
|
||||||
None,
|
comparable_file_string(include_str!(
|
||||||
),
|
"../../tests/compact_with_serde/cake_serialize.rs"
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
))?,
|
||||||
)?;
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
assert_serde_variant_results(
|
&cake_entity,
|
||||||
&cake_entity,
|
&WithSerde::Serialize,
|
||||||
&(
|
&DateTimeCrate::Chrono,
|
||||||
include_str!("../../tests/compact_with_serde/cake_deserialize.rs").into(),
|
&None,
|
||||||
WithSerde::Deserialize,
|
false,
|
||||||
None,
|
false,
|
||||||
),
|
&TokenStream::new(),
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
&TokenStream::new(),
|
||||||
)?;
|
))
|
||||||
assert_serde_variant_results(
|
);
|
||||||
&cake_entity,
|
assert_eq!(
|
||||||
&(
|
comparable_file_string(include_str!(
|
||||||
include_str!("../../tests/compact_with_serde/cake_both.rs").into(),
|
"../../tests/compact_with_serde/cake_deserialize.rs"
|
||||||
WithSerde::Both,
|
))?,
|
||||||
None,
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
),
|
&cake_entity,
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
&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
|
// 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(
|
assert_serde_variant_results(
|
||||||
&cake_entity,
|
&cake_entity,
|
||||||
&(
|
&(
|
||||||
include_str!("../../tests/expanded_with_serde/cake_none.rs").into(),
|
include_str!("../../tests/compact_with_serde/cake_serialize_with_hidden_column.rs"),
|
||||||
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(),
|
|
||||||
WithSerde::Serialize,
|
WithSerde::Serialize,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
Box::new(EntityWriter::gen_compact_code_blocks),
|
||||||
)?;
|
)?;
|
||||||
assert_serde_variant_results(
|
assert_serde_variant_results(
|
||||||
&cake_entity,
|
&cake_entity,
|
||||||
&(
|
&(
|
||||||
include_str!("../../tests/expanded_with_serde/cake_deserialize.rs").into(),
|
include_str!(
|
||||||
WithSerde::Deserialize,
|
"../../tests/expanded_with_serde/cake_serialize_with_hidden_column.rs"
|
||||||
None,
|
),
|
||||||
),
|
WithSerde::Serialize,
|
||||||
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,
|
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
Box::new(EntityWriter::gen_expanded_code_blocks),
|
||||||
@ -1466,13 +1778,174 @@ mod tests {
|
|||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn assert_serde_variant_results(
|
fn assert_serde_variant_results(
|
||||||
cake_entity: &Entity,
|
cake_entity: &Entity,
|
||||||
entity_serde_variant: &(String, WithSerde, Option<String>),
|
entity_serde_variant: &(&str, WithSerde, Option<String>),
|
||||||
generator: Box<
|
generator: Box<
|
||||||
dyn Fn(&Entity, &WithSerde, &DateTimeCrate, &Option<String>) -> Vec<TokenStream>,
|
dyn Fn(
|
||||||
|
&Entity,
|
||||||
|
&WithSerde,
|
||||||
|
&DateTimeCrate,
|
||||||
|
&Option<String>,
|
||||||
|
bool,
|
||||||
|
bool,
|
||||||
|
&TokenStream,
|
||||||
|
&TokenStream,
|
||||||
|
) -> Vec<TokenStream>,
|
||||||
>,
|
>,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let mut reader = BufReader::new(entity_serde_variant.0.as_bytes());
|
let mut reader = BufReader::new(entity_serde_variant.0.as_bytes());
|
||||||
let mut lines: Vec<String> = Vec::new();
|
let mut lines: Vec<String> = 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<TokenStream>) -> String {
|
||||||
|
generated
|
||||||
|
.into_iter()
|
||||||
|
.fold(TokenStream::new(), |mut acc, tok| {
|
||||||
|
acc.extend(tok);
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn comparable_file_string(file: &str) -> io::Result<String> {
|
||||||
|
let mut reader = BufReader::new(file.as_bytes());
|
||||||
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
reader.read_until(b'\n', &mut Vec::new())?;
|
reader.read_until(b'\n', &mut Vec::new())?;
|
||||||
|
|
||||||
@ -1483,19 +1956,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
let content = lines.join("");
|
let content = lines.join("");
|
||||||
let expected: TokenStream = content.parse().unwrap();
|
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(expected.to_string())
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_attributes/cake_none.rs
Normal file
35
sea-orm-codegen/tests/compact_with_attributes/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
36
sea-orm-codegen/tests/compact_with_attributes/cake_one.rs
Normal file
36
sea-orm-codegen/tests/compact_with_attributes/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_none.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_one.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[sea_orm(table_name = "cake")]
|
#[sea_orm(table_name = "cake")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
#[sea_orm(column_type = "Text", nullable)]
|
#[sea_orm(column_type = "Text", nullable)]
|
||||||
pub name: Option<String> ,
|
pub name: Option<String> ,
|
||||||
|
@ -7,6 +7,7 @@ use serde::Deserialize;
|
|||||||
#[sea_orm(table_name = "cake")]
|
#[sea_orm(table_name = "cake")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
#[sea_orm(column_type = "Text", nullable)]
|
#[sea_orm(column_type = "Text", nullable)]
|
||||||
pub name: Option<String> ,
|
pub name: Option<String> ,
|
||||||
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
78
sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs
Normal file
78
sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_none.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_one.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Id,
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
|
||||||
|
pub enum PrimaryKey {
|
||||||
|
Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimaryKeyTrait for PrimaryKey {
|
||||||
|
type ValueType = i32;
|
||||||
|
|
||||||
|
fn auto_increment() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
|
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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -14,6 +14,7 @@ impl EntityName for Entity {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize, Deserialize)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: Option<String> ,
|
pub name: Option<String> ,
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ impl EntityName for Entity {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Deserialize)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: Option<String> ,
|
pub name: Option<String> ,
|
||||||
}
|
}
|
||||||
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -18,15 +18,15 @@ path = "src/lib.rs"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bae = "^0.1"
|
bae = { version = "0.1", default-features = false }
|
||||||
syn = { version = "^1", default-features = false, features = [ "full", "derive", "clone-impls", "parsing", "proc-macro", "printing", "extra-traits" ] }
|
syn = { version = "1", default-features = false }
|
||||||
quote = "^1"
|
quote = { version = "1", default-features = false }
|
||||||
heck = "^0.3"
|
heck = { version = "0.3", default-features = false }
|
||||||
proc-macro2 = "^1"
|
proc-macro2 = { version = "1", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
sea-orm = { path = "../", features = ["macros"] }
|
sea-orm = { path = "../", features = ["macros"] }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
postgres-array = []
|
postgres-array = []
|
||||||
|
@ -20,17 +20,17 @@ name = "sea_orm_migration"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = { version = "^0.1" }
|
async-trait = { version = "0.1", default-features = false }
|
||||||
clap = { version = "^3.2", features = ["env", "derive"], optional = true }
|
clap = { version = "3.2", default-features = false, features = ["std", "env", "derive"], optional = true }
|
||||||
dotenvy = { version = "^0.15", 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 = { 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-orm-cli = { version = "0.10.3", path = "../sea-orm-cli", default-features = false, optional = true }
|
||||||
sea-schema = { version = "^0.10.2" }
|
sea-schema = { version = "0.10.2" }
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
tracing = { version = "0.1", default-features = false, features = ["log"] }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "^1", features = ["attributes", "tokio1"] }
|
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["cli"]
|
default = ["cli"]
|
||||||
|
@ -174,9 +174,8 @@ impl DatabaseTransaction {
|
|||||||
|
|
||||||
/// Commit a transaction atomically
|
/// Commit a transaction atomically
|
||||||
#[instrument(level = "trace")]
|
#[instrument(level = "trace")]
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code, unused_mut)]
|
||||||
pub async fn commit(mut self) -> Result<(), DbErr> {
|
pub async fn commit(mut self) -> Result<(), DbErr> {
|
||||||
self.open = false;
|
|
||||||
match *self.conn.lock().await {
|
match *self.conn.lock().await {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
InnerConnection::MySql(ref mut c) => {
|
InnerConnection::MySql(ref mut c) => {
|
||||||
@ -201,14 +200,14 @@ impl DatabaseTransaction {
|
|||||||
c.commit();
|
c.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.open = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// rolls back a transaction in case error are encountered during the operation
|
/// rolls back a transaction in case error are encountered during the operation
|
||||||
#[instrument(level = "trace")]
|
#[instrument(level = "trace")]
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code, unused_mut)]
|
||||||
pub async fn rollback(mut self) -> Result<(), DbErr> {
|
pub async fn rollback(mut self) -> Result<(), DbErr> {
|
||||||
self.open = false;
|
|
||||||
match *self.conn.lock().await {
|
match *self.conn.lock().await {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
InnerConnection::MySql(ref mut c) => {
|
InnerConnection::MySql(ref mut c) => {
|
||||||
@ -233,6 +232,7 @@ impl DatabaseTransaction {
|
|||||||
c.rollback();
|
c.rollback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.open = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 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;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// Defines the type of relationship
|
/// 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<String> = 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<RelationDef> 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<RelationDef> 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -45,8 +45,8 @@ where
|
|||||||
let query = self
|
let query = self
|
||||||
.query
|
.query
|
||||||
.clone()
|
.clone()
|
||||||
.limit(self.page_size as u64)
|
.limit(self.page_size)
|
||||||
.offset((self.page_size * page) as u64)
|
.offset(self.page_size * page)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let builder = self.db.get_database_backend();
|
let builder = self.db.get_database_backend();
|
||||||
let stmt = builder.build(&query);
|
let stmt = builder.build(&query);
|
||||||
|
@ -189,7 +189,8 @@ where
|
|||||||
for col in E::Column::iter() {
|
for col in E::Column::iter() {
|
||||||
let av = model.get(col);
|
let av = model.get(col);
|
||||||
if av.is_set() {
|
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
|
self
|
||||||
@ -207,7 +208,7 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
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 crate::{entity::*, query::*, DbBackend};
|
||||||
use sea_query::{Expr, Value};
|
use sea_query::{Expr, Value};
|
||||||
|
|
||||||
@ -294,4 +295,33 @@ mod tests {
|
|||||||
r#"UPDATE "fruit" SET "id" = 3 WHERE "fruit"."id" = 2"#,
|
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"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
unpack_table_ref, ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, Identity,
|
ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, Iterable, PrimaryKeyToColumn,
|
||||||
Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, RelationTrait, Schema,
|
PrimaryKeyTrait, RelationTrait, Schema,
|
||||||
};
|
};
|
||||||
use sea_query::{
|
use sea_query::{
|
||||||
extension::postgres::{Type, TypeCreateStatement},
|
extension::postgres::{Type, TypeCreateStatement},
|
||||||
ColumnDef, ForeignKeyCreateStatement, Iden, Index, IndexCreateStatement, TableCreateStatement,
|
ColumnDef, Iden, Index, IndexCreateStatement, TableCreateStatement,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Schema {
|
impl Schema {
|
||||||
@ -40,6 +40,51 @@ impl Schema {
|
|||||||
{
|
{
|
||||||
create_index_from_entity(entity, self.backend)
|
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::<Entity>(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<E>(&self, column: E::Column) -> ColumnDef
|
||||||
|
where
|
||||||
|
E: EntityTrait,
|
||||||
|
{
|
||||||
|
column_def_from_entity_column::<E>(column, self.backend)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_enum_from_active_enum<A>(backend: DbBackend) -> TypeCreateStatement
|
pub(crate) fn create_enum_from_active_enum<A>(backend: DbBackend) -> TypeCreateStatement
|
||||||
@ -117,39 +162,7 @@ where
|
|||||||
let mut stmt = TableCreateStatement::new();
|
let mut stmt = TableCreateStatement::new();
|
||||||
|
|
||||||
for column in E::Column::iter() {
|
for column in E::Column::iter() {
|
||||||
let orm_column_def = column.def();
|
let mut column_def = column_def_from_entity_column::<E>(column, backend);
|
||||||
let types = match orm_column_def.col_type {
|
|
||||||
ColumnType::Enum { name, variants } => match backend {
|
|
||||||
DbBackend::MySql => {
|
|
||||||
let variants: Vec<String> = 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stmt.col(&mut column_def);
|
stmt.col(&mut column_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,57 +179,52 @@ where
|
|||||||
if relation.is_owner {
|
if relation.is_owner {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut foreign_key_stmt = ForeignKeyCreateStatement::new();
|
stmt.foreign_key(&mut relation.into());
|
||||||
let from_tbl = unpack_table_ref(&relation.from_tbl);
|
|
||||||
let to_tbl = unpack_table_ref(&relation.to_tbl);
|
|
||||||
let from_cols: Vec<String> = 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.table(entity.table_ref()).take()
|
stmt.table(entity.table_ref()).take()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn column_def_from_entity_column<E>(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<String> = 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{sea_query::*, tests_cfg::*, DbBackend, EntityName, Schema};
|
use crate::{sea_query::*, tests_cfg::*, DbBackend, EntityName, Schema};
|
||||||
|
70
tests/common/features/event_trigger.rs
Normal file
70
tests/common/features/event_trigger.rs
Normal file
@ -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<Event>);
|
||||||
|
|
||||||
|
impl From<Events> 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<Self, TryGetError> {
|
||||||
|
let vec: Vec<String> = 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<Self, sea_query::ValueTypeErr> {
|
||||||
|
let value: Option<Vec<String>> =
|
||||||
|
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))))
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ pub mod applog;
|
|||||||
pub mod byte_primary_key;
|
pub mod byte_primary_key;
|
||||||
pub mod collection;
|
pub mod collection;
|
||||||
pub mod custom_active_model;
|
pub mod custom_active_model;
|
||||||
|
pub mod event_trigger;
|
||||||
pub mod insert_default;
|
pub mod insert_default;
|
||||||
pub mod json_struct;
|
pub mod json_struct;
|
||||||
pub mod json_vec;
|
pub mod json_vec;
|
||||||
@ -21,6 +22,7 @@ pub use active_enum_child::Entity as ActiveEnumChild;
|
|||||||
pub use applog::Entity as Applog;
|
pub use applog::Entity as Applog;
|
||||||
pub use byte_primary_key::Entity as BytePrimaryKey;
|
pub use byte_primary_key::Entity as BytePrimaryKey;
|
||||||
pub use collection::Entity as Collection;
|
pub use collection::Entity as Collection;
|
||||||
|
pub use event_trigger::Entity as EventTrigger;
|
||||||
pub use insert_default::Entity as InsertDefault;
|
pub use insert_default::Entity as InsertDefault;
|
||||||
pub use json_struct::Entity as JsonStruct;
|
pub use json_struct::Entity as JsonStruct;
|
||||||
pub use json_vec::Entity as JsonVec;
|
pub use json_vec::Entity as JsonVec;
|
||||||
|
@ -45,6 +45,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
|
|
||||||
if DbBackend::Postgres == db_backend {
|
if DbBackend::Postgres == db_backend {
|
||||||
create_collection_table(db).await?;
|
create_collection_table(db).await?;
|
||||||
|
create_event_trigger_table(db).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -411,3 +412,23 @@ pub async fn create_pi_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|||||||
|
|
||||||
create_table(db, &stmt, Pi).await
|
create_table(db, &stmt, Pi).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_event_trigger_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
48
tests/event_trigger_tests.rs
Normal file
48
tests/event_trigger_tests.rs
Normal file
@ -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(())
|
||||||
|
}
|
@ -27,8 +27,8 @@ pub async fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
key: "markup".to_owned(),
|
key: "markup".to_owned(),
|
||||||
value: "1.18".to_owned(),
|
value: "1.18".to_owned(),
|
||||||
bytes: vec![1, 2, 3],
|
bytes: vec![1, 2, 3],
|
||||||
date: Some(Date::from_ymd(2021, 9, 27)),
|
date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),
|
||||||
time: Some(Time::from_hms(11, 32, 55)),
|
time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),
|
||||||
},
|
},
|
||||||
metadata::Model {
|
metadata::Model {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
@ -36,8 +36,8 @@ pub async fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
key: "exchange_rate".to_owned(),
|
key: "exchange_rate".to_owned(),
|
||||||
value: "0.78".to_owned(),
|
value: "0.78".to_owned(),
|
||||||
bytes: vec![1, 2, 3],
|
bytes: vec![1, 2, 3],
|
||||||
date: Some(Date::from_ymd(2021, 9, 27)),
|
date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),
|
||||||
time: Some(Time::from_hms(11, 32, 55)),
|
time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),
|
||||||
},
|
},
|
||||||
metadata::Model {
|
metadata::Model {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
|
@ -23,7 +23,7 @@ pub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
let model = self_join::Model {
|
let model = self_join::Model {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
uuid_ref: None,
|
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?;
|
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 {
|
let linked_model = self_join::Model {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
uuid_ref: Some(model.clone().uuid),
|
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?;
|
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 {
|
let not_linked_model = self_join::Model {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
uuid_ref: None,
|
uuid_ref: None,
|
||||||
time: Some(Time::from_hms(3, 00, 00)),
|
time: Some(Time::from_hms_opt(3, 00, 00).unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
not_linked_model
|
not_linked_model
|
||||||
|
@ -28,8 +28,8 @@ pub async fn insert_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
key: "markup".to_owned(),
|
key: "markup".to_owned(),
|
||||||
value: "1.18".to_owned(),
|
value: "1.18".to_owned(),
|
||||||
bytes: vec![1, 2, 3],
|
bytes: vec![1, 2, 3],
|
||||||
date: Some(Date::from_ymd(2021, 9, 27)),
|
date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),
|
||||||
time: Some(Time::from_hms(11, 32, 55)),
|
time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = metadata.clone().into_active_model().insert(db).await?;
|
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(),
|
key: "markup".to_owned(),
|
||||||
value: "1.18".to_owned(),
|
value: "1.18".to_owned(),
|
||||||
bytes: vec![1, 2, 3],
|
bytes: vec![1, 2, 3],
|
||||||
date: Some(Date::from_ymd(2021, 9, 27)),
|
date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),
|
||||||
time: Some(Time::from_hms(11, 32, 55)),
|
time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = Metadata::insert(metadata.clone().into_active_model())
|
let res = Metadata::insert(metadata.clone().into_active_model())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user