diff --git a/Cargo.toml b/Cargo.toml index 0665ae23..4e1b7e6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } tracing = { version = "0.1", features = ["log"] } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.5.0", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.20.0", features = ["thread-safe"] } +sea-query = { git = "https://github.com/charleschege/sea-query.git", features = ["thread-safe"] } sea-strum = { version = "^0.23", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index 18dca696..78e7f33e 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -608,6 +608,11 @@ impl_into_active_value!(crate::prelude::DateTime, Set); #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] impl_into_active_value!(crate::prelude::DateTimeWithTimeZone, Set); +#[cfg(feature = "with-chrono")] +#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))] +impl_into_active_value!(crate::prelude::DateTimeUtc, Set); + + #[cfg(feature = "with-rust_decimal")] #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))] impl_into_active_value!(crate::prelude::Decimal, Set); diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index 28f5fe70..109b2b4e 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -28,6 +28,50 @@ pub use chrono::NaiveDateTime as DateTime; #[cfg(feature = "with-chrono")] pub type DateTimeWithTimeZone = chrono::DateTime; +/// Handles the time and dates in UTC +/// +/// ### Example Usage +/// ```ignore +/// use chrono::{DateTime, NaiveDateTime, Utc}; +/// use sea_orm::prelude::*; +/// +/// let my_model = fruit::Model { +/// id: 3_i32, +/// name: "Fruit".to_owned(), +/// cake_id: Some(4), +/// timer: DateTime::::from_utc(NaiveDateTime::from_timestamp(61, 0), Utc), +/// }; +/// +/// assert_eq!( +/// fruit::Model { +/// id: 3, +/// name: "Fruit".to_owned(), +/// cake_id: Some(4,), +/// timer: DateTime::::from_utc(NaiveDateTime::from_timestamp(61, 0), Utc), +/// }, +/// my_model +/// ); +/// +/// // Define a `Model` containing a type of `DateTimeUtc` field +/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)] +/// pub struct Model { +/// pub id: i32, +/// pub name: String, +/// pub cake_id: Option, +/// pub timer: DateTimeUtc, +/// } +/// +/// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +/// pub enum Column { +/// Id, +/// Name, +/// CakeId, +/// Timer, +/// } +/// ``` +#[cfg(feature = "with-chrono")] +pub type DateTimeUtc = chrono::DateTime; + #[cfg(feature = "with-rust_decimal")] pub use rust_decimal::Decimal; diff --git a/src/executor/query.rs b/src/executor/query.rs index 3a842fc0..3091e507 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -271,6 +271,10 @@ try_getable_all!(chrono::NaiveDateTime); #[cfg(feature = "with-chrono")] try_getable_date_time!(chrono::DateTime); +#[cfg(feature = "with-chrono")] +try_getable_date_time!(chrono::DateTime); + + #[cfg(feature = "with-rust_decimal")] use rust_decimal::Decimal; @@ -614,6 +618,9 @@ try_from_u64_err!(chrono::NaiveDateTime); #[cfg(feature = "with-chrono")] try_from_u64_err!(chrono::DateTime); +#[cfg(feature = "with-chrono")] +try_from_u64_err!(chrono::DateTime); + #[cfg(feature = "with-rust_decimal")] try_from_u64_err!(rust_decimal::Decimal); diff --git a/src/query/combine.rs b/src/query/combine.rs index 2baf3fa2..2e1b19c8 100644 --- a/src/query/combine.rs +++ b/src/query/combine.rs @@ -46,10 +46,14 @@ where let col = match &sel.expr { SimpleExpr::Column(col_ref) => match &col_ref { ColumnRef::Column(col) | ColumnRef::TableColumn(_, col) => col, + _ => panic!("Unimplemented"), }, SimpleExpr::AsEnum(_, simple_expr) => match simple_expr.as_ref() { SimpleExpr::Column(col_ref) => match &col_ref { ColumnRef::Column(col) | ColumnRef::TableColumn(_, col) => col, + _ => panic!( + "cannot apply alias for AsEnum with expr other than Column" + ), }, _ => { panic!("cannot apply alias for AsEnum with expr other than Column") diff --git a/tests/common/features/datetimeutc.rs b/tests/common/features/datetimeutc.rs new file mode 100644 index 00000000..ec3f24f9 --- /dev/null +++ b/tests/common/features/datetimeutc.rs @@ -0,0 +1,16 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "satellites")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub satellite_name: String, + pub launch_date: DateTimeUtc, + pub deployment_date: DateTimeUtc, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/features/mod.rs b/tests/common/features/mod.rs index ea880fd2..8416aa64 100644 --- a/tests/common/features/mod.rs +++ b/tests/common/features/mod.rs @@ -2,6 +2,7 @@ pub mod active_enum; pub mod active_enum_child; pub mod applog; pub mod byte_primary_key; +pub mod datetimeutc; pub mod metadata; pub mod repository; pub mod schema; @@ -12,6 +13,7 @@ pub use active_enum::Entity as ActiveEnum; pub use active_enum_child::Entity as ActiveEnumChild; pub use applog::Entity as Applog; pub use byte_primary_key::Entity as BytePrimaryKey; +pub use datetimeutc::Entity as DateTimeUtcTest; pub use metadata::Entity as Metadata; pub use repository::Entity as Repository; pub use schema::*; diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index c38feb04..25eada19 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -16,6 +16,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { create_repository_table(db).await?; create_self_join_table(db).await?; create_byte_primary_key_table(db).await?; + create_satellites_table(db).await?; let create_enum_stmts = match db_backend { DbBackend::MySql | DbBackend::Sqlite => Vec::new(), @@ -201,3 +202,33 @@ pub async fn create_active_enum_child_table(db: &DbConn) -> Result Result { + let stmt = sea_query::Table::create() + .table(datetimeutc::Entity) + .col( + ColumnDef::new(datetimeutc::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(datetimeutc::Column::SatelliteName) + .string() + .not_null(), + ) + .col( + ColumnDef::new(datetimeutc::Column::LaunchDate) + .timestamp_with_time_zone() + .not_null(), + ) + .col( + ColumnDef::new(datetimeutc::Column::DeploymentDate) + .timestamp_with_time_zone() + .not_null(), + ) + .to_owned(); + + create_table(db, &stmt, DateTimeUtcTest).await +} diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs index cad35270..b7975b89 100644 --- a/tests/timestamp_tests.rs +++ b/tests/timestamp_tests.rs @@ -1,5 +1,4 @@ pub mod common; - pub use common::{features::*, setup::*, TestContext}; use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; @@ -13,8 +12,17 @@ async fn main() -> Result<(), DbErr> { let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await; create_tables(&ctx.db).await?; create_applog(&ctx.db).await?; + ctx.delete().await; + { + let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await; + create_tables(&ctx.db).await?; + create_satellites_log(&ctx.db).await?; + + ctx.delete().await; + } + Ok(()) } @@ -35,3 +43,24 @@ pub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> { Ok(()) } + +pub async fn create_satellites_log(db: &DatabaseConnection) -> Result<(), DbErr> { + let archive = datetimeutc::Model { + id: 1, + satellite_name: "Sea-00001-2022".to_owned(), + launch_date: "2022-01-07T12:11:23Z".parse().unwrap(), + deployment_date: "2022-01-07T12:11:23Z".parse().unwrap(), + }; + + let res = DateTimeUtcTest::insert(archive.clone().into_active_model()) + .exec(db) + .await?; + + assert_eq!(archive.id.clone(), res.last_insert_id); + assert_eq!( + DateTimeUtcTest::find().one(db).await?, + Some(archive.clone()) + ); + + Ok(()) +}