use sqlx::postgres::PgHasArrayType;
use crate::{BindValue, Param};
use super::{BoolExpr, Field, FieldRef, ValueExpr};
impl<T> Field<Vec<T>> {
pub fn overlaps_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.reference().overlaps_expr(values)
}
pub fn contains_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.reference().contains_expr(values)
}
pub fn contained_by_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.reference().contained_by_expr(values)
}
pub fn has_expr(self, value: impl Into<ValueExpr>) -> BoolExpr {
self.reference().has_expr(value)
}
pub fn not_has_expr(self, value: impl Into<ValueExpr>) -> BoolExpr {
self.reference().not_has_expr(value)
}
}
impl<T> Field<Vec<T>>
where
T: BindValue + PgHasArrayType,
{
pub fn overlaps(self, values: Vec<T>) -> BoolExpr {
self.reference().overlaps(values)
}
pub fn contains(self, values: Vec<T>) -> BoolExpr {
self.reference().contains(values)
}
pub fn contained_by(self, values: Vec<T>) -> BoolExpr {
self.reference().contained_by(values)
}
pub fn has(self, value: T) -> BoolExpr {
self.reference().has(value)
}
pub fn not_has(self, value: T) -> BoolExpr {
self.reference().not_has(value)
}
pub fn is_empty(self) -> BoolExpr {
self.reference().is_empty()
}
pub fn is_not_empty(self) -> BoolExpr {
self.reference().is_not_empty()
}
pub fn element(self, index: i32) -> ValueExpr {
self.reference().element(index)
}
pub fn slice(self, start: Option<i32>, end: Option<i32>) -> ValueExpr {
self.reference().slice(start, end)
}
}
impl<T> FieldRef<Vec<T>> {
pub fn overlaps_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.array_expr_infix("&&", values, false)
}
pub fn contains_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.array_expr_infix("@>", values, false)
}
pub fn contained_by_expr(self, values: impl Into<ValueExpr>) -> BoolExpr {
self.array_expr_infix("<@", values, false)
}
pub fn has_expr(self, value: impl Into<ValueExpr>) -> BoolExpr {
self.any_expr_predicate(value, false)
}
pub fn not_has_expr(self, value: impl Into<ValueExpr>) -> BoolExpr {
self.any_expr_predicate(value, true)
}
fn array_expr_infix(
self,
op: &'static str,
values: impl Into<ValueExpr>,
negated: bool,
) -> BoolExpr {
BoolExpr::infix(self.expr(), op, values.into(), negated)
}
fn any_expr_predicate(self, value: impl Into<ValueExpr>, negated: bool) -> BoolExpr {
BoolExpr::any(value.into(), self.expr(), negated)
}
}
impl<T> FieldRef<Vec<T>>
where
T: BindValue + PgHasArrayType,
{
pub fn overlaps(self, values: Vec<T>) -> BoolExpr {
self.array_infix("&&", values, false)
}
pub fn contains(self, values: Vec<T>) -> BoolExpr {
self.array_infix("@>", values, false)
}
pub fn contained_by(self, values: Vec<T>) -> BoolExpr {
self.array_infix("<@", values, false)
}
pub fn has(self, value: T) -> BoolExpr {
self.any_predicate(value, false)
}
pub fn not_has(self, value: T) -> BoolExpr {
self.any_predicate(value, true)
}
pub fn is_empty(self) -> BoolExpr {
BoolExpr::array_is_empty(self.expr(), false)
}
pub fn is_not_empty(self) -> BoolExpr {
BoolExpr::array_is_empty(self.expr(), true)
}
pub fn element(self, index: i32) -> ValueExpr {
ValueExpr::subscript(self.expr(), ValueExpr::Param(Param::typed(index)))
}
pub fn slice(self, start: Option<i32>, end: Option<i32>) -> ValueExpr {
ValueExpr::slice(
self.expr(),
start.map(|value| ValueExpr::Param(Param::typed(value))),
end.map(|value| ValueExpr::Param(Param::typed(value))),
)
}
fn array_infix(self, op: &'static str, values: Vec<T>, negated: bool) -> BoolExpr {
BoolExpr::infix(
self.expr(),
op,
ValueExpr::Param(Param::typed(values)),
negated,
)
}
fn any_predicate(self, value: T, negated: bool) -> BoolExpr {
BoolExpr::any(ValueExpr::Param(Param::typed(value)), self.expr(), negated)
}
}
impl Field<serde_json::Value> {
#[inline]
pub fn contains(self, value: serde_json::Value) -> BoolExpr {
self.reference().contains(value)
}
#[inline]
pub fn contained_by(self, value: serde_json::Value) -> BoolExpr {
self.reference().contained_by(value)
}
pub fn has_key(self, key: impl Into<String>) -> BoolExpr {
self.reference().has_key(key)
}
#[inline]
pub fn has_any_keys(self, keys: Vec<String>) -> BoolExpr {
self.reference().has_any_keys(keys)
}
#[inline]
pub fn has_all_keys(self, keys: Vec<String>) -> BoolExpr {
self.reference().has_all_keys(keys)
}
pub fn get(self, key: impl Into<String>) -> ValueExpr {
self.reference().get(key)
}
pub fn get_text(self, key: impl Into<String>) -> ValueExpr {
self.reference().get_text(key)
}
#[inline]
pub fn path(self, path: Vec<String>) -> ValueExpr {
self.reference().path(path)
}
#[inline]
pub fn path_text(self, path: Vec<String>) -> ValueExpr {
self.reference().path_text(path)
}
}
impl<T> Field<sqlx::postgres::types::PgRange<T>>
where
T: BindValue,
sqlx::postgres::types::PgRange<T>: BindValue,
{
pub fn range_contains(self, value: T) -> BoolExpr {
self.reference().range_contains(value)
}
pub fn contains_range(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().contains_range(value)
}
pub fn contained_by(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().contained_by(value)
}
pub fn overlaps(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().overlaps(value)
}
pub fn adjacent_to(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().adjacent_to(value)
}
pub fn strictly_left_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().strictly_left_of(value)
}
pub fn strictly_right_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().strictly_right_of(value)
}
pub fn does_not_extend_right_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().does_not_extend_right_of(value)
}
pub fn does_not_extend_left_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.reference().does_not_extend_left_of(value)
}
}
impl<T> FieldRef<sqlx::postgres::types::PgRange<T>>
where
T: BindValue,
sqlx::postgres::types::PgRange<T>: BindValue,
{
pub fn range_contains(self, value: T) -> BoolExpr {
BoolExpr::infix(
self.expr(),
"@>",
ValueExpr::Param(Param::typed(value)),
false,
)
}
pub fn contains_range(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("@>", value)
}
pub fn contained_by(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("<@", value)
}
pub fn overlaps(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("&&", value)
}
pub fn adjacent_to(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("-|-", value)
}
pub fn strictly_left_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("<<", value)
}
pub fn strictly_right_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix(">>", value)
}
pub fn does_not_extend_right_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("&<", value)
}
pub fn does_not_extend_left_of(self, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
self.range_infix("&>", value)
}
fn range_infix(self, op: &'static str, value: sqlx::postgres::types::PgRange<T>) -> BoolExpr {
BoolExpr::infix(
self.expr(),
op,
ValueExpr::Param(Param::typed(value)),
false,
)
}
}
impl FieldRef<serde_json::Value> {
#[inline]
pub fn contains(self, value: serde_json::Value) -> BoolExpr {
self.json_infix("@>", Param::typed(value))
}
#[inline]
pub fn contained_by(self, value: serde_json::Value) -> BoolExpr {
self.json_infix("<@", Param::typed(value))
}
pub fn has_key(self, key: impl Into<String>) -> BoolExpr {
self.json_infix("?", Param::typed(key.into()))
}
#[inline]
pub fn has_any_keys(self, keys: Vec<String>) -> BoolExpr {
self.json_infix("?|", Param::typed(keys))
}
#[inline]
pub fn has_all_keys(self, keys: Vec<String>) -> BoolExpr {
self.json_infix("?&", Param::typed(keys))
}
pub fn get(self, key: impl Into<String>) -> ValueExpr {
self.json_value_infix("->", Param::typed(key.into()))
}
pub fn get_text(self, key: impl Into<String>) -> ValueExpr {
self.json_value_infix("->>", Param::typed(key.into()))
}
#[inline]
pub fn path(self, path: Vec<String>) -> ValueExpr {
self.json_value_infix("#>", Param::typed(path))
}
#[inline]
pub fn path_text(self, path: Vec<String>) -> ValueExpr {
self.json_value_infix("#>>", Param::typed(path))
}
fn json_infix(self, op: &'static str, param: Param) -> BoolExpr {
BoolExpr::infix(self.expr(), op, ValueExpr::Param(param), false)
}
fn json_value_infix(self, op: &'static str, param: Param) -> ValueExpr {
ValueExpr::binary(
self.expr(),
super::ValueOp::Custom(op),
ValueExpr::Param(param),
)
}
}