mod compare;
mod condition;
mod projection;
pub use condition::*;
pub use projection::*;
use crate::*;
use std::collections::BTreeSet;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ScalarFilter {
pub projection: ScalarProjection,
pub condition: ScalarCondition,
pub mode: QueryMode,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum QueryMode {
Default,
Insensitive,
}
impl ScalarFilter {
pub fn len(&self) -> usize {
match self.condition {
ScalarCondition::In(ref l) => l.len(),
ScalarCondition::NotIn(ref l) => l.len(),
_ => 1,
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn should_batch(&self, chunk_size: usize) -> bool {
self.len() > chunk_size
}
pub fn can_batch(&self) -> bool {
!matches!(
self.condition,
ScalarCondition::NotContains(_)
| ScalarCondition::NotEquals(_)
| ScalarCondition::NotIn(_)
| ScalarCondition::NotSearch(..)
| ScalarCondition::NotStartsWith(_)
| ScalarCondition::NotEndsWith(_)
)
}
pub fn batched(self, chunk_size: usize) -> Vec<ScalarFilter> {
fn inner(mut list: PrismaListValue, chunk_size: usize) -> Vec<PrismaListValue> {
let dedup_list: BTreeSet<_> = list.drain(..).collect();
let mut batches = Vec::with_capacity(list.len() % chunk_size + 1);
batches.push(Vec::with_capacity(chunk_size));
for (idx, item) in dedup_list.into_iter().enumerate() {
if idx != 0 && idx % chunk_size == 0 {
batches.push(Vec::with_capacity(chunk_size));
}
batches.last_mut().unwrap().push(item);
}
batches
}
let mode = self.mode.clone();
match self.condition {
ScalarCondition::In(ConditionListValue::List(list)) => {
let projection = self.projection;
inner(list, chunk_size)
.into_iter()
.map(|batch| ScalarFilter {
projection: projection.clone(),
condition: ScalarCondition::In(ConditionListValue::list(batch)),
mode: mode.clone(),
})
.collect()
}
ScalarCondition::NotIn(ConditionListValue::List(list)) => {
let projection = self.projection;
inner(list, chunk_size)
.into_iter()
.map(|batch| ScalarFilter {
projection: projection.clone(),
condition: ScalarCondition::NotIn(ConditionListValue::list(batch)),
mode: mode.clone(),
})
.collect()
}
_ => vec![self],
}
}
pub fn as_field_ref(&self) -> Option<&ScalarFieldRef> {
self.condition.as_field_ref()
}
pub fn scalar_fields(&self) -> Vec<&ScalarFieldRef> {
let mut fields = self.projection.scalar_fields();
if let Some(field_ref) = self.as_field_ref() {
fields.push(field_ref);
}
fields
}
pub fn is_unique(&self) -> bool {
if let Some(sf) = self.scalar_ref() {
sf.unique()
} else {
false
}
}
pub fn scalar_ref(&self) -> Option<&ScalarFieldRef> {
self.projection.as_single()
}
}