#[cfg(test)]
mod tests {
use indoc::indoc;
use rust_decimal::{Decimal, prelude::FromPrimitive};
use std::{borrow::Cow, sync::Arc, time::Duration};
use tank::{
DefaultValueType, DynQuery, Entity, GenericSqlWriter, PrimaryKeyType, QueryBuilder,
SqlWriter, TableRef, Value, expr,
};
#[derive(Entity)]
#[tank(name = "a_table", primary_key = ("bravo", "delta"))]
struct MyEntity {
_alpha: Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<f64>>>>>>>>>>>,
_bravo: i16,
_charlie: Box<Box<Option<Option<Box<Box<Option<Box<rust_decimal::Decimal>>>>>>>>,
#[tank(name = "delta")]
_delta_duration: Duration,
_echo: Option<Arc<rust_decimal::Decimal>>,
_foxtrot: &'static str,
}
impl MyEntity {
pub fn sample() -> Self {
Self {
_alpha: Box::new(Box::new(Box::new(Box::new(Box::new(Box::new(Box::new(
Box::new(Box::new(Box::new(Box::new(0.0)))),
))))))),
_bravo: 2,
_charlie: Box::new(Box::new(Some(Some(Box::new(Box::new(Some(Box::new(
Decimal::from_f64(10.2).unwrap(),
)))))))),
_delta_duration: Duration::from_secs(1),
_echo: Some(Arc::new(Decimal::from_f64(23.44).unwrap())),
_foxtrot: "Target acquired",
}
}
}
const WRITER: GenericSqlWriter = GenericSqlWriter {};
#[test]
fn test_odd_entity() {
assert!(matches!(
MyEntity::table(),
TableRef {
name: Cow::Borrowed("a_table"),
schema: Cow::Borrowed(""),
alias: Cow::Borrowed(""),
..
}
));
let pk = MyEntity::primary_key_def().to_vec();
assert_eq!(pk.len(), 2);
assert_eq!(pk[0].nullable, false);
assert_eq!(pk[0].primary_key, PrimaryKeyType::PartOfPrimaryKey);
assert_eq!(pk[1].nullable, false);
assert_eq!(pk[1].primary_key, PrimaryKeyType::PartOfPrimaryKey);
let columns = MyEntity::columns();
assert_eq!(columns.len(), 6);
assert_eq!(columns[0].column_ref.name, "alpha");
assert_eq!(columns[1].column_ref.name, "bravo");
assert_eq!(columns[2].column_ref.name, "charlie");
assert_eq!(columns[3].column_ref.name, "delta");
assert_eq!(columns[4].column_ref.name, "echo");
assert_eq!(columns[5].column_ref.name, "foxtrot");
assert_eq!(columns[0].column_ref.table, "a_table");
assert_eq!(columns[1].column_ref.table, "a_table");
assert_eq!(columns[2].column_ref.table, "a_table");
assert_eq!(columns[3].column_ref.table, "a_table");
assert_eq!(columns[4].column_ref.table, "a_table");
assert_eq!(columns[5].column_ref.table, "a_table");
assert_eq!(columns[0].column_ref.schema, "");
assert_eq!(columns[1].column_ref.schema, "");
assert_eq!(columns[2].column_ref.schema, "");
assert_eq!(columns[3].column_ref.schema, "");
assert_eq!(columns[4].column_ref.schema, "");
assert_eq!(columns[5].column_ref.schema, "");
assert!(matches!(columns[0].default, DefaultValueType::None));
assert!(matches!(columns[1].default, DefaultValueType::None));
assert!(matches!(columns[2].default, DefaultValueType::None));
assert!(matches!(columns[3].default, DefaultValueType::None));
assert!(matches!(columns[4].default, DefaultValueType::None));
assert!(matches!(columns[5].default, DefaultValueType::None));
assert_eq!(columns[0].value, Value::Float64(None));
assert_eq!(columns[1].value, Value::Int16(None));
assert_eq!(columns[2].value, Value::Decimal(None, 0, 0));
assert_eq!(columns[3].value, Value::Interval(None));
assert_eq!(columns[4].value, Value::Decimal(None, 0, 0));
assert_eq!(columns[5].value, Value::Varchar(None));
assert_eq!(columns[0].nullable, false);
assert_eq!(columns[1].nullable, false);
assert_eq!(columns[2].nullable, true);
assert_eq!(columns[3].nullable, false);
assert_eq!(columns[4].nullable, true);
assert_eq!(columns[5].nullable, false);
assert!(matches!(columns[0].default, DefaultValueType::None));
assert!(matches!(columns[1].default, DefaultValueType::None));
assert!(matches!(columns[2].default, DefaultValueType::None));
assert!(matches!(columns[3].default, DefaultValueType::None));
assert!(matches!(columns[4].default, DefaultValueType::None));
assert!(matches!(columns[5].default, DefaultValueType::None));
assert_eq!(columns[0].primary_key, PrimaryKeyType::None);
assert_eq!(columns[1].primary_key, PrimaryKeyType::PartOfPrimaryKey);
assert_eq!(columns[2].primary_key, PrimaryKeyType::None);
assert_eq!(columns[3].primary_key, PrimaryKeyType::PartOfPrimaryKey);
assert_eq!(columns[4].primary_key, PrimaryKeyType::None);
assert_eq!(columns[5].primary_key, PrimaryKeyType::None);
assert_eq!(columns[0].unique, false);
assert_eq!(columns[1].unique, false);
assert_eq!(columns[2].unique, false);
assert_eq!(columns[3].unique, false);
assert_eq!(columns[4].unique, false);
assert_eq!(columns[5].unique, false);
assert_eq!(columns[0].references, None);
assert_eq!(columns[1].references, None);
assert_eq!(columns[2].references, None);
assert_eq!(columns[3].references, None);
assert_eq!(columns[4].references, None);
assert_eq!(columns[5].references, None);
assert_eq!(columns[0].on_delete, None);
assert_eq!(columns[1].on_delete, None);
assert_eq!(columns[2].on_delete, None);
assert_eq!(columns[3].on_delete, None);
assert_eq!(columns[4].on_delete, None);
assert_eq!(columns[0].on_update, None);
assert_eq!(columns[5].on_update, None);
assert_eq!(columns[1].on_update, None);
assert_eq!(columns[2].on_update, None);
assert_eq!(columns[3].on_update, None);
assert_eq!(columns[4].on_update, None);
assert_eq!(columns[5].on_update, None);
}
#[test]
fn test_odd_entity_create_table() {
let mut query = DynQuery::default();
WRITER.write_create_table::<MyEntity>(&mut query, true);
assert_eq!(
query.as_str(),
indoc! {r#"
CREATE TABLE IF NOT EXISTS "a_table" (
"alpha" DOUBLE NOT NULL,
"bravo" SMALLINT,
"charlie" DECIMAL,
"delta" INTERVAL,
"echo" DECIMAL,
"foxtrot" VARCHAR NOT NULL,
PRIMARY KEY ("bravo", "delta"));
"#}
.trim()
);
}
#[test]
fn test_odd_entity_drop_table() {
let mut query = DynQuery::default();
WRITER.write_drop_table::<MyEntity>(&mut query, false);
assert_eq!(query.as_str(), r#"DROP TABLE "a_table";"#);
}
#[test]
fn test_odd_entity_select() {
let mut query = DynQuery::default();
WRITER.write_select(
&mut query,
&QueryBuilder::new()
.select(MyEntity::columns())
.from(MyEntity::table())
.where_expr(expr!(MyEntity::_bravo < 0))
.limit(Some(300)),
);
assert_eq!(
query.as_str(),
indoc! {r#"
SELECT "alpha", "bravo", "charlie", "delta", "echo", "foxtrot"
FROM "a_table"
WHERE "bravo" < 0
LIMIT 300;
"#}
.trim()
);
}
#[test]
fn test_odd_entity_insert() {
let mut query = DynQuery::default();
WRITER.write_insert(&mut query, [&MyEntity::sample()], true);
assert_eq!(
query.as_str(),
indoc! {r#"
INSERT INTO "a_table" ("alpha", "bravo", "charlie", "delta", "echo", "foxtrot") VALUES
(0.0, 2, 10.2, INTERVAL '1 SECOND', 23.44, 'Target acquired')
ON CONFLICT ("bravo", "delta") DO UPDATE SET
"alpha" = EXCLUDED."alpha",
"charlie" = EXCLUDED."charlie",
"echo" = EXCLUDED."echo",
"foxtrot" = EXCLUDED."foxtrot";
"#}
.trim()
);
}
#[test]
fn test_odd_entity_delete() {
let mut query = DynQuery::default();
WRITER.write_delete::<MyEntity>(&mut query, expr!(MyEntity::_echo == 5));
assert_eq!(
query.as_str(),
indoc! {r#"
DELETE FROM "a_table"
WHERE "echo" = 5;
"#}
.trim()
);
}
}