use crate::rusqlite::assembler::*;
use crate::sql::Field;
use crate::sql::Table;
use crate::TagCriterium;
impl<T> TagCriterium<T> {
pub fn assemble_rusqlite_query<F: Field, C>(
&self,
assembly_context: &AssemblyContext,
source_field: &F,
dock_prefix: &Prefix,
dock_field: &F,
context: &C,
) -> InvertableRusqliteQuery<F>
where
T: AssembleRusqliteQuery<F, C>,
{
self.assemble_rusqlite_query_as_subquery(
assembly_context,
source_field,
dock_prefix,
dock_field,
context,
)
.as_invertable()
}
fn assemble_rusqlite_query_as_subquery<F: Field, C>(
&self,
assembly_context: &AssemblyContext,
source_field: &F,
dock_prefix: &Prefix,
dock_field: &F,
context: &C,
) -> RusqliteQuery<F>
where
T: AssembleRusqliteQuery<F, C>,
{
let sub_assembly_context = assembly_context.in_subquery_block();
match self {
Self::Has(chain) | Self::HasNot(chain) => {
let subquery = chain
.assemble_rusqlite_query(&sub_assembly_context, context)
.get_corrected_query();
let source_table_alias = source_field
.table()
.sql_safe_prefixed_table_name(sub_assembly_context.prefix());
let operator = if matches!(self, Self::Has(_)) {
"IN"
} else {
"NOT IN"
};
return RusqliteQuery {
used_prefix: dock_prefix.to_string(),
sql_where_clause: format!(
"{} {operator} (
SELECT {}
FROM {} as {source_table_alias}
{}
WHERE {}
)",
dock_field.sql_safe_prefixed_field_name(dock_prefix),
source_field.sql_safe_prefixed_field_name(sub_assembly_context.prefix()),
source_field.table().sql_safe_table_name(),
subquery.joins_to_sql(),
subquery.sql_where_clause
),
sql_joins: vec![],
where_values: subquery.where_values,
};
}
Self::HasNOf { n, chain } => {
let subquery = chain
.assemble_rusqlite_query(&sub_assembly_context, context)
.get_corrected_query();
let source_table_alias = source_field
.table()
.sql_safe_prefixed_table_name(sub_assembly_context.prefix());
return n.assemble_rusqlite_query_with_subquery(
dock_prefix.clone(),
format!(
"(
SELECT COUNT(*)
FROM {} as {source_table_alias}
{}
WHERE {} = {} AND ({})
)",
source_field.table().sql_safe_table_name(),
subquery.joins_to_sql(),
source_field.sql_safe_prefixed_field_name(sub_assembly_context.prefix()),
dock_field.sql_safe_prefixed_field_name(dock_prefix),
subquery.sql_where_clause
)
.as_str(),
subquery.where_values,
);
}
}
}
}