pub trait QueryFormat {
const ENTITY_FIELDS: &'static [&'static str];
fn row_format(table: &str) -> String {
Self::ENTITY_FIELDS
.iter()
.fold(Vec::new(), |mut agg, r| {
agg.push(format!("{table}.{r}"));
agg
})
.join(", ")
}
fn as_record(table: &str, alias: &str) -> String {
format!("({}) AS {alias}", Self::row_format(table))
}
fn as_embedded_record(table: &str) -> String {
format!("({})", Self::row_format(table))
}
fn as_optional_record(table: &str, alias: &str, check_column: &str) -> String {
format!(
"CASE WHEN {check_column} IS NULL THEN NULL ELSE ({}) END AS {alias}",
Self::row_format(table)
)
}
fn as_embedded_optional_record(table: &str, check_column: &str) -> String {
format!(
"CASE WHEN {check_column} IS NULL THEN NULL ELSE ({}) END",
Self::row_format(table)
)
}
fn insert_query() -> &'static str;
fn table_expression() -> &'static str {
""
}
}
pub trait QueryFormatExt: QueryFormat {
fn as_record_with(table: &str, alias: &str, embeds: &[(&str, String)]) -> String {
embeds
.iter()
.fold(Self::as_record(table, alias), |mut agg, e| {
agg = agg.replace(e.0, &e.1);
agg
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn entity_record_trait_impl() {
#[allow(dead_code)]
struct Foo {
bar: String,
baz_id: i32,
fnord: bool,
}
impl QueryFormat for Foo {
const ENTITY_FIELDS: &'static [&'static str] = &["bar", "fnord", "baz_id"];
fn insert_query() -> &'static str {
"INSERT INTO foo (bar, baz_id, fnord) VALUES ($1, $2, $3)"
}
}
impl QueryFormatExt for Foo {}
#[allow(dead_code)]
struct Blarn {
field1: i32,
field2: Vec<u8>,
}
impl QueryFormat for Blarn {
const ENTITY_FIELDS: &'static [&'static str] = &["field1", "field2"];
fn insert_query() -> &'static str {
""
}
}
let record = Foo::as_record_with(
"ft",
"footable",
&[("ft.bar", Blarn::as_embedded_record("extra"))],
);
assert_eq!(
record,
"((extra.field1, extra.field2), ft.fnord, ft.baz_id) AS footable"
);
assert_eq!(
Foo::as_record("ft", "foo"),
"(ft.bar, ft.fnord, ft.baz_id) AS foo"
);
assert_eq!(
Foo::as_optional_record("ft", "foo", "ft.bar"),
"CASE WHEN ft.bar IS NULL THEN NULL ELSE (ft.bar, ft.fnord, ft.baz_id) END AS foo"
);
}
}