Merge branch 'master' into ss/test_suite
# Conflicts: # Cargo.toml
This commit is contained in:
commit
6efb06d28b
95
.github/workflows/rust.yml
vendored
95
.github/workflows/rust.yml
vendored
@ -15,6 +15,86 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
name: Unit Test
|
name: Unit Test
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# runtime: [async-std-native-tls, async-std-rustls, actix-native-tls, actix-rustls, tokio-native-tls, tokio-rustls]
|
||||||
|
runtime: [async-std-native-tls]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-test-${{ matrix.runtime }}-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,runtime-${{ matrix.runtime }}
|
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,runtime-${{ matrix.runtime }}
|
||||||
|
|
||||||
|
sqlite:
|
||||||
|
name: SQLite
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# runtime: [async-std-native-tls, async-std-rustls, actix-native-tls, actix-rustls, tokio-native-tls, tokio-rustls]
|
||||||
|
runtime: [async-std-native-tls]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-sqlite-${{ matrix.runtime }}-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,runtime-${{ matrix.runtime }}
|
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,sqlx-sqlite,runtime-${{ matrix.runtime }}
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
name: Postgres
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# runtime: [async-std-native-tls, async-std-rustls, actix-native-tls, actix-rustls, tokio-native-tls, tokio-rustls]
|
||||||
|
runtime: [async-std-native-tls]
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
image: mysql:8.0
|
image: mysql:8.0
|
||||||
@ -50,11 +130,24 @@ jobs:
|
|||||||
toolchain: stable
|
toolchain: stable
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
target
|
||||||
|
key: ${{ runner.os }}-postgres-${{ matrix.runtime }}-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,runtime-${{ matrix.runtime }}
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --all
|
args: >
|
||||||
|
--all
|
||||||
|
--features default,sqlx-postgres,runtime-${{ matrix.runtime }}
|
||||||
|
47
Cargo.toml
47
Cargo.toml
@ -42,9 +42,9 @@ chrono = { version = "^0", optional = true }
|
|||||||
futures = { version = "^0.3" }
|
futures = { version = "^0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "^0.3" }
|
||||||
rust_decimal = { version = "^1", optional = true }
|
rust_decimal = { version = "^1", optional = true }
|
||||||
# sea-query = { version = "^0.12" }
|
sea-query = { version = "^0.12" }
|
||||||
# sea-query = { path = "../sea-query" }
|
# sea-query = { path = "../sea-query" }
|
||||||
sea-query = { version = "^0.12", git = "https://github.com/samsamai/sea-query.git", branch = "ss/uuid" }
|
# sea-query = { version = "^0.12", git = "https://github.com/samsamai/sea-query.git", branch = "ss/uuid" }
|
||||||
sea-orm-macros = { path = "sea-orm-macros", optional = true }
|
sea-orm-macros = { path = "sea-orm-macros", optional = true }
|
||||||
sea-orm-codegen = { path = "sea-orm-codegen", optional = true }
|
sea-orm-codegen = { path = "sea-orm-codegen", optional = true }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
@ -60,17 +60,15 @@ uuid = { version = "0.8", features = ["serde", "v4"], optional = true }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "^1.9", features = ["attributes"] }
|
async-std = { version = "^1.9", features = ["attributes"] }
|
||||||
|
tokio = { version = "^1.6", features = ["full"] }
|
||||||
|
actix-rt = { version = "2.2.0" }
|
||||||
maplit = { version = "^1" }
|
maplit = { version = "^1" }
|
||||||
rust_decimal_macros = { version = "^1" }
|
rust_decimal_macros = { version = "^1" }
|
||||||
|
|
||||||
sea-orm = { path = ".", features = [
|
sea-orm = { path = ".", features = [
|
||||||
"sqlx-postgres",
|
|
||||||
"sqlx-mysql",
|
|
||||||
"sqlx-sqlite",
|
|
||||||
"sqlx-json",
|
"sqlx-json",
|
||||||
"sqlx-chrono",
|
"sqlx-chrono",
|
||||||
"sqlx-decimal",
|
"sqlx-decimal",
|
||||||
"runtime-async-std-native-tls",
|
"debug-print",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -83,6 +81,10 @@ default = [
|
|||||||
"with-rust_decimal",
|
"with-rust_decimal",
|
||||||
"mock",
|
"mock",
|
||||||
"with-uuid",
|
"with-uuid",
|
||||||
|
"sqlx-postgres",
|
||||||
|
"sqlx-mysql",
|
||||||
|
"sqlx-sqlite",
|
||||||
|
|
||||||
]
|
]
|
||||||
macros = ["sea-orm-macros"]
|
macros = ["sea-orm-macros"]
|
||||||
codegen = ["sea-orm-codegen"]
|
codegen = ["sea-orm-codegen"]
|
||||||
@ -103,9 +105,28 @@ sqlx-decimal = ["sqlx/decimal", "with-rust_decimal"]
|
|||||||
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
|
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
|
||||||
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
|
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
|
||||||
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
|
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
|
||||||
runtime-actix-native-tls = ["sqlx/runtime-actix-native-tls"]
|
runtime-async-std = []
|
||||||
runtime-async-std-native-tls = ["sqlx/runtime-async-std-native-tls"]
|
runtime-async-std-native-tls = [
|
||||||
runtime-tokio-native-tls = ["sqlx/runtime-tokio-native-tls"]
|
"sqlx/runtime-async-std-native-tls",
|
||||||
runtime-actix-rustls = ["sqlx/runtime-actix-rustls"]
|
"runtime-async-std",
|
||||||
runtime-async-std-rustls = ["sqlx/runtime-async-std-rustls"]
|
]
|
||||||
runtime-tokio-rustls = ["sqlx/runtime-tokio-rustls"]
|
runtime-async-std-rustls = [
|
||||||
|
"sqlx/runtime-async-std-rustls",
|
||||||
|
"runtime-async-std",
|
||||||
|
]
|
||||||
|
runtime-actix = []
|
||||||
|
runtime-actix-native-tls = ["sqlx/runtime-actix-native-tls", "runtime-actix"]
|
||||||
|
runtime-actix-rustls = ["sqlx/runtime-actix-rustls", "runtime-actix"]
|
||||||
|
runtime-tokio = []
|
||||||
|
runtime-tokio-native-tls = ["sqlx/runtime-tokio-native-tls", "runtime-tokio"]
|
||||||
|
runtime-tokio-rustls = ["sqlx/runtime-tokio-rustls", "runtime-tokio"]
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "sqlite-basic"
|
||||||
|
path = "tests/basic.rs"
|
||||||
|
required-features = ["sqlx-sqlite"]
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "postgres"
|
||||||
|
path = "tests/pg_tests.rs"
|
||||||
|
required-features = ["sqlx-postgres"]
|
||||||
|
@ -5,5 +5,5 @@ edition = "2018"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print" ] }
|
sea-orm = { path = "../../" }
|
||||||
strum = { version = "^0.20", features = [ "derive" ] }
|
strum = { version = "^0.20", features = [ "derive" ] }
|
||||||
|
@ -36,7 +36,6 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
CakeFilling,
|
|
||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,22 +52,24 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
|
||||||
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::CakeFilling.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::fruit::Entity> for Entity {
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Fruit.def()
|
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 {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
@ -35,9 +35,7 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {}
|
||||||
CakeFilling,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
@ -52,14 +50,17 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
_ => panic!("No RelationDef"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
impl Related<super::cake::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::CakeFilling.def()
|
super::cake_filling::Relation::Cake.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Filling.def().rev())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1.9", features = [ "attributes" ] }
|
async-std = { version = "^1.9", features = [ "attributes" ] }
|
||||||
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print" ] }
|
sea-orm = { path = "../../" }
|
||||||
sea-orm-codegen = { path = "../../sea-orm-codegen" }
|
sea-orm-codegen = { path = "../../sea-orm-codegen" }
|
||||||
sea-query = { version = "^0.12" }
|
sea-query = { version = "^0.12" }
|
||||||
strum = { version = "^0.20", features = [ "derive" ] }
|
strum = { version = "^0.20", features = [ "derive" ] }
|
||||||
|
@ -36,7 +36,6 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
CakeFilling,
|
|
||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,22 +52,24 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
|
||||||
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::CakeFilling.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::fruit::Entity> for Entity {
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Fruit.def()
|
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 {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
@ -35,9 +35,7 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {}
|
||||||
CakeFilling,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
@ -52,14 +50,17 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
_ => panic!("No RelationDef"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
impl Related<super::cake::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::CakeFilling.def()
|
super::cake_filling::Relation::Cake.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Filling.def().rev())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ publish = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1.9", features = [ "attributes" ] }
|
async-std = { version = "^1.9", features = [ "attributes" ] }
|
||||||
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print", "sqlx-json", "macros" ], default-features = false }
|
sea-orm = { path = "../../" }
|
||||||
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" }
|
||||||
|
@ -16,9 +16,9 @@ name = "sea_orm_codegen"
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sea-schema = { version = "^0.2", default-features = false, features = [ "sqlx-mysql", "runtime-async-std-native-tls", "discovery", "writer" ] }
|
sea-schema = { version = "^0.2", default-features = false, features = [ "sqlx-mysql", "discovery", "writer" ] }
|
||||||
sea-query = { version = "^0.12" }
|
sea-query = { version = "^0.12" }
|
||||||
sqlx = { version = "^0.5", features = [ "mysql", "runtime-async-std-native-tls" ] }
|
sqlx = { version = "^0.5", default-features = false, features = [ "mysql" ] }
|
||||||
syn = { version = "^1", default-features = false, features = [ "derive", "parsing", "proc-macro", "printing" ] }
|
syn = { version = "^1", default-features = false, features = [ "derive", "parsing", "proc-macro", "printing" ] }
|
||||||
quote = "^1"
|
quote = "^1"
|
||||||
heck = "^0.3"
|
heck = "^0.3"
|
||||||
@ -26,4 +26,30 @@ proc-macro2 = "^1"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "^1.9", features = [ "attributes" ] }
|
async-std = { version = "^1.9", features = [ "attributes" ] }
|
||||||
sea-orm = { path = "../", features = ["mock", "sqlx-json", "sqlx-chrono", "runtime-async-std-native-tls"] }
|
sea-orm = { path = "../" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
runtime-actix-native-tls = [
|
||||||
|
"sqlx/runtime-actix-native-tls",
|
||||||
|
"sea-schema/runtime-actix-native-tls",
|
||||||
|
]
|
||||||
|
runtime-async-std-native-tls = [
|
||||||
|
"sqlx/runtime-async-std-native-tls",
|
||||||
|
"sea-schema/runtime-async-std-native-tls",
|
||||||
|
]
|
||||||
|
runtime-tokio-native-tls = [
|
||||||
|
"sqlx/runtime-tokio-native-tls",
|
||||||
|
"sea-schema/runtime-tokio-native-tls",
|
||||||
|
]
|
||||||
|
runtime-actix-rustls = [
|
||||||
|
"sqlx/runtime-actix-rustls",
|
||||||
|
"sea-schema/runtime-actix-rustls",
|
||||||
|
]
|
||||||
|
runtime-async-std-rustls = [
|
||||||
|
"sqlx/runtime-async-std-rustls",
|
||||||
|
"sea-schema/runtime-async-std-rustls",
|
||||||
|
]
|
||||||
|
runtime-tokio-rustls = [
|
||||||
|
"sqlx/runtime-tokio-rustls",
|
||||||
|
"sea-schema/runtime-tokio-rustls",
|
||||||
|
]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Column, PrimaryKey, Relation};
|
use crate::{Column, ConjunctRelation, PrimaryKey, Relation};
|
||||||
use heck::{CamelCase, SnakeCase};
|
use heck::{CamelCase, SnakeCase};
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::format_ident;
|
use quote::format_ident;
|
||||||
@ -8,6 +8,7 @@ pub struct Entity {
|
|||||||
pub(crate) table_name: String,
|
pub(crate) table_name: String,
|
||||||
pub(crate) columns: Vec<Column>,
|
pub(crate) columns: Vec<Column>,
|
||||||
pub(crate) relations: Vec<Relation>,
|
pub(crate) relations: Vec<Relation>,
|
||||||
|
pub(crate) conjunct_relations: Vec<ConjunctRelation>,
|
||||||
pub(crate) primary_keys: Vec<PrimaryKey>,
|
pub(crate) primary_keys: Vec<PrimaryKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +116,27 @@ impl Entity {
|
|||||||
let auto_increment = self.columns.iter().any(|col| col.auto_increment);
|
let auto_increment = self.columns.iter().any(|col| col.auto_increment);
|
||||||
format_ident!("{}", auto_increment)
|
format_ident!("{}", auto_increment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_conjunct_relations_via_snake_case(&self) -> Vec<Ident> {
|
||||||
|
self.conjunct_relations
|
||||||
|
.iter()
|
||||||
|
.map(|con_rel| con_rel.get_via_snake_case())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_conjunct_relations_to_snake_case(&self) -> Vec<Ident> {
|
||||||
|
self.conjunct_relations
|
||||||
|
.iter()
|
||||||
|
.map(|con_rel| con_rel.get_to_snake_case())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_conjunct_relations_to_camel_case(&self) -> Vec<Ident> {
|
||||||
|
self.conjunct_relations
|
||||||
|
.iter()
|
||||||
|
.map(|con_rel| con_rel.get_to_camel_case())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -156,6 +178,7 @@ mod tests {
|
|||||||
rel_type: RelationType::HasOne,
|
rel_type: RelationType::HasOne,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
conjunct_relations: vec![],
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
name: "id".to_owned(),
|
name: "id".to_owned(),
|
||||||
}],
|
}],
|
||||||
@ -349,4 +372,43 @@ mod tests {
|
|||||||
format_ident!("{}", true)
|
format_ident!("{}", true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_conjunct_relations_via_snake_case() {
|
||||||
|
let entity = setup();
|
||||||
|
|
||||||
|
for (i, elem) in entity
|
||||||
|
.get_conjunct_relations_via_snake_case()
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
assert_eq!(elem, entity.conjunct_relations[i].get_via_snake_case());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_conjunct_relations_to_snake_case() {
|
||||||
|
let entity = setup();
|
||||||
|
|
||||||
|
for (i, elem) in entity
|
||||||
|
.get_conjunct_relations_to_snake_case()
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
assert_eq!(elem, entity.conjunct_relations[i].get_to_snake_case());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_conjunct_relations_to_camel_case() {
|
||||||
|
let entity = setup();
|
||||||
|
|
||||||
|
for (i, elem) in entity
|
||||||
|
.get_conjunct_relations_to_camel_case()
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
assert_eq!(elem, entity.conjunct_relations[i].get_to_camel_case());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
68
sea-orm-codegen/src/entity/conjunct_relation.rs
Normal file
68
sea-orm-codegen/src/entity/conjunct_relation.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use heck::{CamelCase, SnakeCase};
|
||||||
|
use proc_macro2::Ident;
|
||||||
|
use quote::format_ident;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ConjunctRelation {
|
||||||
|
pub(crate) via: String,
|
||||||
|
pub(crate) to: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConjunctRelation {
|
||||||
|
pub fn get_via_snake_case(&self) -> Ident {
|
||||||
|
format_ident!("{}", self.via.to_snake_case())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_to_snake_case(&self) -> Ident {
|
||||||
|
format_ident!("{}", self.to.to_snake_case())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_to_camel_case(&self) -> Ident {
|
||||||
|
format_ident!("{}", self.to.to_camel_case())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::ConjunctRelation;
|
||||||
|
|
||||||
|
fn setup() -> Vec<ConjunctRelation> {
|
||||||
|
vec![
|
||||||
|
ConjunctRelation {
|
||||||
|
via: "cake_filling".to_owned(),
|
||||||
|
to: "cake".to_owned(),
|
||||||
|
},
|
||||||
|
ConjunctRelation {
|
||||||
|
via: "cake_filling".to_owned(),
|
||||||
|
to: "filling".to_owned(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_via_snake_case() {
|
||||||
|
let conjunct_relations = setup();
|
||||||
|
let via_vec = vec!["cake_filling", "cake_filling"];
|
||||||
|
for (con_rel, via) in conjunct_relations.into_iter().zip(via_vec) {
|
||||||
|
assert_eq!(con_rel.get_via_snake_case(), via);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_to_snake_case() {
|
||||||
|
let conjunct_relations = setup();
|
||||||
|
let to_vec = vec!["cake", "filling"];
|
||||||
|
for (con_rel, to) in conjunct_relations.into_iter().zip(to_vec) {
|
||||||
|
assert_eq!(con_rel.get_to_snake_case(), to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_to_camel_case() {
|
||||||
|
let conjunct_relations = setup();
|
||||||
|
let to_vec = vec!["Cake", "Filling"];
|
||||||
|
for (con_rel, to) in conjunct_relations.into_iter().zip(to_vec) {
|
||||||
|
assert_eq!(con_rel.get_to_camel_case(), to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
mod base_entity;
|
mod base_entity;
|
||||||
mod column;
|
mod column;
|
||||||
|
mod conjunct_relation;
|
||||||
mod generator;
|
mod generator;
|
||||||
mod primary_key;
|
mod primary_key;
|
||||||
mod relation;
|
mod relation;
|
||||||
@ -8,6 +9,7 @@ mod writer;
|
|||||||
|
|
||||||
pub use base_entity::*;
|
pub use base_entity::*;
|
||||||
pub use column::*;
|
pub use column::*;
|
||||||
|
pub use conjunct_relation::*;
|
||||||
pub use generator::*;
|
pub use generator::*;
|
||||||
pub use primary_key::*;
|
pub use primary_key::*;
|
||||||
pub use relation::*;
|
pub use relation::*;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::{Column, Entity, EntityWriter, Error, PrimaryKey, Relation, RelationType};
|
use crate::{
|
||||||
|
Column, ConjunctRelation, Entity, EntityWriter, Error, PrimaryKey, Relation, RelationType,
|
||||||
|
};
|
||||||
use sea_query::TableStatement;
|
use sea_query::TableStatement;
|
||||||
use sea_schema::mysql::def::Schema;
|
use sea_schema::mysql::def::Schema;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -11,7 +13,8 @@ pub struct EntityTransformer {
|
|||||||
impl EntityTransformer {
|
impl EntityTransformer {
|
||||||
pub fn transform(self) -> Result<EntityWriter, Error> {
|
pub fn transform(self) -> Result<EntityWriter, Error> {
|
||||||
let mut inverse_relations: HashMap<String, Vec<Relation>> = HashMap::new();
|
let mut inverse_relations: HashMap<String, Vec<Relation>> = HashMap::new();
|
||||||
let mut entities = Vec::new();
|
let mut conjunct_relations: HashMap<String, Vec<ConjunctRelation>> = HashMap::new();
|
||||||
|
let mut entities = HashMap::new();
|
||||||
for table_ref in self.schema.tables.iter() {
|
for table_ref in self.schema.tables.iter() {
|
||||||
let table_stmt = table_ref.write();
|
let table_stmt = table_ref.write();
|
||||||
let table_create = match table_stmt {
|
let table_create = match table_stmt {
|
||||||
@ -63,42 +66,65 @@ impl EntityTransformer {
|
|||||||
table_name: table_name.clone(),
|
table_name: table_name.clone(),
|
||||||
columns,
|
columns,
|
||||||
relations: relations.clone().collect(),
|
relations: relations.clone().collect(),
|
||||||
|
conjunct_relations: vec![],
|
||||||
primary_keys,
|
primary_keys,
|
||||||
};
|
};
|
||||||
entities.push(entity);
|
entities.insert(table_name.clone(), entity.clone());
|
||||||
for mut rel in relations.into_iter() {
|
for (i, mut rel) in relations.into_iter().enumerate() {
|
||||||
let ref_table = rel.ref_table;
|
let is_conjunct_relation = entity.primary_keys.len() == entity.columns.len()
|
||||||
let mut unique = true;
|
&& entity.primary_keys.len() == 2;
|
||||||
for col in rel.columns.iter() {
|
match is_conjunct_relation {
|
||||||
if !unique_columns.contains(col) {
|
true => {
|
||||||
unique = false;
|
let another_rel = entity.relations.get((i == 0) as usize).unwrap();
|
||||||
break;
|
let conjunct_relation = ConjunctRelation {
|
||||||
|
via: table_name.clone(),
|
||||||
|
to: another_rel.ref_table.clone(),
|
||||||
|
};
|
||||||
|
if let Some(vec) = conjunct_relations.get_mut(&rel.ref_table) {
|
||||||
|
vec.push(conjunct_relation);
|
||||||
|
} else {
|
||||||
|
conjunct_relations.insert(rel.ref_table, vec![conjunct_relation]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false => {
|
||||||
|
let ref_table = rel.ref_table;
|
||||||
|
let mut unique = true;
|
||||||
|
for col in rel.columns.iter() {
|
||||||
|
if !unique_columns.contains(col) {
|
||||||
|
unique = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let rel_type = if unique {
|
||||||
|
RelationType::HasOne
|
||||||
|
} else {
|
||||||
|
RelationType::HasMany
|
||||||
|
};
|
||||||
|
rel.rel_type = rel_type;
|
||||||
|
rel.ref_table = table_name.clone();
|
||||||
|
rel.columns = Vec::new();
|
||||||
|
rel.ref_columns = Vec::new();
|
||||||
|
if let Some(vec) = inverse_relations.get_mut(&ref_table) {
|
||||||
|
vec.push(rel);
|
||||||
|
} else {
|
||||||
|
inverse_relations.insert(ref_table, vec![rel]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let rel_type = if unique {
|
|
||||||
RelationType::HasOne
|
|
||||||
} else {
|
|
||||||
RelationType::HasMany
|
|
||||||
};
|
|
||||||
rel.rel_type = rel_type;
|
|
||||||
rel.ref_table = table_name.clone();
|
|
||||||
rel.columns = Vec::new();
|
|
||||||
rel.ref_columns = Vec::new();
|
|
||||||
if let Some(vec) = inverse_relations.get_mut(&ref_table) {
|
|
||||||
vec.push(rel);
|
|
||||||
} else {
|
|
||||||
inverse_relations.insert(ref_table, vec![rel]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (tbl_name, relations) in inverse_relations.iter() {
|
for (tbl_name, mut relations) in inverse_relations.into_iter() {
|
||||||
for ent in entities.iter_mut() {
|
if let Some(entity) = entities.get_mut(&tbl_name) {
|
||||||
if ent.table_name.eq(tbl_name) {
|
entity.relations.append(&mut relations);
|
||||||
ent.relations.append(relations.clone().as_mut());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{:#?}", entities);
|
for (tbl_name, mut conjunct_relations) in conjunct_relations.into_iter() {
|
||||||
Ok(EntityWriter { entities })
|
if let Some(entity) = entities.get_mut(&tbl_name) {
|
||||||
|
entity.conjunct_relations.append(&mut conjunct_relations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(EntityWriter {
|
||||||
|
entities: entities.into_iter().map(|(_, v)| v).collect(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ impl EntityWriter {
|
|||||||
Self::gen_impl_relation_trait(entity),
|
Self::gen_impl_relation_trait(entity),
|
||||||
];
|
];
|
||||||
code_blocks.extend(Self::gen_impl_related(entity));
|
code_blocks.extend(Self::gen_impl_related(entity));
|
||||||
|
code_blocks.extend(Self::gen_impl_conjunct_related(entity));
|
||||||
code_blocks.extend(vec![Self::gen_impl_active_model_behavior()]);
|
code_blocks.extend(vec![Self::gen_impl_active_model_behavior()]);
|
||||||
code_blocks
|
code_blocks
|
||||||
}
|
}
|
||||||
@ -239,7 +240,7 @@ impl EntityWriter {
|
|||||||
let camel = entity.get_relation_ref_tables_camel_case();
|
let camel = entity.get_relation_ref_tables_camel_case();
|
||||||
let snake = entity.get_relation_ref_tables_snake_case();
|
let snake = entity.get_relation_ref_tables_snake_case();
|
||||||
camel
|
camel
|
||||||
.iter()
|
.into_iter()
|
||||||
.zip(snake)
|
.zip(snake)
|
||||||
.map(|(c, s)| {
|
.map(|(c, s)| {
|
||||||
quote! {
|
quote! {
|
||||||
@ -253,6 +254,31 @@ impl EntityWriter {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gen_impl_conjunct_related(entity: &Entity) -> Vec<TokenStream> {
|
||||||
|
let table_name_camel_case = entity.get_table_name_camel_case_ident();
|
||||||
|
let via_snake_case = entity.get_conjunct_relations_via_snake_case();
|
||||||
|
let to_snake_case = entity.get_conjunct_relations_to_snake_case();
|
||||||
|
let to_camel_case = entity.get_conjunct_relations_to_camel_case();
|
||||||
|
via_snake_case
|
||||||
|
.into_iter()
|
||||||
|
.zip(to_snake_case)
|
||||||
|
.zip(to_camel_case)
|
||||||
|
.map(|((via_snake_case, to_snake_case), to_camel_case)| {
|
||||||
|
quote! {
|
||||||
|
impl Related<super::#to_snake_case::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::#via_snake_case::Relation::#to_camel_case.def()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::#via_snake_case::Relation::#table_name_camel_case.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn gen_impl_active_model_behavior() -> TokenStream {
|
pub fn gen_impl_active_model_behavior() -> TokenStream {
|
||||||
quote! {
|
quote! {
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
@ -277,7 +303,9 @@ impl EntityWriter {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{Column, Entity, EntityWriter, PrimaryKey, Relation, RelationType};
|
use crate::{
|
||||||
|
Column, ConjunctRelation, Entity, EntityWriter, PrimaryKey, Relation, RelationType,
|
||||||
|
};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use sea_query::ColumnType;
|
use sea_query::ColumnType;
|
||||||
use std::io::{self, BufRead, BufReader};
|
use std::io::{self, BufRead, BufReader};
|
||||||
@ -310,20 +338,16 @@ mod tests {
|
|||||||
unique: false,
|
unique: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
relations: vec![
|
relations: vec![Relation {
|
||||||
Relation {
|
ref_table: "fruit".to_owned(),
|
||||||
ref_table: "cake_filling".to_owned(),
|
columns: vec![],
|
||||||
columns: vec![],
|
ref_columns: vec![],
|
||||||
ref_columns: vec![],
|
rel_type: RelationType::HasMany,
|
||||||
rel_type: RelationType::HasMany,
|
}],
|
||||||
},
|
conjunct_relations: vec![ConjunctRelation {
|
||||||
Relation {
|
via: "cake_filling".to_owned(),
|
||||||
ref_table: "fruit".to_owned(),
|
to: "filling".to_owned(),
|
||||||
columns: vec![],
|
}],
|
||||||
ref_columns: vec![],
|
|
||||||
rel_type: RelationType::HasMany,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
name: "id".to_owned(),
|
name: "id".to_owned(),
|
||||||
}],
|
}],
|
||||||
@ -360,6 +384,7 @@ mod tests {
|
|||||||
rel_type: RelationType::BelongsTo,
|
rel_type: RelationType::BelongsTo,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
conjunct_relations: vec![],
|
||||||
primary_keys: vec![
|
primary_keys: vec![
|
||||||
PrimaryKey {
|
PrimaryKey {
|
||||||
name: "cake_id".to_owned(),
|
name: "cake_id".to_owned(),
|
||||||
@ -387,11 +412,10 @@ mod tests {
|
|||||||
unique: false,
|
unique: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
relations: vec![Relation {
|
relations: vec![],
|
||||||
ref_table: "cake_filling".to_owned(),
|
conjunct_relations: vec![ConjunctRelation {
|
||||||
columns: vec![],
|
via: "cake_filling".to_owned(),
|
||||||
ref_columns: vec![],
|
to: "cake".to_owned(),
|
||||||
rel_type: RelationType::HasMany,
|
|
||||||
}],
|
}],
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
name: "id".to_owned(),
|
name: "id".to_owned(),
|
||||||
@ -436,6 +460,7 @@ mod tests {
|
|||||||
rel_type: RelationType::HasMany,
|
rel_type: RelationType::HasMany,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
conjunct_relations: vec![],
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
name: "id".to_owned(),
|
name: "id".to_owned(),
|
||||||
}],
|
}],
|
||||||
@ -471,6 +496,7 @@ mod tests {
|
|||||||
ref_columns: vec!["id".to_owned()],
|
ref_columns: vec!["id".to_owned()],
|
||||||
rel_type: RelationType::BelongsTo,
|
rel_type: RelationType::BelongsTo,
|
||||||
}],
|
}],
|
||||||
|
conjunct_relations: vec![],
|
||||||
primary_keys: vec![PrimaryKey {
|
primary_keys: vec![PrimaryKey {
|
||||||
name: "id".to_owned(),
|
name: "id".to_owned(),
|
||||||
}],
|
}],
|
||||||
|
@ -36,7 +36,6 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
CakeFilling,
|
|
||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,22 +52,24 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
|
||||||
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::CakeFilling.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::fruit::Entity> for Entity {
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Fruit.def()
|
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 {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
@ -35,9 +35,7 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||||
pub enum Relation {
|
pub enum Relation {}
|
||||||
CakeFilling,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColumnTrait for Column {
|
impl ColumnTrait for Column {
|
||||||
type EntityName = Entity;
|
type EntityName = Entity;
|
||||||
@ -52,14 +50,17 @@ impl ColumnTrait for Column {
|
|||||||
impl RelationTrait for Relation {
|
impl RelationTrait for Relation {
|
||||||
fn def(&self) -> RelationDef {
|
fn def(&self) -> RelationDef {
|
||||||
match self {
|
match self {
|
||||||
Self::CakeFilling => Entity::has_many(super::cake_filling::Entity).into(),
|
_ => panic!("No RelationDef"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::cake_filling::Entity> for Entity {
|
impl Related<super::cake::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::CakeFilling.def()
|
super::cake_filling::Relation::Cake.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Filling.def().rev())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use crate::{
|
use crate::{error::*, ActiveModelTrait, DatabaseConnection, Insert, Statement};
|
||||||
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Insert, Iterable, Statement,
|
|
||||||
};
|
|
||||||
use sea_query::InsertStatement;
|
use sea_query::InsertStatement;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
@ -18,6 +16,7 @@ impl<A> Insert<A>
|
|||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
|
#[allow(unused_mut)]
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
self,
|
self,
|
||||||
db: &DatabaseConnection,
|
db: &DatabaseConnection,
|
||||||
@ -26,6 +25,7 @@ where
|
|||||||
let mut query = self.query;
|
let mut query = self.query;
|
||||||
#[cfg(feature = "sqlx-postgres")]
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
if let DatabaseConnection::SqlxPostgresPoolConnection(_) = db {
|
if let DatabaseConnection::SqlxPostgresPoolConnection(_) = db {
|
||||||
|
use crate::{EntityTrait, Iterable};
|
||||||
use sea_query::{Alias, Expr, Query};
|
use sea_query::{Alias, Expr, Query};
|
||||||
for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
|
for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
|
||||||
query.returning(
|
query.returning(
|
||||||
|
@ -134,6 +134,7 @@ macro_rules! try_getable_unsigned {
|
|||||||
row.try_get(column.as_str())
|
row.try_get(column.as_str())
|
||||||
.map_err(crate::sqlx_error_to_query_err)
|
.map_err(crate::sqlx_error_to_query_err)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
QueryResultRow::SqlxPostgres(_) => {
|
QueryResultRow::SqlxPostgres(_) => {
|
||||||
panic!("{} unsupported by sqlx-postgres", stringify!($type))
|
panic!("{} unsupported by sqlx-postgres", stringify!($type))
|
||||||
}
|
}
|
||||||
@ -161,6 +162,7 @@ macro_rules! try_getable_unsigned {
|
|||||||
Err(_) => Ok(None),
|
Err(_) => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
QueryResultRow::SqlxPostgres(_) => {
|
QueryResultRow::SqlxPostgres(_) => {
|
||||||
panic!("{} unsupported by sqlx-postgres", stringify!($type))
|
panic!("{} unsupported by sqlx-postgres", stringify!($type))
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ pub use common::{bakery_chain::*, setup::*, TestContext};
|
|||||||
|
|
||||||
mod crud;
|
mod crud;
|
||||||
|
|
||||||
#[async_std::test]
|
|
||||||
// cargo test --test bakery_chain_tests -- --nocapture
|
// cargo test --test bakery_chain_tests -- --nocapture
|
||||||
|
#[async_std::test]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let base_url = "mysql://root:@localhost";
|
let base_url = "mysql://root:@localhost";
|
||||||
let db_name = "bakery_chain_schema_crud_tests";
|
let db_name = "bakery_chain_schema_crud_tests";
|
||||||
|
@ -2,8 +2,11 @@ use sea_orm::{entity::*, error::*, sea_query, tests_cfg::*, DbBackend, DbConn, S
|
|||||||
|
|
||||||
mod setup;
|
mod setup;
|
||||||
|
|
||||||
#[async_std::test]
|
|
||||||
// cargo test --test basic -- --nocapture
|
// cargo test --test basic -- --nocapture
|
||||||
|
#[cfg_attr(feature = "runtime-async-std", async_std::main)]
|
||||||
|
#[cfg_attr(feature = "runtime-actix", actix_rt::main)]
|
||||||
|
#[cfg_attr(feature = "runtime-tokio", tokio::main)]
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let db: DbConn = setup::setup().await;
|
let db: DbConn = setup::setup().await;
|
||||||
|
|
||||||
|
@ -9,7 +9,10 @@ pub use common::bakery_chain::*;
|
|||||||
use sea_query::{ColumnDef, TableCreateStatement};
|
use sea_query::{ColumnDef, TableCreateStatement};
|
||||||
|
|
||||||
// cargo test --test pg_tests -- --nocapture
|
// cargo test --test pg_tests -- --nocapture
|
||||||
#[async_std::test]
|
#[cfg_attr(feature = "runtime-async-std", async_std::main)]
|
||||||
|
#[cfg_attr(feature = "runtime-actix", actix_rt::main)]
|
||||||
|
#[cfg_attr(feature = "runtime-tokio", tokio::main)]
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let base_url = "postgres://root:root@localhost";
|
let base_url = "postgres://root:root@localhost";
|
||||||
let db_name = "bakery_chain_schema_crud_tests";
|
let db_name = "bakery_chain_schema_crud_tests";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user