Merge pull request #970 from ikrivosheev/feature/issues-969_sea-query-binder
issues-969 Replace sea-query-driver to sea-query-binder
This commit is contained in:
commit
52531db70f
@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
* Replaced `usize` with `u64` in `PaginatorTrait` https://github.com/SeaQL/sea-orm/pull/789
|
||||
|
||||
### Enhancements
|
||||
|
||||
* `fn column()` also handle enum type https://github.com/SeaQL/sea-orm/pull/973
|
||||
|
||||
## 0.9.2 - 2022-08-20
|
||||
|
||||
### Enhancements
|
||||
|
25
COMMUNITY.md
25
COMMUNITY.md
@ -7,10 +7,11 @@ If you have built an app using SeaORM and want to showcase it, feel free to open
|
||||
### Startups
|
||||
|
||||
- [Caido](https://caido.io/) | A lightweight web security auditing toolkit
|
||||
- [Svix](https://www.svix.com/) ([repository](https://github.com/svix/svix-webhooks)) | The enterprise ready webhooks service
|
||||
- [Sensei](https://l2.technology/sensei) ([repository](https://github.com/L2-Technology/sensei)) | A Bitcoin lightning node implementation
|
||||
- [Spyglass](https://docs.spyglass.fyi/) ([repository](https://github.com/a5huynh/spyglass)) | 🔭 A personal search engine that indexes what you want w/ a simple set of rules.
|
||||
- [Svix](https://www.svix.com/) ([repository](https://github.com/svix/svix-webhooks))  | The enterprise ready webhooks service
|
||||
- [Sensei](https://l2.technology/sensei) ([repository](https://github.com/L2-Technology/sensei))  | A Bitcoin lightning node implementation
|
||||
- [Spyglass](https://docs.spyglass.fyi/) ([repository](https://github.com/a5huynh/spyglass))  | 🔭 A personal search engine that indexes what you want w/ a simple set of rules.
|
||||
- [My Data My Consent](https://mydatamyconsent.com/) | Online data sharing for people and businesses simplified
|
||||
- [CodeCTRL](https://codectrl.authentura.com) ([repository](https://github.com/Authentura/codectrl)) | A self-hostable code logging platform
|
||||
|
||||
### Frameworks
|
||||
|
||||
@ -31,7 +32,7 @@ If you have built an app using SeaORM and want to showcase it, feel free to open
|
||||
- [mediarepo](https://mediarepo.trivernis.dev) ([repository](https://github.com/Trivernis/mediarepo)) | A tag-based media management application
|
||||
- [THUBurrow](https://thuburrow.com) ([repository](https://github.com/BobAnkh/THUBurrow)) | A campus forum built by Next.js and Rocket
|
||||
- [Backpack](https://github.com/JSH32/Backpack) | Open source self hosted file sharing platform on crack
|
||||
- [Stump](https://github.com/aaronleopold/stump) | A free and open source comics server with OPDS support
|
||||
- [Stump](https://github.com/aaronleopold/stump)  | A free and open source comics server with OPDS support
|
||||
- [mugen](https://github.com/koopa1338/mugen-dms) | DMS written in 🦀
|
||||
- [JinShu](https://github.com/gengteng/jinshu) | A cross-platform **I**nstant **M**essaging system written in 🦀
|
||||
- [rust-juniper-playground](https://github.com/Yama-Tomo/rust-juniper-playground) | juniper with SeaORM example
|
||||
@ -39,7 +40,7 @@ If you have built an app using SeaORM and want to showcase it, feel free to open
|
||||
- [pansy](https://github.com/niuhuan/pansy) | An illustrations app using SeaORM, SQLite, flutter. runs on the desktop and mobile terminals
|
||||
- [Orca](https://github.com/workfoxes/orca) | An No-code Test Automation platfrom using actix, SeaORM, react. runs on the desktop and cloud
|
||||
- [symbols](https://github.com/nappa85/symbols) | A proc-macro utility to populates enum variants with primary keys values
|
||||
- [Warpgate](https://github.com/warp-tech/warpgate) | Smart SSH bastion that works with any SSH client
|
||||
- [Warpgate](https://github.com/warp-tech/warpgate)  | Smart SSH bastion that works with any SSH client
|
||||
- [suzuya](https://github.com/SH11235/suzuya) | A merchandise management application using SeaORM, Actix-Web, Tera
|
||||
- [snmp-sim-rust](https://github.com/sonalake/snmp-sim-rust) | SNMP Simulator
|
||||
- [template_flow](https://github.com/hilary888/template_flow) | An experiment exploring replacing placeholders in pre-prepared templates with their actual values
|
||||
@ -49,4 +50,16 @@ If you have built an app using SeaORM and want to showcase it, feel free to open
|
||||
- [KrakenPics](https://github.com/kraken-pics/backend) | A public file host written in rust using seaorm & actix_web
|
||||
- [service_auth](https://github.com/shorii/service_auth) | A simple JWT authentication web-application
|
||||
- [rj45less-server](https://github.com/pmnxis/rj45less-server) | A simple unique number allocator for custom router
|
||||
- [SophyCore](https://github.com/FarDragi/SophyCore) | Main system that centralizes all rules, to be used by both the discord bot and the future site
|
||||
- [SophyCore](https://github.com/FarDragi/SophyCore) | Main system that centralizes all rules, to be used by both the discord bot and the future site
|
||||
- [lldap](https://github.com/nitnelave/lldap)  | Light LDAP implementation for authentication
|
||||
- [nitro_repo](https://github.com/wyatt-herkamp/nitro_repo) | An OpenSource, lightweight, and fast artifact manager.
|
||||
- [MoonRamp](https://github.com/MoonRamp/MoonRamp) | A free and open source crypto payment gateway
|
||||
- [url_shortener](https://github.com/michidk/url_shortener) | A simple self-hosted URL shortener written in Rust
|
||||
|
||||
## Learning Resources
|
||||
|
||||
If you have article, tutorial, podcast or video reated to SeaORM and want to share it with the community, feel free to submit a PR and add it to the list below!
|
||||
|
||||
### Tutorials
|
||||
|
||||
- Async GraphQL with Rust: [Part 1](https://konkle.us/async-graphql-rust-1-introduction/), [Part 2](https://konkle.us/async-graphql-with-rust-part-two/), [Part 3](https://konkle.us/async-graphql-with-rust-part-three/) by [Brandon Konkle](https://github.com/bkonkle)
|
||||
|
44
Cargo.toml
44
Cargo.toml
@ -8,6 +8,7 @@ authors = ["Chris Tsang <tyt2y7@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "🐚 An async & dynamic ORM for Rust"
|
||||
license = "MIT OR Apache-2.0"
|
||||
homepage = "https://www.sea-ql.org/SeaORM"
|
||||
documentation = "https://docs.rs/sea-orm"
|
||||
repository = "https://github.com/SeaQL/sea-orm"
|
||||
categories = ["database"]
|
||||
@ -34,6 +35,7 @@ tracing = { version = "^0.1", features = ["log"] }
|
||||
rust_decimal = { version = "^1", optional = true }
|
||||
sea-orm-macros = { version = "^0.10.0", path = "sea-orm-macros", optional = true }
|
||||
sea-query = { version = "^0.27", features = ["thread-safe"] }
|
||||
sea-query-binder = { version = "^0.1", optional = true }
|
||||
sea-strum = { version = "^0.23", features = ["derive", "sea-orm"] }
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = { version = "^1.0", optional = true }
|
||||
@ -45,6 +47,7 @@ once_cell = "1.8"
|
||||
|
||||
[patch.crates-io]
|
||||
sea-query = { git = "https://github.com/SeaQL/sea-query" }
|
||||
sea-query-binder = { git = "https://github.com/SeaQL/sea-query" }
|
||||
|
||||
[dev-dependencies]
|
||||
smol = { version = "^1.2" }
|
||||
@ -71,19 +74,20 @@ default = [
|
||||
]
|
||||
macros = ["sea-orm-macros"]
|
||||
mock = []
|
||||
with-json = ["serde_json", "sea-query/with-json", "chrono/serde", "sqlx?/json"]
|
||||
with-chrono = ["chrono", "sea-query/with-chrono", "sqlx?/chrono"]
|
||||
with-rust_decimal = ["rust_decimal", "sea-query/with-rust_decimal", "sqlx?/decimal"]
|
||||
with-uuid = ["uuid", "sea-query/with-uuid", "sqlx?/uuid"]
|
||||
with-time = ["time", "sea-query/with-time", "sqlx?/time"]
|
||||
with-json = ["serde_json", "sea-query/with-json", "chrono/serde", "sea-query-binder?/with-json", "sqlx?/json"]
|
||||
with-chrono = ["chrono", "sea-query/with-chrono", "sea-query-binder?/with-chrono", "sqlx?/chrono"]
|
||||
with-rust_decimal = ["rust_decimal", "sea-query/with-rust_decimal", "sea-query-binder?/with-rust_decimal", "sqlx?/decimal"]
|
||||
with-uuid = ["uuid", "sea-query/with-uuid", "sea-query-binder?/with-uuid", "sqlx?/uuid"]
|
||||
with-time = ["time", "sea-query/with-time", "sea-query-binder?/with-time", "sqlx?/time"]
|
||||
sqlx-dep = []
|
||||
sqlx-all = ["sqlx-mysql", "sqlx-postgres", "sqlx-sqlite"]
|
||||
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
|
||||
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
|
||||
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
|
||||
sqlx-mysql = ["sqlx-dep", "sea-query-binder/sqlx-mysql", "sqlx/mysql"]
|
||||
sqlx-postgres = ["sqlx-dep", "sea-query-binder/sqlx-postgres", "sqlx/postgres"]
|
||||
sqlx-sqlite = ["sqlx-dep", "sea-query-binder/sqlx-sqlite", "sqlx/sqlite"]
|
||||
runtime-async-std = []
|
||||
runtime-async-std-native-tls = [
|
||||
"sqlx/runtime-async-std-native-tls",
|
||||
"sea-query-binder/runtime-async-std-native-tls",
|
||||
"runtime-async-std",
|
||||
]
|
||||
runtime-async-std-rustls = [
|
||||
@ -91,8 +95,24 @@ 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-actix-native-tls = [
|
||||
"sqlx/runtime-actix-native-tls",
|
||||
"sea-query-binder/runtime-actix-native-tls",
|
||||
"runtime-actix",
|
||||
]
|
||||
runtime-actix-rustls = [
|
||||
"sqlx/runtime-actix-rustls",
|
||||
"sea-query-binder/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"]
|
||||
runtime-tokio-native-tls = [
|
||||
"sqlx/runtime-tokio-native-tls",
|
||||
"sea-query-binder/runtime-tokio-native-tls",
|
||||
"runtime-tokio",
|
||||
]
|
||||
runtime-tokio-rustls = [
|
||||
"sqlx/runtime-tokio-rustls",
|
||||
"sea-query-binder/runtime-tokio-rustls",
|
||||
"runtime-tokio",
|
||||
]
|
||||
|
@ -70,20 +70,17 @@ mod form {
|
||||
use super::fruit::*;
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel, DeriveActiveModelBehavior,
|
||||
)]
|
||||
pub struct Model {
|
||||
pub id: i32,
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveIntoActiveModel)]
|
||||
pub struct InputModel {
|
||||
pub name: String,
|
||||
}
|
||||
}
|
||||
|
||||
async fn save_custom_active_model(db: &DbConn) -> Result<(), DbErr> {
|
||||
let pineapple = form::ActiveModel {
|
||||
id: NotSet,
|
||||
name: Set("Pineapple".to_owned()),
|
||||
};
|
||||
let pineapple = form::InputModel {
|
||||
name: "Pineapple".to_owned(),
|
||||
}
|
||||
.into_active_model();
|
||||
|
||||
let pineapple = pineapple.save(db).await?;
|
||||
|
||||
|
@ -8,6 +8,7 @@ authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ]
|
||||
edition = "2021"
|
||||
description = "Command line utility for SeaORM"
|
||||
license = "MIT OR Apache-2.0"
|
||||
homepage = "https://www.sea-ql.org/SeaORM"
|
||||
documentation = "https://docs.rs/sea-orm"
|
||||
repository = "https://github.com/SeaQL/sea-orm"
|
||||
categories = [ "database" ]
|
||||
|
@ -5,6 +5,7 @@ authors = ["Billy Chan <ccw.billy.123@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "Code Generator for SeaORM"
|
||||
license = "MIT OR Apache-2.0"
|
||||
homepage = "https://www.sea-ql.org/SeaORM"
|
||||
documentation = "https://docs.rs/sea-orm"
|
||||
repository = "https://github.com/SeaQL/sea-orm"
|
||||
categories = ["database"]
|
||||
|
@ -5,6 +5,7 @@ authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ]
|
||||
edition = "2021"
|
||||
description = "Derive macros for SeaORM"
|
||||
license = "MIT OR Apache-2.0"
|
||||
homepage = "https://www.sea-ql.org/SeaORM"
|
||||
documentation = "https://docs.rs/sea-orm"
|
||||
repository = "https://github.com/SeaQL/sea-orm"
|
||||
categories = [ "database" ]
|
||||
|
@ -8,6 +8,7 @@ authors = [ "Billy Chan <ccw.billy.123@gmail.com>" ]
|
||||
edition = "2021"
|
||||
description = "Migration utility for SeaORM"
|
||||
license = "MIT OR Apache-2.0"
|
||||
homepage = "https://www.sea-ql.org/SeaORM"
|
||||
documentation = "https://docs.rs/sea-orm"
|
||||
repository = "https://github.com/SeaQL/sea-orm"
|
||||
categories = [ "database" ]
|
||||
|
@ -6,6 +6,11 @@ use sea_orm_migration::prelude::*;
|
||||
|
||||
#[async_std::test]
|
||||
async fn main() -> Result<(), DbErr> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.with_test_writer()
|
||||
.init();
|
||||
|
||||
let url = std::env::var("DATABASE_URL").expect("Environment variable 'DATABASE_URL' not set");
|
||||
let db_name = "sea_orm_migration";
|
||||
let db = Database::connect(&url).await?;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use sea_query::Values;
|
||||
use std::{future::Future, pin::Pin, sync::Arc};
|
||||
|
||||
use sqlx::{
|
||||
@ -5,8 +6,7 @@ use sqlx::{
|
||||
MySql, MySqlPool,
|
||||
};
|
||||
|
||||
sea_query::sea_query_driver_mysql!();
|
||||
use sea_query_driver_mysql::bind_query;
|
||||
use sea_query_binder::{SqlxBinder, SqlxValues};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
@ -215,10 +215,10 @@ impl From<MySqlQueryResult> for ExecResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySqlArguments> {
|
||||
let mut query = sqlx::query(&stmt.sql);
|
||||
if let Some(values) = &stmt.values {
|
||||
query = bind_query(query, values);
|
||||
}
|
||||
query
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, SqlxValues> {
|
||||
let values = stmt
|
||||
.values
|
||||
.as_ref()
|
||||
.map_or(Values(Vec::new()), |values| values.clone());
|
||||
sqlx::query_with(&stmt.sql, SqlxValues(values))
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
use sea_query::Values;
|
||||
use sea_query_binder::SqlxValues;
|
||||
use std::{future::Future, pin::Pin, sync::Arc};
|
||||
|
||||
use sqlx::{
|
||||
postgres::{PgArguments, PgConnectOptions, PgQueryResult, PgRow},
|
||||
postgres::{PgConnectOptions, PgQueryResult, PgRow},
|
||||
PgPool, Postgres,
|
||||
};
|
||||
|
||||
sea_query::sea_query_driver_postgres!();
|
||||
use sea_query_driver_postgres::bind_query;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
@ -215,10 +215,10 @@ impl From<PgQueryResult> for ExecResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, PgArguments> {
|
||||
let mut query = sqlx::query(&stmt.sql);
|
||||
if let Some(values) = &stmt.values {
|
||||
query = bind_query(query, values);
|
||||
}
|
||||
query
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, SqlxValues> {
|
||||
let values = stmt
|
||||
.values
|
||||
.as_ref()
|
||||
.map_or(Values(Vec::new()), |values| values.clone());
|
||||
sqlx::query_with(&stmt.sql, SqlxValues(values))
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use sea_query::Values;
|
||||
use std::{future::Future, pin::Pin, sync::Arc};
|
||||
|
||||
use sqlx::{
|
||||
@ -5,8 +6,7 @@ use sqlx::{
|
||||
Sqlite, SqlitePool,
|
||||
};
|
||||
|
||||
sea_query::sea_query_driver_sqlite!();
|
||||
use sea_query_driver_sqlite::bind_query;
|
||||
use sea_query_binder::SqlxValues;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
@ -222,10 +222,10 @@ impl From<SqliteQueryResult> for ExecResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, SqliteArguments> {
|
||||
let mut query = sqlx::query(&stmt.sql);
|
||||
if let Some(values) = &stmt.values {
|
||||
query = bind_query(query, values);
|
||||
}
|
||||
query
|
||||
pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, SqlxValues> {
|
||||
let values = stmt
|
||||
.values
|
||||
.as_ref()
|
||||
.map_or(Values(Vec::new()), |values| values.clone());
|
||||
sqlx::query_with(&stmt.sql, SqlxValues(values))
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{EntityName, IdenStatic, Iterable};
|
||||
use sea_query::{Alias, BinOper, DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
||||
use crate::{cast_text_as_enum, EntityName, IdenStatic, IntoSimpleExpr, Iterable};
|
||||
use sea_query::{BinOper, DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// Defines a Column for an Entity
|
||||
@ -100,13 +100,7 @@ macro_rules! bind_oper_with_enum_casting {
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
let val = Expr::val(v);
|
||||
let col_def = self.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
let expr = match col_type.get_enum_name() {
|
||||
Some(enum_name) => val.as_enum(Alias::new(enum_name)),
|
||||
None => val.into(),
|
||||
};
|
||||
let expr = cast_text_as_enum(Expr::val(v), self);
|
||||
Expr::tbl(self.entity_name(), *self).binary(BinOper::$bin_op, expr)
|
||||
}
|
||||
};
|
||||
@ -305,6 +299,11 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr {
|
||||
|
||||
bind_subquery_func!(in_subquery);
|
||||
bind_subquery_func!(not_in_subquery);
|
||||
|
||||
/// Construct a [`SimpleExpr::Column`] wrapped in [`Expr`].
|
||||
fn into_expr(self) -> Expr {
|
||||
Expr::expr(self.into_simple_expr())
|
||||
}
|
||||
}
|
||||
|
||||
impl ColumnType {
|
||||
|
@ -1,10 +1,8 @@
|
||||
use crate::{
|
||||
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel,
|
||||
Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
||||
};
|
||||
use sea_query::{
|
||||
Alias, Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple,
|
||||
cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Insert,
|
||||
IntoActiveModel, Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
||||
};
|
||||
use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple};
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
/// Defines a structure to perform INSERT operations in an ActiveModel
|
||||
@ -149,16 +147,10 @@ where
|
||||
let db_backend = db.get_database_backend();
|
||||
let found = match db.support_returning() {
|
||||
true => {
|
||||
let returning =
|
||||
Query::returning().exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
|
||||
let col = Expr::col(c);
|
||||
let col_def = ColumnTrait::def(&c);
|
||||
let col_type = col_def.get_column_type();
|
||||
match col_type.get_enum_name() {
|
||||
Some(_) => col.as_enum(Alias::new("text")),
|
||||
None => col.into(),
|
||||
}
|
||||
}));
|
||||
let returning = Query::returning().exprs(
|
||||
<A::Entity as EntityTrait>::Column::iter()
|
||||
.map(|c| cast_enum_as_text(Expr::col(c), &c)),
|
||||
);
|
||||
insert_statement.returning(returning);
|
||||
SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
|
||||
db_backend.build(&insert_statement),
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel,
|
||||
cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel,
|
||||
Iterable, SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
|
||||
};
|
||||
use sea_query::{Alias, Expr, FromValueTuple, Query, UpdateStatement};
|
||||
use sea_query::{Expr, FromValueTuple, Query, UpdateStatement};
|
||||
use std::future::Future;
|
||||
|
||||
/// Defines an update operation
|
||||
@ -91,16 +91,10 @@ where
|
||||
{
|
||||
match db.support_returning() {
|
||||
true => {
|
||||
let returning =
|
||||
Query::returning().exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
|
||||
let col = Expr::col(c);
|
||||
let col_def = c.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
match col_type.get_enum_name() {
|
||||
Some(_) => col.as_enum(Alias::new("text")),
|
||||
None => col.into(),
|
||||
}
|
||||
}));
|
||||
let returning = Query::returning().exprs(
|
||||
<A::Entity as EntityTrait>::Column::iter()
|
||||
.map(|c| cast_enum_as_text(Expr::col(c), &c)),
|
||||
);
|
||||
query.returning(returning);
|
||||
let db_backend = db.get_database_backend();
|
||||
let found: Option<<A::Entity as EntityTrait>::Model> =
|
||||
|
@ -1,12 +1,10 @@
|
||||
use crate::{
|
||||
ColumnTrait, EntityTrait, IdenStatic, IntoSimpleExpr, Iterable, QueryTrait, Select, SelectTwo,
|
||||
SelectTwoMany,
|
||||
cast_enum_as_text, ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select,
|
||||
SelectTwo, SelectTwoMany,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
pub use sea_query::JoinType;
|
||||
use sea_query::{
|
||||
Alias, ColumnRef, DynIden, Expr, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr,
|
||||
};
|
||||
use sea_query::{Alias, ColumnRef, Iden, Order, SeaRc, SelectExpr, SelectStatement, SimpleExpr};
|
||||
|
||||
macro_rules! select_def {
|
||||
( $ident: ident, $str: expr ) => {
|
||||
@ -148,18 +146,10 @@ where
|
||||
F: EntityTrait,
|
||||
S: QueryTrait<QueryStatement = SelectStatement>,
|
||||
{
|
||||
let text_type = SeaRc::new(Alias::new("text")) as DynIden;
|
||||
for col in <F::Column as Iterable>::iter() {
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
let alias = format!("{}{}", SelectB.as_str(), col.as_str());
|
||||
let expr = Expr::expr(col.into_simple_expr());
|
||||
let expr = match col_type.get_enum_name() {
|
||||
Some(_) => expr.as_enum(text_type.clone()),
|
||||
None => expr.into(),
|
||||
};
|
||||
selector.query().expr(SelectExpr {
|
||||
expr,
|
||||
expr: cast_enum_as_text(col.into_expr(), &col),
|
||||
alias: Some(SeaRc::new(Alias::new(&alias))),
|
||||
window: None,
|
||||
});
|
||||
|
@ -38,11 +38,34 @@ pub trait QuerySelect: Sized {
|
||||
/// r#"SELECT "cake"."name" FROM "cake""#
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// Enum column will be casted into text (PostgreSQL only)
|
||||
///
|
||||
/// ```
|
||||
/// use sea_orm::{entity::*, query::*, tests_cfg::lunch_set, DbBackend};
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// lunch_set::Entity::find()
|
||||
/// .select_only()
|
||||
/// .column(lunch_set::Column::Tea)
|
||||
/// .build(DbBackend::Postgres)
|
||||
/// .to_string(),
|
||||
/// r#"SELECT CAST("lunch_set"."tea" AS text) FROM "lunch_set""#
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// lunch_set::Entity::find()
|
||||
/// .select_only()
|
||||
/// .column(lunch_set::Column::Tea)
|
||||
/// .build(DbBackend::MySql)
|
||||
/// .to_string(),
|
||||
/// r#"SELECT `lunch_set`.`tea` FROM `lunch_set`"#
|
||||
/// );
|
||||
/// ```
|
||||
fn column<C>(mut self, col: C) -> Self
|
||||
where
|
||||
C: ColumnTrait,
|
||||
{
|
||||
self.query().expr(col.into_simple_expr());
|
||||
self.query().expr(cast_enum_as_text(col.into_expr(), &col));
|
||||
self
|
||||
}
|
||||
|
||||
@ -532,3 +555,33 @@ pub(crate) fn unpack_table_alias(table_ref: &TableRef) -> Option<DynIden> {
|
||||
| TableRef::DatabaseSchemaTableAlias(_, _, _, alias) => Some(SeaRc::clone(alias)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
struct Text;
|
||||
|
||||
pub(crate) fn cast_enum_as_text<C>(expr: Expr, col: &C) -> SimpleExpr
|
||||
where
|
||||
C: ColumnTrait,
|
||||
{
|
||||
cast_enum_text_inner(expr, col, |col, _| col.as_enum(Text))
|
||||
}
|
||||
|
||||
pub(crate) fn cast_text_as_enum<C>(expr: Expr, col: &C) -> SimpleExpr
|
||||
where
|
||||
C: ColumnTrait,
|
||||
{
|
||||
cast_enum_text_inner(expr, col, |col, enum_name| col.as_enum(enum_name))
|
||||
}
|
||||
|
||||
fn cast_enum_text_inner<C, F>(expr: Expr, col: &C, f: F) -> SimpleExpr
|
||||
where
|
||||
C: ColumnTrait,
|
||||
F: Fn(Expr, DynIden) -> SimpleExpr,
|
||||
{
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
match col_type.get_enum_name() {
|
||||
Some(enum_name) => f(expr, SeaRc::new(Alias::new(enum_name))),
|
||||
None => expr.into(),
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,
|
||||
cast_text_as_enum, ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,
|
||||
PrimaryKeyTrait, QueryTrait,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use sea_query::{Alias, Expr, InsertStatement, OnConflict, ValueTuple};
|
||||
use sea_query::{Expr, InsertStatement, OnConflict, ValueTuple};
|
||||
|
||||
/// Performs INSERT operations on a ActiveModel
|
||||
#[derive(Debug)]
|
||||
@ -134,14 +134,7 @@ where
|
||||
}
|
||||
if av_has_val {
|
||||
columns.push(col);
|
||||
let val = Expr::val(av.into_value().unwrap());
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
let expr = match col_type.get_enum_name() {
|
||||
Some(enum_name) => val.as_enum(Alias::new(enum_name)),
|
||||
None => val.into(),
|
||||
};
|
||||
values.push(expr);
|
||||
values.push(cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col));
|
||||
}
|
||||
}
|
||||
self.query.columns(columns);
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
join_tbl_on_condition, unpack_table_ref, ColumnTrait, EntityTrait, IdenStatic, Iterable,
|
||||
cast_enum_as_text, join_tbl_on_condition, unpack_table_ref, EntityTrait, IdenStatic, Iterable,
|
||||
Linked, QuerySelect, Related, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
|
||||
};
|
||||
pub use sea_query::JoinType;
|
||||
use sea_query::{Alias, Condition, DynIden, Expr, IntoIden, SeaRc, SelectExpr};
|
||||
use sea_query::{Alias, Condition, Expr, IntoIden, SeaRc, SelectExpr};
|
||||
|
||||
impl<E> Select<E>
|
||||
where
|
||||
@ -92,22 +92,15 @@ where
|
||||
.join_as(JoinType::LeftJoin, table_ref, to_tbl, condition);
|
||||
}
|
||||
slf = slf.apply_alias(SelectA.as_str());
|
||||
let text_type = SeaRc::new(Alias::new("text")) as DynIden;
|
||||
let mut select_two = SelectTwo::new_without_prepare(slf.query);
|
||||
for col in <T::Column as Iterable>::iter() {
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
let alias = format!("{}{}", SelectB.as_str(), col.as_str());
|
||||
let expr = Expr::tbl(
|
||||
Alias::new(&format!("r{}", l.link().len() - 1)).into_iden(),
|
||||
col.into_iden(),
|
||||
);
|
||||
let expr = match col_type.get_enum_name() {
|
||||
Some(_) => expr.as_enum(text_type.clone()),
|
||||
None => expr.into(),
|
||||
};
|
||||
select_two.query().expr(SelectExpr {
|
||||
expr,
|
||||
expr: cast_enum_as_text(expr, &col),
|
||||
alias: Some(SeaRc::new(Alias::new(&alias))),
|
||||
window: None,
|
||||
});
|
||||
|
@ -1,8 +1,11 @@
|
||||
use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait};
|
||||
use crate::{
|
||||
cast_enum_as_text, ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect,
|
||||
QueryTrait,
|
||||
};
|
||||
use core::fmt::Debug;
|
||||
use core::marker::PhantomData;
|
||||
pub use sea_query::JoinType;
|
||||
use sea_query::{Alias, DynIden, Expr, IntoColumnRef, SeaRc, SelectStatement, SimpleExpr};
|
||||
use sea_query::{IntoColumnRef, SelectStatement, SimpleExpr};
|
||||
|
||||
/// Defines a structure to perform select operations
|
||||
#[derive(Clone, Debug)]
|
||||
@ -119,18 +122,8 @@ where
|
||||
}
|
||||
|
||||
fn column_list(&self) -> Vec<SimpleExpr> {
|
||||
let table = SeaRc::new(E::default()) as DynIden;
|
||||
let text_type = SeaRc::new(Alias::new("text")) as DynIden;
|
||||
E::Column::iter()
|
||||
.map(|col| {
|
||||
let expr = Expr::tbl(table.clone(), col);
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
match col_type.get_enum_name() {
|
||||
Some(_) => expr.as_enum(text_type.clone()),
|
||||
None => expr.into(),
|
||||
}
|
||||
})
|
||||
.map(|col| cast_enum_as_text(col.into_expr(), &col))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter,
|
||||
QueryTrait,
|
||||
cast_text_as_enum, ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn,
|
||||
QueryFilter, QueryTrait,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use sea_query::{Alias, Expr, IntoIden, SimpleExpr, UpdateStatement};
|
||||
use sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement};
|
||||
|
||||
/// Defines a structure to perform UPDATE query operations on a ActiveModel
|
||||
#[derive(Clone, Debug)]
|
||||
@ -109,13 +109,7 @@ where
|
||||
}
|
||||
let av = self.model.get(col);
|
||||
if av.is_set() {
|
||||
let val = Expr::val(av.into_value().unwrap());
|
||||
let col_def = col.def();
|
||||
let col_type = col_def.get_column_type();
|
||||
let expr = match col_type.get_enum_name() {
|
||||
Some(enum_name) => val.as_enum(Alias::new(enum_name)),
|
||||
None => val.into(),
|
||||
};
|
||||
let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col);
|
||||
self.query.value_expr(col, expr);
|
||||
}
|
||||
}
|
||||
|
23
src/tests_cfg/lunch_set.rs
Normal file
23
src/tests_cfg/lunch_set.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use super::sea_orm_active_enums::*;
|
||||
use crate as sea_orm;
|
||||
use crate::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "lunch_set")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub tea: Tea,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -8,7 +8,9 @@ pub mod entity_linked;
|
||||
pub mod filling;
|
||||
pub mod fruit;
|
||||
pub mod indexes;
|
||||
pub mod lunch_set;
|
||||
pub mod rust_keyword;
|
||||
pub mod sea_orm_active_enums;
|
||||
pub mod vendor;
|
||||
|
||||
pub use cake::Entity as Cake;
|
||||
@ -17,5 +19,6 @@ pub use cake_filling::Entity as CakeFilling;
|
||||
pub use cake_filling_price::Entity as CakeFillingPrice;
|
||||
pub use filling::Entity as Filling;
|
||||
pub use fruit::Entity as Fruit;
|
||||
pub use lunch_set::Entity as LunchSet;
|
||||
pub use rust_keyword::Entity as RustKeyword;
|
||||
pub use vendor::Entity as Vendor;
|
||||
|
11
src/tests_cfg/sea_orm_active_enums.rs
Normal file
11
src/tests_cfg/sea_orm_active_enums.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate as sea_orm;
|
||||
use crate::entity::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
|
||||
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "tea")]
|
||||
pub enum Tea {
|
||||
#[sea_orm(string_value = "EverydayTea")]
|
||||
EverydayTea,
|
||||
#[sea_orm(string_value = "BreakfastTea")]
|
||||
BreakfastTea,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user