diff --git a/Cargo.toml b/Cargo.toml index 2d9493c37..725460b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,19 +25,19 @@ path = "src/lib.rs" async-stream = { version = "^0.3" } async-trait = { version = "^0.1" } chrono = { version = "^0", optional = true } -time = { version = "^0.2", optional = true } +time = { version = "^0.3", optional = true } futures = { version = "^0.3" } futures-util = { version = "^0.3" } log = { version = "^0" } tracing = { version = "0.1", features = ["log"] } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.8.0", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.24.5", features = ["thread-safe"] } +sea-query = { version = "^0.26", features = ["thread-safe"] } sea-strum = { version = "^0.23", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } -sqlx = { version = "^0.5", optional = true } -uuid = { version = "0.8", features = ["serde", "v4"], optional = true } +sqlx = { version = "^0.6", optional = true } +uuid = { version = "^1", features = ["serde", "v4"], optional = true } ouroboros = "0.15" url = "^2.2" once_cell = "1.8" @@ -53,6 +53,7 @@ rust_decimal_macros = { version = "^1" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } sea-orm = { path = ".", features = ["mock", "debug-print"] } pretty_assertions = { version = "^0.7" } +time = { version = "^0.3", features = ["macros"] } [features] debug-print = [] diff --git a/sea-orm-cli/Cargo.toml b/sea-orm-cli/Cargo.toml index c612fa843..0a609e7ee 100644 --- a/sea-orm-cli/Cargo.toml +++ b/sea-orm-cli/Cargo.toml @@ -33,8 +33,8 @@ clap = { version = "^3.2", features = ["env", "derive"] } dotenv = { version = "^0.15" } async-std = { version = "^1.9", features = [ "attributes", "tokio1" ] } sea-orm-codegen = { version = "^0.8.0", path = "../sea-orm-codegen", optional = true } -sea-schema = { version = "^0.8.1" } -sqlx = { version = "^0.5", default-features = false, features = [ "mysql", "postgres" ], optional = true } +sea-schema = { version = "^0.9.2" } +sqlx = { version = "^0.6", default-features = false, features = [ "mysql", "postgres" ], optional = true } tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing = { version = "0.1" } url = "^2.2" diff --git a/sea-orm-codegen/Cargo.toml b/sea-orm-codegen/Cargo.toml index a4db24507..8f9c4e570 100644 --- a/sea-orm-codegen/Cargo.toml +++ b/sea-orm-codegen/Cargo.toml @@ -15,7 +15,7 @@ name = "sea_orm_codegen" path = "src/lib.rs" [dependencies] -sea-query = { version = "^0.24.0" } +sea-query = { version = "^0.26.0" } syn = { version = "^1", default-features = false, features = [ "derive", "parsing", diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index 8f8c95534..89d998c5a 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -213,7 +213,7 @@ mod tests { use crate::Column; use proc_macro2::TokenStream; use quote::quote; - use sea_query::{Alias, ColumnDef, ColumnType, SeaRc}; + use sea_query::{Alias, BlobSize, ColumnDef, ColumnType, SeaRc}; fn setup() -> Vec { macro_rules! make_col { @@ -243,7 +243,7 @@ mod tests { make_col!("CakeFillingId", ColumnType::BigUnsigned(Some(12))), make_col!("cake-filling-id", ColumnType::Float(None)), make_col!("CAKE_FILLING_ID", ColumnType::Double(None)), - make_col!("CAKE-FILLING-ID", ColumnType::Binary(None)), + make_col!("CAKE-FILLING-ID", ColumnType::Binary(BlobSize::Blob(None))), make_col!("CAKE", ColumnType::Boolean), make_col!("date", ColumnType::Date), make_col!("time", ColumnType::Time(None)), diff --git a/sea-orm-macros/src/derives/try_getable_from_json.rs b/sea-orm-macros/src/derives/try_getable_from_json.rs index efcb76b55..957cee3dd 100644 --- a/sea-orm-macros/src/derives/try_getable_from_json.rs +++ b/sea-orm-macros/src/derives/try_getable_from_json.rs @@ -1,8 +1,7 @@ use proc_macro2::{Ident, TokenStream}; -use quote::{format_ident, quote, quote_spanned}; -use syn::{ext::IdentExt, Data, DataStruct, Field, Fields}; +use quote::quote; -pub fn expand_derive_from_json_query_result(ident: Ident, data: Data) -> syn::Result { +pub fn expand_derive_from_json_query_result(ident: Ident) -> syn::Result { Ok(quote!( #[automatically_derived] impl sea_orm::TryGetableFromJson for #ident {} diff --git a/sea-orm-macros/src/lib.rs b/sea-orm-macros/src/lib.rs index d9ea0d28b..d3026d235 100644 --- a/sea-orm-macros/src/lib.rs +++ b/sea-orm-macros/src/lib.rs @@ -611,9 +611,9 @@ pub fn derive_migration_name(input: TokenStream) -> TokenStream { #[proc_macro_derive(FromJsonQueryResult)] pub fn derive_from_json_query_result(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); + let DeriveInput { ident, .. } = parse_macro_input!(input); - match derives::expand_derive_from_json_query_result(ident, data) { + match derives::expand_derive_from_json_query_result(ident) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } diff --git a/sea-orm-migration/Cargo.toml b/sea-orm-migration/Cargo.toml index f834902c2..72207c21b 100644 --- a/sea-orm-migration/Cargo.toml +++ b/sea-orm-migration/Cargo.toml @@ -23,7 +23,7 @@ clap = { version = "^3.2", features = ["env", "derive"] } dotenv = { version = "^0.15" } sea-orm = { version = "^0.8.0", path = "../", default-features = false, features = ["macros"] } sea-orm-cli = { version = "^0.8.1", path = "../sea-orm-cli", default-features = false } -sea-schema = { version = "^0.8.1" } +sea-schema = { version = "^0.9.2" } tracing = { version = "0.1", features = ["log"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/src/database/mod.rs b/src/database/mod.rs index 7d9b7b357..4a24ec88d 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -132,7 +132,7 @@ impl ConnectOptions { opt = opt.min_connections(min_connections); } if let Some(connect_timeout) = self.connect_timeout { - opt = opt.connect_timeout(connect_timeout); + opt = opt.acquire_timeout(connect_timeout); } if let Some(idle_timeout) = self.idle_timeout { opt = opt.idle_timeout(Some(idle_timeout)); diff --git a/src/database/stream/metric.rs b/src/database/stream/metric.rs index c7b51174c..975ced9a1 100644 --- a/src/database/stream/metric.rs +++ b/src/database/stream/metric.rs @@ -54,7 +54,7 @@ impl<'a> Drop for MetricStream<'a> { fn drop(&mut self) { if let (Some(callback), Some(elapsed)) = (self.metric_callback.as_deref(), self.elapsed) { let info = crate::metric::Info { - elapsed: elapsed, + elapsed, statement: self.stmt, failed: false, }; diff --git a/src/entity/column.rs b/src/entity/column.rs index cbf514753..9ee437e81 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -244,7 +244,7 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { /// ``` fn starts_with(&self, s: &str) -> SimpleExpr { let pattern = format!("{}%", s); - Expr::tbl(self.entity_name(), *self).like(&pattern) + Expr::tbl(self.entity_name(), *self).like(pattern) } /// ``` @@ -260,7 +260,7 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { /// ``` fn ends_with(&self, s: &str) -> SimpleExpr { let pattern = format!("%{}", s); - Expr::tbl(self.entity_name(), *self).like(&pattern) + Expr::tbl(self.entity_name(), *self).like(pattern) } /// ``` @@ -276,7 +276,7 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { /// ``` fn contains(&self, s: &str) -> SimpleExpr { let pattern = format!("%{}%", s); - Expr::tbl(self.entity_name(), *self).like(&pattern) + Expr::tbl(self.entity_name(), *self).like(pattern) } bind_func_no_params!(max); @@ -382,7 +382,7 @@ impl From for sea_query::ColumnType { ColumnType::TimestampWithTimeZone => sea_query::ColumnType::TimestampWithTimeZone(None), ColumnType::Time => sea_query::ColumnType::Time(None), ColumnType::Date => sea_query::ColumnType::Date, - ColumnType::Binary => sea_query::ColumnType::Binary(None), + ColumnType::Binary => sea_query::ColumnType::Binary(sea_query::BlobSize::Blob(None)), ColumnType::Boolean => sea_query::ColumnType::Boolean, ColumnType::Money(s) => sea_query::ColumnType::Money(s), ColumnType::Json => sea_query::ColumnType::Json, diff --git a/src/executor/insert.rs b/src/executor/insert.rs index 61e7bfb6e..fca685936 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -42,8 +42,7 @@ where // so that self is dropped before entering await let mut query = self.query; if db.support_returning() && ::PrimaryKey::iter().count() > 0 { - let mut returning = Query::select(); - returning.columns( + let returning = Query::returning().columns( ::PrimaryKey::iter().map(|c| c.into_column_ref()), ); query.returning(returning); @@ -149,16 +148,16 @@ where let db_backend = db.get_database_backend(); let found = match db.support_returning() { true => { - let mut returning = Query::select(); - returning.exprs(::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(::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(), + } + })); insert_statement.returning(returning); SelectorRaw::::Model>>::from_statement( db_backend.build(&insert_statement), diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs index 520e7025e..a1a6f90da 100644 --- a/src/executor/paginator.rs +++ b/src/executor/paginator.rs @@ -98,7 +98,10 @@ where let number_of_items = self.num_items().await?; let number_of_pages = self.compute_pages_number(number_of_items); - Ok(ItemsAndPagesNumber { number_of_items, number_of_pages }) + Ok(ItemsAndPagesNumber { + number_of_items, + number_of_pages, + }) } /// Compute the number of pages for the current page diff --git a/src/executor/query.rs b/src/executor/query.rs index d7c2bb0d3..b1e0bac18 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -298,7 +298,6 @@ try_getable_all!(i32); try_getable_all!(i64); try_getable_unsigned!(u8); try_getable_unsigned!(u16); -try_getable_all!(u32); try_getable_mysql!(u64); try_getable_all!(f32); try_getable_all!(f64); @@ -391,6 +390,47 @@ impl TryGetable for Decimal { #[cfg(feature = "with-uuid")] try_getable_all!(uuid::Uuid); +impl TryGetable for u32 { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + let _column = format!("{}{}", pre, col); + match &res.row { + #[cfg(feature = "sqlx-mysql")] + QueryResultRow::SqlxMySql(row) => { + use sqlx::Row; + row.try_get::, _>(_column.as_str()) + .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) + .and_then(|opt| opt.ok_or(TryGetError::Null)) + } + #[cfg(feature = "sqlx-postgres")] + QueryResultRow::SqlxPostgres(row) => { + use sqlx::postgres::types::Oid; + // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`; + // Instead, `u32` was wrapped by a `sqlx::Oid`. + use sqlx::Row; + row.try_get::, _>(_column.as_str()) + .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) + .and_then(|opt| opt.ok_or(TryGetError::Null)) + .map(|oid| oid.0) + } + #[cfg(feature = "sqlx-sqlite")] + QueryResultRow::SqlxSqlite(row) => { + use sqlx::Row; + row.try_get::, _>(_column.as_str()) + .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) + .and_then(|opt| opt.ok_or(TryGetError::Null)) + } + #[cfg(feature = "mock")] + #[allow(unused_variables)] + QueryResultRow::Mock(row) => row.try_get(_column.as_str()).map_err(|e| { + debug_print!("{:#?}", e.to_string()); + TryGetError::Null + }), + #[allow(unreachable_patterns)] + _ => unreachable!(), + } + } +} + // TryGetableMany // /// Perform a query on multiple columns diff --git a/src/executor/update.rs b/src/executor/update.rs index ea3c223ac..38b7e29cb 100644 --- a/src/executor/update.rs +++ b/src/executor/update.rs @@ -91,16 +91,16 @@ where { match db.support_returning() { true => { - let mut returning = Query::select(); - returning.exprs(::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(::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(), + } + })); query.returning(returning); let db_backend = db.get_database_backend(); let found: Option<::Model> = diff --git a/src/query/helper.rs b/src/query/helper.rs index e239f926d..109912e5f 100644 --- a/src/query/helper.rs +++ b/src/query/helper.rs @@ -482,6 +482,7 @@ pub(crate) fn unpack_table_ref(table_ref: &TableRef) -> DynIden { | TableRef::TableAlias(tbl, _) | TableRef::SchemaTableAlias(_, tbl, _) | TableRef::DatabaseSchemaTableAlias(_, _, tbl, _) - | TableRef::SubQuery(_, tbl) => SeaRc::clone(tbl), + | TableRef::SubQuery(_, tbl) + | TableRef::ValuesList(_, tbl) => SeaRc::clone(tbl), } } diff --git a/src/query/json.rs b/src/query/json.rs index 63a214441..b821c0832 100644 --- a/src/query/json.rs +++ b/src/query/json.rs @@ -67,7 +67,7 @@ impl FromQueryResult for JsonValue { #[cfg(feature = "sqlx-postgres")] QueryResultRow::SqlxPostgres(row) => { use serde_json::json; - use sqlx::{Column, Postgres, Row, Type}; + use sqlx::{postgres::types::Oid, Column, Postgres, Row, Type}; for column in row.columns() { let col = if !column.name().starts_with(pre) { continue; @@ -89,7 +89,11 @@ impl FromQueryResult for JsonValue { match_postgres_type!(i64); // match_postgres_type!(u8); // unsupported by SQLx Postgres // match_postgres_type!(u16); // unsupported by SQLx Postgres - match_postgres_type!(u32); + // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`; + // Instead, `u32` was wrapped by a `sqlx::Oid`. + if >::type_info().eq(col_type) { + try_get_type!(u32, col) + } // match_postgres_type!(u64); // unsupported by SQLx Postgres match_postgres_type!(f32); match_postgres_type!(f64); diff --git a/tests/common/features/json_vec.rs b/tests/common/features/json_vec.rs index 7b347c7b3..506003cbc 100644 --- a/tests/common/features/json_vec.rs +++ b/tests/common/features/json_vec.rs @@ -20,7 +20,7 @@ pub struct StringVec(pub Vec); impl From for Value { fn from(source: StringVec) -> Self { - Value::String(serde_json::to_string(&source).ok().map(|s| Box::new(s))) + Value::String(serde_json::to_string(&source).ok().map(Box::new)) } } diff --git a/tests/json_struct_tests.rs b/tests/json_struct_tests.rs index 5c5876902..877806969 100644 --- a/tests/json_struct_tests.rs +++ b/tests/json_struct_tests.rs @@ -37,15 +37,13 @@ pub async fn insert_json_struct_1(db: &DatabaseConnection) -> Result<(), DbErr> name: "apple".into(), price: 12.01, notes: Some("hand picked, organic".into()), - } - .into(), + }, json_value_opt: Some(KeyValue { id: 1, name: "apple".into(), price: 12.01, notes: Some("hand picked, organic".into()), - }) - .into(), + }), }; let result = model.clone().into_active_model().insert(db).await?; @@ -79,9 +77,8 @@ pub async fn insert_json_struct_2(db: &DatabaseConnection) -> Result<(), DbErr> name: "orange".into(), price: 10.93, notes: None, - } - .into(), - json_value_opt: None.into(), + }, + json_value_opt: None, }; let result = model.clone().into_active_model().insert(db).await?; diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs index 7fa0447b4..425adf268 100644 --- a/tests/returning_tests.rs +++ b/tests/returning_tests.rs @@ -32,8 +32,8 @@ async fn main() -> Result<(), DbErr> { ]) .and_where(Column::Id.eq(1)); - let mut returning = Query::select(); - returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]); + let returning = + Query::returning().columns(vec![Column::Id, Column::Name, Column::ProfitMargin]); create_tables(db).await?; diff --git a/tests/time_crate_tests.rs b/tests/time_crate_tests.rs index 0fb4ba32a..f7a4cff05 100644 --- a/tests/time_crate_tests.rs +++ b/tests/time_crate_tests.rs @@ -1,7 +1,7 @@ pub mod common; pub use common::{features::*, setup::*, TestContext}; use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; -use time::{date, time}; +use time::macros::{date, time}; #[sea_orm_macros::test] #[cfg(any( diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs index 0350e8b16..c151ee331 100644 --- a/tests/timestamp_tests.rs +++ b/tests/timestamp_tests.rs @@ -2,7 +2,6 @@ pub mod common; pub use common::{features::*, setup::*, TestContext}; use pretty_assertions::assert_eq; use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; -use serde_json::json; #[sea_orm_macros::test] #[cfg(any( @@ -39,17 +38,17 @@ pub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> { #[cfg(feature = "sqlx-sqlite")] assert_eq!( Applog::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "action": "Testing", "json": r#""HI""#, - "created_at": "2021-09-17 09:50:20", + "created_at": "2021-09-17T17:50:20+08:00", })) ); #[cfg(feature = "sqlx-mysql")] assert_eq!( Applog::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "action": "Testing", "json": "HI", @@ -59,7 +58,7 @@ pub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> { #[cfg(feature = "sqlx-postgres")] assert_eq!( Applog::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "action": "Testing", "json": "HI", @@ -88,17 +87,17 @@ pub async fn create_satellites_log(db: &DatabaseConnection) -> Result<(), DbErr> #[cfg(feature = "sqlx-sqlite")] assert_eq!( Satellite::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "satellite_name": "Sea-00001-2022", - "launch_date": "2022-01-07 12:11:23", - "deployment_date": "2022-01-07 12:11:23", + "launch_date": "2022-01-07T12:11:23+00:00", + "deployment_date": "2022-01-07T12:11:23Z".parse::().unwrap(), })) ); #[cfg(feature = "sqlx-mysql")] assert_eq!( Satellite::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "satellite_name": "Sea-00001-2022", "launch_date": "2022-01-07T12:11:23Z", @@ -108,7 +107,7 @@ pub async fn create_satellites_log(db: &DatabaseConnection) -> Result<(), DbErr> #[cfg(feature = "sqlx-postgres")] assert_eq!( Satellite::find().into_json().one(db).await?, - Some(json!({ + Some(serde_json::json!({ "id": 1, "satellite_name": "Sea-00001-2022", "launch_date": "2022-01-07T12:11:23+00:00",