diff --git a/Cargo.toml b/Cargo.toml index 3641e030..67084e66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.2", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.16.1", features = ["thread-safe"] } +sea-query = { version = "^0.16.2", git = "https://github.com/SeaQL/sea-query.git", branch = "pg-driver-timestamp-tz", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 768d3b7c..c34c43f7 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -172,9 +172,12 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res "bool" => quote! { Boolean }, "NaiveDate" => quote! { Date }, "NaiveTime" => quote! { Time }, - "DateTime" | "NaiveDateTime" | "DateTimeWithTimeZone" => { + "DateTime" | "NaiveDateTime" => { quote! { DateTime } } + "DateTimeWithTimeZone" => { + quote! { TimestampWithTimeZone } + } "Uuid" => quote! { Uuid }, "Json" => quote! { Json }, "Decimal" => quote! { Decimal }, diff --git a/src/entity/column.rs b/src/entity/column.rs index 6e871f4d..26d8ec0e 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -24,6 +24,7 @@ pub enum ColumnType { Decimal(Option<(u32, u32)>), DateTime, Timestamp, + TimestampWithTimeZone, Time, Date, Binary, @@ -278,6 +279,7 @@ impl From for sea_query::ColumnType { ColumnType::Decimal(s) => sea_query::ColumnType::Decimal(s), ColumnType::DateTime => sea_query::ColumnType::DateTime(None), ColumnType::Timestamp => sea_query::ColumnType::Timestamp(None), + 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), @@ -309,6 +311,7 @@ impl From for ColumnType { sea_query::ColumnType::Decimal(s) => Self::Decimal(s), sea_query::ColumnType::DateTime(_) => Self::DateTime, sea_query::ColumnType::Timestamp(_) => Self::Timestamp, + sea_query::ColumnType::TimestampWithTimeZone(_) => Self::TimestampWithTimeZone, sea_query::ColumnType::Time(_) => Self::Time, sea_query::ColumnType::Date => Self::Date, sea_query::ColumnType::Binary(_) => Self::Binary, diff --git a/tests/common/bakery_chain/log.rs b/tests/common/bakery_chain/log.rs new file mode 100644 index 00000000..c483e41b --- /dev/null +++ b/tests/common/bakery_chain/log.rs @@ -0,0 +1,21 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "log")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub json: Json, + pub created_at: DateTimeWithTimeZone, +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation {} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + unreachable!() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/bakery_chain/metadata.rs b/tests/common/bakery_chain/metadata.rs index 69579492..2585b2db 100644 --- a/tests/common/bakery_chain/metadata.rs +++ b/tests/common/bakery_chain/metadata.rs @@ -1,5 +1,4 @@ use sea_orm::entity::prelude::*; -use uuid::Uuid; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "metadata")] diff --git a/tests/common/bakery_chain/mod.rs b/tests/common/bakery_chain/mod.rs index 3282766d..dc145d36 100644 --- a/tests/common/bakery_chain/mod.rs +++ b/tests/common/bakery_chain/mod.rs @@ -4,6 +4,7 @@ pub mod cake; pub mod cakes_bakers; pub mod customer; pub mod lineitem; +pub mod log; pub mod metadata; pub mod order; @@ -13,5 +14,6 @@ pub use super::cake::Entity as Cake; pub use super::cakes_bakers::Entity as CakesBakers; pub use super::customer::Entity as Customer; pub use super::lineitem::Entity as Lineitem; +pub use super::log::Entity as Log; pub use super::metadata::Entity as Metadata; pub use super::order::Entity as Order; diff --git a/tests/common/setup/mod.rs b/tests/common/setup/mod.rs index 74e35b45..d982b2b7 100644 --- a/tests/common/setup/mod.rs +++ b/tests/common/setup/mod.rs @@ -53,6 +53,7 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection { schema::create_cakes_bakers_table(&db).await.unwrap(); schema::create_lineitem_table(&db).await.unwrap(); schema::create_metadata_table(&db).await.unwrap(); + schema::create_log_table(&db).await.unwrap(); db } diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index 78947c36..bbb09a0a 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -286,3 +286,25 @@ pub async fn create_metadata_table(db: &DbConn) -> Result { create_table(db, &stmt, Metadata).await } + +pub async fn create_log_table(db: &DbConn) -> Result { + let stmt = sea_query::Table::create() + .table(log::Entity) + .if_not_exists() + .col( + ColumnDef::new(log::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(log::Column::Json).json().not_null()) + .col( + ColumnDef::new(log::Column::CreatedAt) + .timestamp_with_time_zone() + .not_null(), + ) + .to_owned(); + + create_table(db, &stmt, Log).await +} diff --git a/tests/timestamp_tests.rs b/tests/timestamp_tests.rs new file mode 100644 index 00000000..e1f145ca --- /dev/null +++ b/tests/timestamp_tests.rs @@ -0,0 +1,35 @@ +pub mod common; + +pub use common::{bakery_chain::*, setup::*, TestContext}; +use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel}; + +#[sea_orm_macros::test] +#[cfg(feature = "sqlx-postgres")] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("bakery_chain_schema_timestamp_tests").await; + + create_log(&ctx.db).await?; + + ctx.delete().await; + + Ok(()) +} + +pub async fn create_log(db: &DatabaseConnection) -> Result<(), DbErr> { + let log = log::Model { + id: 1, + json: Json::String("HI".to_owned()), + created_at: "2021-09-17T17:50:20+08:00".parse().unwrap(), + }; + + let res = Log::insert(log.clone().into_active_model()) + .exec(db) + .await?; + + assert_eq!(log.id.clone(), res.last_insert_id); + assert_eq!(Log::find().one(db).await?, Some(log.clone())); + + assert!(false); + + Ok(()) +}