Supports time crate

This commit is contained in:
Billy Chan 2022-03-13 18:18:09 +08:00
parent de57934061
commit 9687819a7e
No known key found for this signature in database
GPG Key ID: A2D690CAC7DF3CC7
7 changed files with 190 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.6.0", path = "sea-orm-macros", optional = true }
sea-query = { version = "^0.21.0", features = ["thread-safe"] }
sea-query = { git = "https://github.com/billy1624/sea-query", branch = "pr/256", 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 }
@ -39,6 +39,7 @@ uuid = { version = "0.8", features = ["serde", "v4"], optional = true }
ouroboros = "0.14"
url = "^2.2"
once_cell = "1.8"
time = { version = "^0.2", optional = true }
[dev-dependencies]
smol = { version = "^1.2" }
@ -60,6 +61,7 @@ default = [
"with-chrono",
"with-rust_decimal",
"with-uuid",
"with-time",
]
macros = ["sea-orm-macros"]
mock = []
@ -67,12 +69,14 @@ 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"]

View File

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

View File

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

View File

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

View File

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

View File

@ -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
tests/time_crate_tests.rs Normal file
View File

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