Merge pull request #602 from SeaQL/support-time-crate
Supports `time` crate
This commit is contained in:
commit
fe1f763feb
@ -25,12 +25,13 @@ path = "src/lib.rs"
|
|||||||
async-stream = { version = "^0.3" }
|
async-stream = { version = "^0.3" }
|
||||||
async-trait = { version = "^0.1" }
|
async-trait = { version = "^0.1" }
|
||||||
chrono = { version = "^0", optional = true }
|
chrono = { version = "^0", optional = true }
|
||||||
|
time = { version = "^0.2", optional = true }
|
||||||
futures = { version = "^0.3" }
|
futures = { version = "^0.3" }
|
||||||
futures-util = { version = "^0.3" }
|
futures-util = { version = "^0.3" }
|
||||||
tracing = { version = "0.1", features = ["log"] }
|
tracing = { version = "0.1", features = ["log"] }
|
||||||
rust_decimal = { version = "^1", optional = true }
|
rust_decimal = { version = "^1", optional = true }
|
||||||
sea-orm-macros = { version = "^0.6.0", path = "sea-orm-macros", 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"] }
|
sea-strum = { version = "^0.23", features = ["derive", "sea-orm"] }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
serde_json = { version = "^1", optional = true }
|
serde_json = { version = "^1", optional = true }
|
||||||
@ -60,6 +61,7 @@ default = [
|
|||||||
"with-chrono",
|
"with-chrono",
|
||||||
"with-rust_decimal",
|
"with-rust_decimal",
|
||||||
"with-uuid",
|
"with-uuid",
|
||||||
|
"with-time",
|
||||||
]
|
]
|
||||||
macros = ["sea-orm-macros"]
|
macros = ["sea-orm-macros"]
|
||||||
mock = []
|
mock = []
|
||||||
@ -67,12 +69,14 @@ with-json = ["serde_json", "sea-query/with-json", "chrono/serde"]
|
|||||||
with-chrono = ["chrono", "sea-query/with-chrono"]
|
with-chrono = ["chrono", "sea-query/with-chrono"]
|
||||||
with-rust_decimal = ["rust_decimal", "sea-query/with-rust_decimal"]
|
with-rust_decimal = ["rust_decimal", "sea-query/with-rust_decimal"]
|
||||||
with-uuid = ["uuid", "sea-query/with-uuid"]
|
with-uuid = ["uuid", "sea-query/with-uuid"]
|
||||||
|
with-time = ["time", "sea-query/with-time"]
|
||||||
sqlx-all = ["sqlx-mysql", "sqlx-postgres", "sqlx-sqlite"]
|
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-json = ["sqlx/json", "with-json"]
|
||||||
sqlx-chrono = ["sqlx/chrono", "with-chrono"]
|
sqlx-chrono = ["sqlx/chrono", "with-chrono"]
|
||||||
sqlx-decimal = ["sqlx/decimal", "with-rust_decimal"]
|
sqlx-decimal = ["sqlx/decimal", "with-rust_decimal"]
|
||||||
sqlx-uuid = ["sqlx/uuid", "with-uuid"]
|
sqlx-uuid = ["sqlx/uuid", "with-uuid"]
|
||||||
|
sqlx-time = ["sqlx/time", "with-time"]
|
||||||
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
|
sqlx-mysql = ["sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql"]
|
||||||
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
|
sqlx-postgres = ["sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres"]
|
||||||
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
|
sqlx-sqlite = ["sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite"]
|
||||||
|
@ -36,6 +36,39 @@ pub type DateTimeUtc = chrono::DateTime<chrono::Utc>;
|
|||||||
#[cfg(feature = "with-chrono")]
|
#[cfg(feature = "with-chrono")]
|
||||||
pub type DateTimeLocal = chrono::DateTime<chrono::Local>;
|
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")]
|
#[cfg(feature = "with-rust_decimal")]
|
||||||
pub use rust_decimal::Decimal;
|
pub use rust_decimal::Decimal;
|
||||||
|
|
||||||
|
@ -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!(bool);
|
||||||
try_getable_all!(i8);
|
try_getable_all!(i8);
|
||||||
try_getable_all!(i16);
|
try_getable_all!(i16);
|
||||||
@ -287,6 +325,18 @@ try_getable_all!(chrono::DateTime<chrono::Utc>);
|
|||||||
#[cfg(feature = "with-chrono")]
|
#[cfg(feature = "with-chrono")]
|
||||||
try_getable_all!(chrono::DateTime<chrono::Local>);
|
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")]
|
#[cfg(feature = "with-rust_decimal")]
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ pub mod satellite;
|
|||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod sea_orm_active_enums;
|
pub mod sea_orm_active_enums;
|
||||||
pub mod self_join;
|
pub mod self_join;
|
||||||
|
pub mod transaction_log;
|
||||||
|
|
||||||
pub use active_enum::Entity as ActiveEnum;
|
pub use active_enum::Entity as ActiveEnum;
|
||||||
pub use active_enum_child::Entity as ActiveEnumChild;
|
pub use active_enum_child::Entity as ActiveEnumChild;
|
||||||
@ -19,3 +20,4 @@ pub use satellite::Entity as Satellite;
|
|||||||
pub use schema::*;
|
pub use schema::*;
|
||||||
pub use sea_orm_active_enums::*;
|
pub use sea_orm_active_enums::*;
|
||||||
pub use self_join::Entity as SelfJoin;
|
pub use self_join::Entity as SelfJoin;
|
||||||
|
pub use transaction_log::Entity as TransactionLog;
|
||||||
|
@ -17,6 +17,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {
|
|||||||
create_self_join_table(db).await?;
|
create_self_join_table(db).await?;
|
||||||
create_byte_primary_key_table(db).await?;
|
create_byte_primary_key_table(db).await?;
|
||||||
create_satellites_table(db).await?;
|
create_satellites_table(db).await?;
|
||||||
|
create_transaction_log_table(db).await?;
|
||||||
|
|
||||||
let create_enum_stmts = match db_backend {
|
let create_enum_stmts = match db_backend {
|
||||||
DbBackend::MySql | DbBackend::Sqlite => Vec::new(),
|
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
|
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
tests/common/features/transaction_log.rs
Normal file
17
tests/common/features/transaction_log.rs
Normal 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
46
tests/time_crate_tests.rs
Normal 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(())
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user