Skip to content

Commit

Permalink
Merge pull request #970 from ikrivosheev/feature/issues-969_sea-query…
Browse files Browse the repository at this point in the history
…-binder

issues-969 Replace sea-query-driver to sea-query-binder
  • Loading branch information
ikrivosheev authored Sep 9, 2022
2 parents af0bc7a + ab5b488 commit 52531db
Show file tree
Hide file tree
Showing 24 changed files with 227 additions and 146 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 19 additions & 6 deletions COMMUNITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)) ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service
- [Sensei](https://l2.technology/sensei) ([repository](https://github.com/L2-Technology/sensei)) ![GitHub stars](https://img.shields.io/github/stars/L2-Technology/sensei.svg?style=social) | A Bitcoin lightning node implementation
- [Spyglass](https://docs.spyglass.fyi/) ([repository](https://github.com/a5huynh/spyglass)) ![GitHub stars](https://img.shields.io/github/stars/a5huynh/spyglass.svg?style=social) | 🔭 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

Expand All @@ -31,15 +32,15 @@ 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) ![GitHub stars](https://img.shields.io/github/stars/aaronleopold/stump.svg?style=social) | 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
- [Oura Postgres Sink](https://github.com/dcSpark/oura-postgres-sink) | Sync a postgres database with the cardano blockchain using [Oura](https://github.com/txpipe/oura)
- [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) ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | 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
Expand All @@ -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) ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | 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 changes: 32 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ authors = ["Chris Tsang <[email protected]>"]
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"]
Expand All @@ -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 }
Expand All @@ -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" }
Expand All @@ -71,28 +74,45 @@ 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 = [
"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-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",
]
15 changes: 6 additions & 9 deletions examples/basic/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;

Expand Down
1 change: 1 addition & 0 deletions sea-orm-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ authors = [ "Billy Chan <[email protected]>" ]
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" ]
Expand Down
1 change: 1 addition & 0 deletions sea-orm-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ authors = ["Billy Chan <[email protected]>"]
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"]
Expand Down
1 change: 1 addition & 0 deletions sea-orm-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ authors = [ "Billy Chan <[email protected]>" ]
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" ]
Expand Down
1 change: 1 addition & 0 deletions sea-orm-migration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ authors = [ "Billy Chan <[email protected]>" ]
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" ]
Expand Down
5 changes: 5 additions & 0 deletions sea-orm-migration/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;
Expand Down
16 changes: 8 additions & 8 deletions src/driver/sqlx_mysql.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use sea_query::Values;
use std::{future::Future, pin::Pin, sync::Arc};

use sqlx::{
mysql::{MySqlArguments, MySqlConnectOptions, MySqlQueryResult, MySqlRow},
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::{
Expand Down Expand Up @@ -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))
}
18 changes: 9 additions & 9 deletions src/driver/sqlx_postgres.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down Expand Up @@ -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))
}
16 changes: 8 additions & 8 deletions src/driver/sqlx_sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use sea_query::Values;
use std::{future::Future, pin::Pin, sync::Arc};

use sqlx::{
sqlite::{SqliteArguments, SqliteConnectOptions, SqliteQueryResult, SqliteRow},
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::{
Expand Down Expand Up @@ -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))
}
17 changes: 8 additions & 9 deletions src/entity/column.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
}
};
Expand Down Expand Up @@ -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 {
Expand Down
22 changes: 7 additions & 15 deletions src/executor/insert.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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),
Expand Down
Loading

0 comments on commit 52531db

Please sign in to comment.