mod common;
use chrono::{NaiveDate, NaiveDateTime};
use orbit_orm::{Database, Model, OrbitModel, Query, Value, raw};
async fn connect() -> Option<Database> {
let url = common::url()?;
Some(Database::connect(&url).await.expect("connects"))
}
#[derive(Debug, PartialEq, OrbitModel)]
#[orbit(table = "orbit_values_events")]
struct Event {
id: i64,
#[orbit(fillable)]
happened_at: NaiveDateTime,
#[orbit(fillable)]
day: NaiveDate,
#[orbit(fillable)]
payload: Vec<u8>,
}
async fn run_sql(db: &Database, sql: &str) {
common::exec(db, sql).await;
}
async fn setup(db: &Database) {
run_sql(db, "DROP TABLE IF EXISTS orbit_values_events").await;
run_sql(
db,
"CREATE TABLE orbit_values_events (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
happened_at DATETIME(6) NOT NULL,
day DATE NOT NULL,
payload MEDIUMBLOB NOT NULL
)",
)
.await;
}
fn datetime() -> NaiveDateTime {
NaiveDate::from_ymd_opt(2026, 11, 10)
.unwrap()
.and_hms_micro_opt(18, 35, 7, 123_456)
.unwrap()
}
fn day() -> NaiveDate {
NaiveDate::from_ymd_opt(2026, 11, 10).unwrap()
}
fn payload() -> Vec<u8> {
vec![0x00, 0xff, 0xfe, b'o', b'k', 0x80, 0x00]
}
#[tokio::test]
async fn datetime_date_and_bytes_round_trip_through_the_builder_and_update() {
let Some(db) = connect().await else { return };
setup(&db).await;
let id = Query::<Event>::table()
.insert(
&db,
&[
("happened_at", Value::from(datetime())),
("day", Value::from(day())),
("payload", Value::from(payload())),
],
)
.await
.expect("inserts");
let saved = Event::query()
.find_or_fail(&db, id as i64)
.await
.expect("finds");
assert_eq!(
saved,
Event {
id: id as i64,
happened_at: datetime(),
day: day(),
payload: payload(),
}
);
assert_eq!(
saved.happened_at.and_utc().timestamp_subsec_micros(),
123_456
);
let tuples: Vec<(NaiveDateTime, NaiveDate, Vec<u8>)> = raw::fetch_all(
&db,
"SELECT happened_at, day, payload FROM orbit_values_events",
&[],
)
.await
.expect("reads");
assert_eq!(tuples, vec![(datetime(), day(), payload())]);
let found = Event::query()
.where_eq("happened_at", datetime())
.where_eq("day", day())
.where_eq("payload", payload())
.count(&db)
.await
.expect("counts");
assert_eq!(found, 1);
let next_day = NaiveDate::from_ymd_opt(2026, 11, 11).unwrap();
let changed = Event::query()
.where_eq("id", id)
.update(
&db,
&[
("day", Value::from(next_day)),
("payload", Value::from(vec![0x00u8, 0x01])),
],
)
.await
.expect("updates");
assert_eq!(changed, 1);
let updated = Event::query()
.find_or_fail(&db, id as i64)
.await
.expect("finds");
assert_eq!(updated.day, next_day);
assert_eq!(updated.payload, vec![0x00, 0x01]);
assert_eq!(updated.happened_at, datetime());
run_sql(&db, "DROP TABLE orbit_values_events").await;
db.close().await;
}