use super::*;
#[doc(hidden)]
#[derive(Clone, Debug)]
#[must_use]
pub struct ColumnList {
pub(crate) items: Vec<SelectItem>,
}
impl ColumnList {
pub(crate) fn one(item: SelectItem) -> Self {
Self { items: vec![item] }
}
}
#[doc(hidden)]
pub trait IntoColumn {
fn into_column(self) -> ColumnList;
}
#[doc(hidden)]
pub trait IntoColumns {
fn into_columns(self) -> ColumnList;
}
impl<T> IntoColumn for Field<T> {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_field(self))
}
}
impl<T> IntoColumn for &Field<T> {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_field(*self))
}
}
impl<T> IntoColumn for FieldRef<T> {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_ref(self))
}
}
impl<T> IntoColumn for &FieldRef<T> {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_ref(self.clone()))
}
}
impl IntoColumn for Meta {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_meta(self))
}
}
impl IntoColumn for &Meta {
fn into_column(self) -> ColumnList {
ColumnList::one(select_item_for_meta(*self))
}
}
impl<T> IntoColumns for Vec<Field<T>> {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_field).collect(),
}
}
}
impl<T> IntoColumns for &[Field<T>] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.iter().copied().map(select_item_for_field).collect(),
}
}
}
impl<T, const N: usize> IntoColumns for [Field<T>; N] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_field).collect(),
}
}
}
impl<T> IntoColumns for Vec<FieldRef<T>> {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_ref).collect(),
}
}
}
impl<T> IntoColumns for &[FieldRef<T>] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.iter().cloned().map(select_item_for_ref).collect(),
}
}
}
impl<T, const N: usize> IntoColumns for [FieldRef<T>; N] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_ref).collect(),
}
}
}
impl IntoColumns for Vec<Meta> {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_meta).collect(),
}
}
}
impl IntoColumns for &[Meta] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.iter().copied().map(select_item_for_meta).collect(),
}
}
}
impl<const N: usize> IntoColumns for [Meta; N] {
fn into_columns(self) -> ColumnList {
ColumnList {
items: self.into_iter().map(select_item_for_meta).collect(),
}
}
}
macro_rules! impl_select_item_tuple {
($($name:ident),+ $(,)?) => {
impl<$($name),+> IntoColumns for ($($name,)+)
where
$($name: IntoColumn,)+
{
#[allow(non_snake_case)]
fn into_columns(self) -> ColumnList {
let ($($name,)+) = self;
let mut items = Vec::new();
$(items.extend($name.into_column().items);)+
ColumnList { items }
}
}
};
}
impl_select_item_tuple!(A, B);
impl_select_item_tuple!(A, B, C);
impl_select_item_tuple!(A, B, C, D);
impl_select_item_tuple!(A, B, C, D, E);
impl_select_item_tuple!(A, B, C, D, E, F);
impl_select_item_tuple!(A, B, C, D, E, F, G);
impl_select_item_tuple!(A, B, C, D, E, F, G, H);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
impl_select_item_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
impl Assignment {
pub fn new<T>(field: Field<T>, value: impl Into<ValueExpr>) -> Self {
Self {
field: *field.meta,
value: crate::AssignmentValue::Expr(value.into()),
}
}
}
impl OrderDirection {
#[inline]
pub const fn as_sql(self) -> &'static str {
match self {
Self::Asc => "ASC",
Self::Desc => "DESC",
}
}
}
impl NullsPosition {
#[inline]
pub const fn as_sql(self) -> &'static str {
match self {
Self::First => "NULLS FIRST",
Self::Last => "NULLS LAST",
}
}
}
impl LockMode {
#[inline]
pub const fn as_sql(self) -> &'static str {
match self {
Self::Update => "FOR UPDATE",
Self::NoKeyUpdate => "FOR NO KEY UPDATE",
Self::Share => "FOR SHARE",
Self::KeyShare => "FOR KEY SHARE",
}
}
}
impl LockWait {
#[inline]
pub const fn as_sql(self) -> Option<&'static str> {
match self {
Self::Wait => None,
Self::NoWait => Some("NOWAIT"),
Self::SkipLocked => Some("SKIP LOCKED"),
}
}
}
impl RowLock {
#[inline]
pub const fn new(mode: LockMode) -> Self {
Self {
mode,
wait: LockWait::Wait,
of: Vec::new(),
}
}
#[inline]
pub const fn nowait(mut self) -> Self {
self.wait = LockWait::NoWait;
self
}
#[inline]
pub const fn skip_locked(mut self) -> Self {
self.wait = LockWait::SkipLocked;
self
}
pub fn of(mut self, relation: impl Into<String>) -> Self {
self.of.push(relation.into());
self
}
}
impl Default for RowLock {
fn default() -> Self {
Self::new(LockMode::Update)
}
}
impl OrderItem {
pub fn asc(expr: impl Into<ValueExpr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Asc,
nulls: None,
}
}
pub fn desc(expr: impl Into<ValueExpr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Desc,
nulls: None,
}
}
#[inline]
pub fn nulls_first(mut self) -> Self {
self.nulls = Some(NullsPosition::First);
self
}
#[inline]
pub fn nulls_last(mut self) -> Self {
self.nulls = Some(NullsPosition::Last);
self
}
pub fn asc_nulls_first(expr: impl Into<ValueExpr>) -> Self {
Self::asc(expr).nulls_first()
}
pub fn asc_nulls_last(expr: impl Into<ValueExpr>) -> Self {
Self::asc(expr).nulls_last()
}
pub fn desc_nulls_first(expr: impl Into<ValueExpr>) -> Self {
Self::desc(expr).nulls_first()
}
pub fn desc_nulls_last(expr: impl Into<ValueExpr>) -> Self {
Self::desc(expr).nulls_last()
}
}
impl GroupByItem {
pub fn expr(expr: impl Into<ValueExpr>) -> Self {
Self::Expr(expr.into())
}
pub fn rollup(exprs: impl IntoIterator<Item = ValueExpr>) -> Self {
Self::Rollup(exprs.into_iter().collect())
}
pub fn cube(exprs: impl IntoIterator<Item = ValueExpr>) -> Self {
Self::Cube(exprs.into_iter().collect())
}
pub fn grouping_sets(sets: impl IntoIterator<Item = Vec<ValueExpr>>) -> Self {
Self::GroupingSets(sets.into_iter().collect())
}
}