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

Supports time crate #602

Merged
merged 3 commits into from
Mar 20, 2022
Merged
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
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -25,12 +25,13 @@ 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 }
futures = { version = "^0.3" }
futures-util = { version = "^0.3" }
tracing = { version = "0.1", features = ["log"] }
rust_decimal = { version = "^1", optional = true }
sea-orm-macros = { version = "^0.6.0", path = "sea-orm-macros", optional = true }
sea-query = { version = "^0.22.0", features = ["thread-safe"] }
sea-query = { version = "^0.23.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 }
@@ -60,19 +61,22 @@ default = [
"with-chrono",
"with-rust_decimal",
"with-uuid",
"with-time",
]
macros = ["sea-orm-macros"]
mock = []
with-json = ["serde_json", "sea-query/with-json", "chrono/serde"]
with-chrono = ["chrono", "sea-query/with-chrono"]
with-rust_decimal = ["rust_decimal", "sea-query/with-rust_decimal"]
with-uuid = ["uuid", "sea-query/with-uuid"]
with-time = ["time", "sea-query/with-time"]
sqlx-all = ["sqlx-mysql", "sqlx-postgres", "sqlx-sqlite"]
sqlx-dep = ["sqlx-json", "sqlx-chrono", "sqlx-decimal", "sqlx-uuid"]
sqlx-dep = ["sqlx-json", "sqlx-chrono", "sqlx-decimal", "sqlx-uuid", "sqlx-time"]
sqlx-json = ["sqlx/json", "with-json"]
sqlx-chrono = ["sqlx/chrono", "with-chrono"]
sqlx-decimal = ["sqlx/decimal", "with-rust_decimal"]
sqlx-uuid = ["sqlx/uuid", "with-uuid"]
sqlx-time = ["sqlx/time", "with-time"]
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
33 changes: 33 additions & 0 deletions src/entity/prelude.rs
Original file line number Diff line number Diff line change
@@ -36,6 +36,39 @@ pub type DateTimeUtc = chrono::DateTime<chrono::Utc>;
#[cfg(feature = "with-chrono")]
pub type DateTimeLocal = chrono::DateTime<chrono::Local>;

#[cfg(feature = "with-chrono")]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an abstract way which would do this faster rather than importing the #[cfg()] macro always.

pub use chrono::NaiveDate as ChronoDate;

#[cfg(feature = "with-chrono")]
pub use chrono::NaiveTime as ChronoTime;

#[cfg(feature = "with-chrono")]
pub use chrono::NaiveDateTime as ChronoDateTime;

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

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

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

#[cfg(feature = "with-time")]
pub use time::Date as TimeDate;

#[cfg(feature = "with-time")]
pub use time::Time as TimeTime;

#[cfg(feature = "with-time")]
pub use time::PrimitiveDateTime as TimeDateTime;

#[cfg(feature = "with-time")]
pub use time::OffsetDateTime as TimeDateTimeWithTimeZone;

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

50 changes: 50 additions & 0 deletions src/executor/query.rs
Original file line number Diff line number Diff line change
@@ -252,6 +252,44 @@ macro_rules! try_getable_date_time {
};
}

macro_rules! try_getable_time {
( $type: ty ) => {
impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
row.try_get::<Option<$type>, _>(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::Row;
row.try_get::<Option<$type>, _>(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-sqlite")]
QueryResultRow::SqlxSqlite(_) => {
panic!("{} unsupported by sqlx-sqlite", stringify!($type))
}
#[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!(),
}
}
}
};
}

try_getable_all!(bool);
try_getable_all!(i8);
try_getable_all!(i16);
@@ -287,6 +325,18 @@ try_getable_all!(chrono::DateTime<chrono::Utc>);
#[cfg(feature = "with-chrono")]
try_getable_all!(chrono::DateTime<chrono::Local>);

#[cfg(feature = "with-time")]
try_getable_time!(time::Date);

#[cfg(feature = "with-time")]
try_getable_time!(time::Time);

#[cfg(feature = "with-time")]
try_getable_time!(time::PrimitiveDateTime);

#[cfg(feature = "with-time")]
try_getable_time!(time::OffsetDateTime);

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

2 changes: 2 additions & 0 deletions tests/common/features/mod.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ pub mod satellite;
pub mod schema;
pub mod sea_orm_active_enums;
pub mod self_join;
pub mod transaction_log;

pub use active_enum::Entity as ActiveEnum;
pub use active_enum_child::Entity as ActiveEnumChild;
@@ -19,3 +20,4 @@ pub use satellite::Entity as Satellite;
pub use schema::*;
pub use sea_orm_active_enums::*;
pub use self_join::Entity as SelfJoin;
pub use transaction_log::Entity as TransactionLog;
36 changes: 36 additions & 0 deletions tests/common/features/schema.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {
create_self_join_table(db).await?;
create_byte_primary_key_table(db).await?;
create_satellites_table(db).await?;
create_transaction_log_table(db).await?;

let create_enum_stmts = match db_backend {
DbBackend::MySql | DbBackend::Sqlite => Vec::new(),
@@ -234,3 +235,38 @@ pub async fn create_satellites_table(db: &DbConn) -> Result<ExecResult, DbErr> {

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

pub async fn create_transaction_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {
let stmt = sea_query::Table::create()
.table(transaction_log::Entity)
.col(
ColumnDef::new(transaction_log::Column::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(
ColumnDef::new(transaction_log::Column::Date)
.date()
.not_null(),
)
.col(
ColumnDef::new(transaction_log::Column::Time)
.time()
.not_null(),
)
.col(
ColumnDef::new(transaction_log::Column::DateTime)
.date_time()
.not_null(),
)
.col(
ColumnDef::new(transaction_log::Column::DateTimeTz)
.timestamp_with_time_zone()
.not_null(),
)
.to_owned();

create_table(db, &stmt, TransactionLog).await
}
17 changes: 17 additions & 0 deletions tests/common/features/transaction_log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "transaction_log")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub date: TimeDate,
pub time: TimeTime,
pub date_time: TimeDateTime,
pub date_time_tz: TimeDateTimeWithTimeZone,
}

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

impl ActiveModelBehavior for ActiveModel {}
46 changes: 46 additions & 0 deletions tests/time_crate_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pub mod common;
pub use common::{features::*, setup::*, TestContext};
use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel};
use time::{date, time};

#[sea_orm_macros::test]
#[cfg(any(
feature = "sqlx-mysql",
feature = "sqlx-sqlite",
feature = "sqlx-postgres"
))]
#[cfg_attr(
feature = "sqlx-sqlite",
should_panic(expected = "time::Date unsupported by sqlx-sqlite")
)]
async fn main() {
let ctx = TestContext::new("time_crate_tests").await;
create_tables(&ctx.db).await.unwrap();
create_transaction_log(&ctx.db).await.unwrap();

ctx.delete().await;
}

pub async fn create_transaction_log(db: &DatabaseConnection) -> Result<(), DbErr> {
let transaction_log = transaction_log::Model {
id: 1,
date: date!(2022 - 03 - 13),
time: time!(16:24:00),
date_time: date!(2022 - 03 - 13).with_time(time!(16:24:00)),
date_time_tz: date!(2022 - 03 - 13)
.with_time(time!(16:24:00))
.assume_utc(),
};
Comment on lines +27 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, changes. Good work👍


let res = TransactionLog::insert(transaction_log.clone().into_active_model())
.exec(db)
.await?;

assert_eq!(transaction_log.id, res.last_insert_id);
assert_eq!(
TransactionLog::find().one(db).await?,
Some(transaction_log.clone())
);

Ok(())
}