use std::borrow::Cow;
use std::sync::Arc;
use rorm_db::sql::value;
pub mod collections;
mod r#in;
pub use collections::{DynamicCollection, StaticCollection};
pub use r#in::{In, InOperator};
use crate::fields::proxy::{FieldProxy, FieldProxyImpl};
use crate::internal::field::Field;
use crate::internal::query_context::flat_conditions::FlatCondition;
use crate::internal::query_context::ConditionBuilder;
pub trait Condition<'a>: Send + Sync {
fn build(&self, builder: ConditionBuilder<'_, 'a>);
fn boxed<'this>(self) -> Box<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
Box::new(self)
}
fn arc<'this>(self) -> Arc<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
Arc::new(self)
}
}
impl<'a> Condition<'a> for Box<dyn Condition<'a> + '_> {
fn build(&self, builder: ConditionBuilder<'_, 'a>) {
self.as_ref().build(builder);
}
fn boxed<'this>(self) -> Box<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
self
}
fn arc<'this>(self) -> Arc<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
Arc::from(self)
}
}
impl<'a> Condition<'a> for Arc<dyn Condition<'a> + '_> {
fn build(&self, builder: ConditionBuilder<'_, 'a>) {
self.as_ref().build(builder);
}
fn boxed<'this>(self) -> Box<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
Box::from(self)
}
fn arc<'this>(self) -> Arc<dyn Condition<'a> + 'this>
where
Self: Sized + 'this,
{
self
}
}
impl<'a, C: Condition<'a> + ?Sized> Condition<'a> for &'_ C {
fn build(&self, builder: ConditionBuilder<'_, 'a>) {
<C as Condition<'a>>::build(*self, builder);
}
}
#[derive(Clone, Debug)]
pub enum Value<'a> {
Null(value::NullType),
String(Cow<'a, str>),
Choice(Cow<'a, str>),
I64(i64),
I32(i32),
I16(i16),
Bool(bool),
F64(f64),
F32(f32),
Binary(Cow<'a, [u8]>),
#[cfg(feature = "chrono")]
ChronoNaiveTime(chrono::NaiveTime),
#[cfg(feature = "chrono")]
ChronoNaiveDate(chrono::NaiveDate),
#[cfg(feature = "chrono")]
ChronoNaiveDateTime(chrono::NaiveDateTime),
#[cfg(feature = "chrono")]
ChronoDateTime(chrono::DateTime<chrono::Utc>),
#[cfg(feature = "time")]
TimeDate(time::Date),
#[cfg(feature = "time")]
TimeTime(time::Time),
#[cfg(feature = "time")]
TimeOffsetDateTime(time::OffsetDateTime),
#[cfg(feature = "time")]
TimePrimitiveDateTime(time::PrimitiveDateTime),
#[cfg(feature = "uuid")]
Uuid(uuid::Uuid),
#[cfg(feature = "postgres-only")]
MacAddress(mac_address::MacAddress),
#[cfg(feature = "postgres-only")]
IpNetwork(ipnetwork::IpNetwork),
#[cfg(feature = "postgres-only")]
BitVec(Cow<'a, bit_vec::BitVec>),
}
impl Value<'_> {
pub fn as_sql(&self) -> value::Value<'_> {
match self {
Value::Null(null_type) => value::Value::Null(*null_type),
Value::String(v) => value::Value::String(v.as_ref()),
Value::Choice(v) => value::Value::Choice(v.as_ref()),
Value::I64(v) => value::Value::I64(*v),
Value::I32(v) => value::Value::I32(*v),
Value::I16(v) => value::Value::I16(*v),
Value::Bool(v) => value::Value::Bool(*v),
Value::F64(v) => value::Value::F64(*v),
Value::F32(v) => value::Value::F32(*v),
Value::Binary(v) => value::Value::Binary(v.as_ref()),
#[cfg(feature = "chrono")]
Value::ChronoNaiveTime(v) => value::Value::ChronoNaiveTime(*v),
#[cfg(feature = "chrono")]
Value::ChronoNaiveDate(v) => value::Value::ChronoNaiveDate(*v),
#[cfg(feature = "chrono")]
Value::ChronoNaiveDateTime(v) => value::Value::ChronoNaiveDateTime(*v),
#[cfg(feature = "chrono")]
Value::ChronoDateTime(v) => value::Value::ChronoDateTime(*v),
#[cfg(feature = "time")]
Value::TimeDate(v) => value::Value::TimeDate(*v),
#[cfg(feature = "time")]
Value::TimeTime(v) => value::Value::TimeTime(*v),
#[cfg(feature = "time")]
Value::TimeOffsetDateTime(v) => value::Value::TimeOffsetDateTime(*v),
#[cfg(feature = "time")]
Value::TimePrimitiveDateTime(v) => value::Value::TimePrimitiveDateTime(*v),
#[cfg(feature = "uuid")]
Value::Uuid(v) => value::Value::Uuid(*v),
#[cfg(feature = "postgres-only")]
Value::MacAddress(v) => value::Value::MacAddress(*v),
#[cfg(feature = "postgres-only")]
Value::IpNetwork(v) => value::Value::IpNetwork(*v),
#[cfg(feature = "postgres-only")]
Value::BitVec(v) => value::Value::BitVec(v.as_ref()),
}
}
}
impl<'c, 'v: 'c> Condition<'c> for Value<'v> {
fn build(&self, mut builder: ConditionBuilder<'_, 'c>) {
let value_index = builder.push_value(self.clone());
builder.push_condition(FlatCondition::Value(value_index));
}
}
#[derive(Copy, Clone)]
pub struct Column<I: FieldProxyImpl>(pub FieldProxy<I>);
impl<'a, I: FieldProxyImpl> Condition<'a> for Column<I> {
fn build(&self, mut builder: ConditionBuilder<'_, 'a>) {
let path_id = builder.add_path::<I::Path>();
builder.push_condition(FlatCondition::Column(path_id, &<I::Field as Field>::NAME));
}
}
#[derive(Copy, Clone)]
pub struct Binary<A, B> {
pub operator: BinaryOperator,
pub fst_arg: A,
pub snd_arg: B,
}
#[derive(Copy, Clone, Debug)]
pub enum BinaryOperator {
Equals,
NotEquals,
Greater,
GreaterOrEquals,
Less,
LessOrEquals,
Like,
NotLike,
Regexp,
NotRegexp,
#[cfg(feature = "postgres-only")]
ILike,
#[cfg(feature = "postgres-only")]
NotILike,
#[cfg(feature = "postgres-only")]
Contained,
#[cfg(feature = "postgres-only")]
ContainedOrEquals,
#[cfg(feature = "postgres-only")]
Contains,
#[cfg(feature = "postgres-only")]
ContainsOrEquals,
}
impl<'a, A: Condition<'a>, B: Condition<'a>> Condition<'a> for Binary<A, B> {
fn build(&self, mut builder: ConditionBuilder<'_, 'a>) {
builder.push_condition(FlatCondition::BinaryCondition(self.operator));
self.fst_arg.build(builder.reborrow());
self.snd_arg.build(builder.reborrow());
}
}
#[derive(Copy, Clone)]
pub struct Ternary<A, B, C> {
pub operator: TernaryOperator,
pub fst_arg: A,
pub snd_arg: B,
pub trd_arg: C,
}
#[derive(Copy, Clone, Debug)]
pub enum TernaryOperator {
Between,
NotBetween,
}
impl<'a, A: Condition<'a>, B: Condition<'a>, C: Condition<'a>> Condition<'a> for Ternary<A, B, C> {
fn build(&self, mut builder: ConditionBuilder<'_, 'a>) {
builder.push_condition(FlatCondition::TernaryCondition(self.operator));
self.fst_arg.build(builder.reborrow());
self.snd_arg.build(builder.reborrow());
self.trd_arg.build(builder.reborrow());
}
}
#[derive(Copy, Clone)]
pub struct Unary<A> {
pub operator: UnaryOperator,
pub fst_arg: A,
}
#[derive(Copy, Clone, Debug)]
pub enum UnaryOperator {
IsNull,
IsNotNull,
Exists,
NotExists,
Not,
}
impl<'a, A: Condition<'a>> Condition<'a> for Unary<A> {
fn build(&self, mut builder: ConditionBuilder<'_, 'a>) {
builder.push_condition(FlatCondition::UnaryCondition(self.operator));
self.fst_arg.build(builder.reborrow());
}
}