Support the use of chrono::DateTime<Utc> in sea-orm

Add documentation for this

Temporarily use a fork to include new Sea-query code

Add tests for DateTimeUtc

Solve Github actions error by add the code to create a table

Assertion accuracy tests

Rectify incorrect format
This commit is contained in:
Charles Chege 2022-01-05 18:20:11 +03:00 committed by Chris Tsang
parent 82bad4a376
commit 52f38a10ea
9 changed files with 140 additions and 2 deletions

View File

@ -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 }

View File

@ -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);

View File

@ -28,6 +28,50 @@ pub use chrono::NaiveDateTime as DateTime;
#[cfg(feature = "with-chrono")]
pub type DateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;
/// 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::<Utc>::from_utc(NaiveDateTime::from_timestamp(61, 0), Utc),
/// };
///
/// assert_eq!(
/// fruit::Model {
/// id: 3,
/// name: "Fruit".to_owned(),
/// cake_id: Some(4,),
/// timer: DateTime::<Utc>::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<i32>,
/// 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<chrono::Utc>;
#[cfg(feature = "with-rust_decimal")]
pub use rust_decimal::Decimal;

View File

@ -271,6 +271,10 @@ try_getable_all!(chrono::NaiveDateTime);
#[cfg(feature = "with-chrono")]
try_getable_date_time!(chrono::DateTime<chrono::FixedOffset>);
#[cfg(feature = "with-chrono")]
try_getable_date_time!(chrono::DateTime<chrono::Utc>);
#[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<chrono::FixedOffset>);
#[cfg(feature = "with-chrono")]
try_from_u64_err!(chrono::DateTime<chrono::Utc>);
#[cfg(feature = "with-rust_decimal")]
try_from_u64_err!(rust_decimal::Decimal);

View File

@ -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")

View File

@ -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 {}

View File

@ -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::*;

View File

@ -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<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(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
}

View File

@ -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(())
}