Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DateTime<Utc> & DateTime<Local> #489

Merged
merged 3 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = { version = "^0.21.0", features = ["thread-safe"] }
sea-strum = { version = "^0.23", features = ["derive", "sea-orm"] }
serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1", optional = true }
Expand Down
5 changes: 3 additions & 2 deletions sea-orm-codegen/src/entity/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ impl Column {
ColumnType::Json | ColumnType::JsonBinary => "Json".to_owned(),
ColumnType::Date => "Date".to_owned(),
ColumnType::Time(_) => "Time".to_owned(),
ColumnType::DateTime(_) | ColumnType::Timestamp(_) => "DateTime".to_owned(),
ColumnType::DateTime(_) => "DateTime".to_owned(),
ColumnType::Timestamp(_) => "DateTimeUtc".to_owned(),
ColumnType::TimestampWithTimeZone(_) => "DateTimeWithTimeZone".to_owned(),
ColumnType::Decimal(_) | ColumnType::Money(_) => "Decimal".to_owned(),
ColumnType::Uuid => "Uuid".to_owned(),
Expand Down Expand Up @@ -271,7 +272,7 @@ mod tests {
"Date",
"Time",
"DateTime",
"DateTime",
"DateTimeUtc",
"DateTimeWithTimeZone",
];
for (mut col, rs_type) in columns.into_iter().zip(rs_types) {
Expand Down
2 changes: 1 addition & 1 deletion sea-orm-macros/src/derives/entity_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
"DateTime" | "NaiveDateTime" => {
quote! { DateTime }
}
"DateTimeWithTimeZone" => {
"DateTimeUtc" | "DateTimeLocal" | "DateTimeWithTimeZone" => {
quote! { TimestampWithTimeZone }
}
"Uuid" => quote! { Uuid },
Expand Down
8 changes: 8 additions & 0 deletions src/entity/active_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,14 @@ 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-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
impl_into_active_value!(crate::prelude::DateTimeLocal, Set);

#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
impl_into_active_value!(crate::prelude::Decimal, Set);
Expand Down
11 changes: 11 additions & 0 deletions src/entity/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct ColumnDef {
pub(crate) null: bool,
pub(crate) unique: bool,
pub(crate) indexed: bool,
pub(crate) default_value: Option<Value>,
}

/// The type of column as defined in the SQL format
Expand Down Expand Up @@ -300,6 +301,7 @@ impl ColumnType {
null: false,
unique: false,
indexed: false,
default_value: None,
}
}

Expand Down Expand Up @@ -335,6 +337,15 @@ impl ColumnDef {
self
}

/// Set the default value
pub fn default_value<T>(mut self, value: T) -> Self
where
T: Into<Value>,
{
self.default_value = Some(value.into());
self
}

/// Get [ColumnType] as reference
pub fn get_column_type(&self) -> &ColumnType {
&self.col_type
Expand Down
10 changes: 9 additions & 1 deletion src/entity/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ pub use chrono::NaiveTime as Time;
#[cfg(feature = "with-chrono")]
pub use chrono::NaiveDateTime as DateTime;

/// Handles the time and dates
/// Date time with fixed offset
#[cfg(feature = "with-chrono")]
pub type DateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;

/// Date time represented in UTC
#[cfg(feature = "with-chrono")]
pub type DateTimeUtc = chrono::DateTime<chrono::Utc>;

/// Date time represented in local time
#[cfg(feature = "with-chrono")]
pub type DateTimeLocal = chrono::DateTime<chrono::Local>;

#[cfg(feature = "with-rust_decimal")]
pub use rust_decimal::Decimal;

Expand Down
12 changes: 12 additions & 0 deletions src/executor/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ try_getable_all!(chrono::NaiveDateTime);
#[cfg(feature = "with-chrono")]
try_getable_date_time!(chrono::DateTime<chrono::FixedOffset>);

#[cfg(feature = "with-chrono")]
try_getable_all!(chrono::DateTime<chrono::Utc>);

#[cfg(feature = "with-chrono")]
try_getable_all!(chrono::DateTime<chrono::Local>);

#[cfg(feature = "with-rust_decimal")]
use rust_decimal::Decimal;

Expand Down Expand Up @@ -614,6 +620,12 @@ try_from_u64_err!(chrono::NaiveDateTime);
#[cfg(feature = "with-chrono")]
try_from_u64_err!(chrono::DateTime<chrono::FixedOffset>);

#[cfg(feature = "with-chrono")]
try_from_u64_err!(chrono::DateTime<chrono::Utc>);

#[cfg(feature = "with-chrono")]
try_from_u64_err!(chrono::DateTime<chrono::Local>);

#[cfg(feature = "with-rust_decimal")]
try_from_u64_err!(rust_decimal::Decimal);

Expand Down
14 changes: 12 additions & 2 deletions src/query/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,21 @@ where
None => {
let col = match &sel.expr {
SimpleExpr::Column(col_ref) => match &col_ref {
ColumnRef::Column(col) | ColumnRef::TableColumn(_, col) => col,
ColumnRef::Column(col)
| ColumnRef::TableColumn(_, col)
| ColumnRef::SchemaTableColumn(_, _, col) => col,
ColumnRef::Asterisk | ColumnRef::TableAsterisk(_) => {
panic!("cannot apply alias for Column with asterisk")
}
},
SimpleExpr::AsEnum(_, simple_expr) => match simple_expr.as_ref() {
SimpleExpr::Column(col_ref) => match &col_ref {
ColumnRef::Column(col) | ColumnRef::TableColumn(_, col) => col,
ColumnRef::Column(col)
| ColumnRef::TableColumn(_, col)
| ColumnRef::SchemaTableColumn(_, _, col) => col,
ColumnRef::Asterisk | ColumnRef::TableAsterisk(_) => {
panic!("cannot apply alias for AsEnum with asterisk")
}
},
_ => {
panic!("cannot apply alias for AsEnum with expr other than Column")
Expand Down
2 changes: 1 addition & 1 deletion src/query/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ macro_rules! debug_query_stmt {
/// let raw_sql = debug_query!(&c, DbBackend::Sqlite);
/// assert_eq!(
/// raw_sql,
/// r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#
/// r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#
/// );
/// ```
#[macro_export]
Expand Down
3 changes: 3 additions & 0 deletions src/schema/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ where
if orm_column_def.unique {
column_def.unique_key();
}
if let Some(value) = orm_column_def.default_value {
column_def.default(value);
}
for primary_key in E::PrimaryKey::iter() {
if column.to_string() == primary_key.into_column().to_string() {
if E::PrimaryKey::auto_increment() {
Expand Down
80 changes: 68 additions & 12 deletions tests/active_enum_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,14 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
[
r#"SELECT "active_enum_child"."id", "active_enum_child"."parent_id", "active_enum_child"."category", "active_enum_child"."color", "active_enum_child"."tea""#,
r#"FROM "active_enum_child""#,
r#"INNER JOIN "active_enum" ON "active_enum"."id" = "active_enum_child"."parent_id""#,
r#"WHERE "active_enum"."id" = 1"#,
]
.join(" ")
);
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
Expand Down Expand Up @@ -435,8 +441,16 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
_select
.build(DbBackend::Sqlite)
.to_string(),
[
r#"SELECT "active_enum"."id" AS "A_id", "active_enum"."category" AS "A_category", "active_enum"."color" AS "A_color", "active_enum"."tea" AS "A_tea","#,
r#""active_enum_child"."id" AS "B_id", "active_enum_child"."parent_id" AS "B_parent_id", "active_enum_child"."category" AS "B_category", "active_enum_child"."color" AS "B_color", "active_enum_child"."tea" AS "B_tea""#,
r#"FROM "active_enum""#,
r#"LEFT JOIN "active_enum_child" ON "active_enum"."id" = "active_enum_child"."parent_id""#,
]
.join(" ")
);
assert_eq!(
_select
Expand Down Expand Up @@ -478,8 +492,14 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
[
r#"SELECT "active_enum_child"."id", "active_enum_child"."parent_id", "active_enum_child"."category", "active_enum_child"."color", "active_enum_child"."tea""#,
r#"FROM "active_enum_child""#,
r#"INNER JOIN "active_enum" AS "r0" ON "r0"."id" = "active_enum_child"."parent_id""#,
r#"WHERE "r0"."id" = 1"#,
]
.join(" ")
);
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
Expand Down Expand Up @@ -508,8 +528,16 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
_select
.build(DbBackend::Sqlite)
.to_string(),
[
r#"SELECT "active_enum"."id" AS "A_id", "active_enum"."category" AS "A_category", "active_enum"."color" AS "A_color", "active_enum"."tea" AS "A_tea","#,
r#""r0"."id" AS "B_id", "r0"."parent_id" AS "B_parent_id", "r0"."category" AS "B_category", "r0"."color" AS "B_color", "r0"."tea" AS "B_tea""#,
r#"FROM "active_enum""#,
r#"LEFT JOIN "active_enum_child" AS "r0" ON "active_enum"."id" = "r0"."parent_id""#,
]
.join(" ")
);
assert_eq!(
_select
Expand Down Expand Up @@ -552,8 +580,14 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
[
r#"SELECT "active_enum"."id", "active_enum"."category", "active_enum"."color", "active_enum"."tea""#,
r#"FROM "active_enum""#,
r#"INNER JOIN "active_enum_child" ON "active_enum_child"."parent_id" = "active_enum"."id""#,
r#"WHERE "active_enum_child"."id" = 1"#,
]
.join(" ")
);
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
Expand Down Expand Up @@ -582,8 +616,16 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
_select
.build(DbBackend::Sqlite)
.to_string(),
[
r#"SELECT "active_enum_child"."id" AS "A_id", "active_enum_child"."parent_id" AS "A_parent_id", "active_enum_child"."category" AS "A_category", "active_enum_child"."color" AS "A_color", "active_enum_child"."tea" AS "A_tea","#,
r#""active_enum"."id" AS "B_id", "active_enum"."category" AS "B_category", "active_enum"."color" AS "B_color", "active_enum"."tea" AS "B_tea""#,
r#"FROM "active_enum_child""#,
r#"LEFT JOIN "active_enum" ON "active_enum_child"."parent_id" = "active_enum"."id""#,
]
.join(" ")
);
assert_eq!(
_select
Expand Down Expand Up @@ -626,8 +668,14 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
[
r#"SELECT "active_enum"."id", "active_enum"."category", "active_enum"."color", "active_enum"."tea""#,
r#"FROM "active_enum""#,
r#"INNER JOIN "active_enum_child" AS "r0" ON "r0"."parent_id" = "active_enum"."id""#,
r#"WHERE "r0"."id" = 1"#,
]
.join(" ")
);
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
Expand Down Expand Up @@ -656,8 +704,16 @@ mod tests {
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
{
assert_eq!(
_select.build(DbBackend::MySql).to_string(),
_select.build(DbBackend::Sqlite).to_string(),
_select
.build(DbBackend::Sqlite)
.to_string(),
[
r#"SELECT "active_enum_child"."id" AS "A_id", "active_enum_child"."parent_id" AS "A_parent_id", "active_enum_child"."category" AS "A_category", "active_enum_child"."color" AS "A_color", "active_enum_child"."tea" AS "A_tea","#,
r#""r0"."id" AS "B_id", "r0"."category" AS "B_category", "r0"."color" AS "B_color", "r0"."tea" AS "B_tea""#,
r#"FROM "active_enum_child""#,
r#"LEFT JOIN "active_enum" AS "r0" ON "active_enum_child"."parent_id" = "r0"."id""#,
]
.join(" ")
);
assert_eq!(
_select
Expand Down
2 changes: 2 additions & 0 deletions tests/common/features/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod applog;
pub mod byte_primary_key;
pub mod metadata;
pub mod repository;
pub mod satellite;
pub mod schema;
pub mod sea_orm_active_enums;
pub mod self_join;
Expand All @@ -14,6 +15,7 @@ pub use applog::Entity as Applog;
pub use byte_primary_key::Entity as BytePrimaryKey;
pub use metadata::Entity as Metadata;
pub use repository::Entity as Repository;
pub use satellite::Entity as Satellite;
pub use schema::*;
pub use sea_orm_active_enums::*;
pub use self_join::Entity as SelfJoin;
18 changes: 18 additions & 0 deletions tests/common/features/satellite.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "satellite")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub satellite_name: String,
#[sea_orm(default_value = "2022-01-26 16:24:00")]
pub launch_date: DateTimeUtc,
#[sea_orm(default_value = "2022-01-26 16:24:00")]
pub deployment_date: DateTimeLocal,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}
33 changes: 33 additions & 0 deletions tests/common/features/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -201,3 +202,35 @@ pub async fn create_active_enum_child_table(db: &DbConn) -> Result<ExecResult, D

create_table(db, &create_table_stmt, ActiveEnumChild).await
}

pub async fn create_satellites_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = sea_query::Table::create()
.table(satellite::Entity)
.col(
ColumnDef::new(satellite::Column::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(
ColumnDef::new(satellite::Column::SatelliteName)
.string()
.not_null(),
)
.col(
ColumnDef::new(satellite::Column::LaunchDate)
.timestamp_with_time_zone()
.not_null()
.default("2022-01-26 16:24:00"),
)
.col(
ColumnDef::new(satellite::Column::DeploymentDate)
.timestamp_with_time_zone()
.not_null()
.default("2022-01-26 16:24:00"),
)
.to_owned();

create_table(db, &stmt, Satellite).await
}
Loading