#![allow(clippy::type_complexity)]
use core::marker::PhantomData;
use crate::drizzle_builder_join_impl;
use drizzle_core::ConflictTarget;
use drizzle_core::traits::{SQLModel, SQLTable, ToSQL};
use drizzle_sqlite::{
builder::{
self, CTEView, DeleteInitial, DeleteReturningSet, DeleteWhereSet, InsertDoUpdateSet,
InsertInitial, InsertOnConflictSet, InsertReturningSet, InsertValuesSet, OnConflictBuilder,
QueryBuilder, SelectFromSet, SelectGroupSet, SelectInitial, SelectJoinSet, SelectLimitSet,
SelectOffsetSet, SelectOrderSet, SelectWhereSet, UpdateInitial, UpdateReturningSet,
UpdateSetClauseSet, UpdateWhereSet,
delete::DeleteBuilder,
insert::InsertBuilder,
select::{AsCteState, IntoSelect, SelectBuilder, SelectSetOpSet},
update::UpdateBuilder,
},
common::SQLiteSchemaType,
traits::SQLiteTable,
values::SQLiteValue,
};
#[derive(Debug)]
pub struct DrizzleBuilder<'a, Runner, Schema, Builder, State> {
pub(crate) runner: &'a Runner,
pub(crate) builder: Builder,
pub(crate) state: PhantomData<(Schema, State)>,
}
pub struct DrizzleOnConflictBuilder<'a, 'b, Runner, Schema, Table> {
runner: &'a Runner,
builder: OnConflictBuilder<'b, Schema, Table>,
}
impl<'a, 'b, Runner, Schema, Table> DrizzleOnConflictBuilder<'a, 'b, Runner, Schema, Table> {
pub fn r#where<E>(mut self, condition: E) -> Self
where
E: drizzle_core::expr::Expr<'b, SQLiteValue<'b>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
self.builder = self.builder.r#where(condition);
self
}
pub fn do_nothing(
self,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertOnConflictSet, Table>,
InsertOnConflictSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.do_nothing(),
state: PhantomData,
}
}
pub fn do_update(
self,
set: impl ToSQL<'b, SQLiteValue<'b>>,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertDoUpdateSet, Table>,
InsertDoUpdateSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.do_update(set),
state: PhantomData,
}
}
}
#[cfg(feature = "libsql")]
pub(crate) struct LibsqlCachedStatement {
pub(crate) sql: Box<str>,
pub(crate) statement: ::libsql::Statement,
}
#[cfg(feature = "libsql")]
pub(crate) struct LibsqlStatementCache(pub(crate) std::sync::Mutex<Option<LibsqlCachedStatement>>);
#[cfg(feature = "libsql")]
impl LibsqlStatementCache {
pub(crate) const fn new() -> Self {
Self(std::sync::Mutex::new(None))
}
pub(crate) fn take(&self, sql: &str) -> Option<LibsqlCachedStatement> {
let mut cache = self.0.lock().unwrap_or_else(|err| err.into_inner());
if cache
.as_ref()
.is_some_and(|cached| cached.sql.as_ref() == sql)
{
cache.take()
} else {
None
}
}
pub(crate) fn store(&self, cached: LibsqlCachedStatement) {
let mut cache = self.0.lock().unwrap_or_else(|err| err.into_inner());
*cache = Some(cached);
}
}
#[cfg(feature = "libsql")]
impl Clone for LibsqlStatementCache {
fn clone(&self) -> Self {
Self::new()
}
}
#[cfg(feature = "libsql")]
impl Default for LibsqlStatementCache {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "libsql")]
impl core::fmt::Debug for LibsqlStatementCache {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("LibsqlStatementCache")
.finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct Drizzle<Conn, Schema = ()> {
pub(crate) conn: Conn,
pub(crate) schema: Schema,
#[cfg(feature = "libsql")]
pub(crate) libsql_statement_cache: LibsqlStatementCache,
}
impl<Conn: Clone, S: Clone> Clone for Drizzle<Conn, S> {
#[inline]
fn clone(&self) -> Self {
Self {
conn: self.conn.clone(),
schema: self.schema.clone(),
#[cfg(feature = "libsql")]
libsql_statement_cache: self.libsql_statement_cache.clone(),
}
}
}
impl<Conn> Drizzle<Conn> {
#[inline]
pub const fn new<S: Copy>(conn: Conn, schema: S) -> (Drizzle<Conn, S>, S) {
let drizzle = Drizzle {
conn,
schema,
#[cfg(feature = "libsql")]
libsql_statement_cache: LibsqlStatementCache::new(),
};
(drizzle, schema)
}
}
impl<Conn, S> AsRef<Self> for Drizzle<Conn, S> {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl<Conn, Schema> Drizzle<Conn, Schema> {
#[inline]
pub const fn conn(&self) -> &Conn {
&self.conn
}
#[inline]
pub const fn conn_mut(&mut self) -> &mut Conn {
&mut self.conn
}
#[inline]
pub const fn schema(&self) -> &Schema {
&self.schema
}
#[cfg(feature = "sqlite")]
pub fn select<'a, 'b, T>(
&'a self,
query: T,
) -> DrizzleBuilder<
'a,
Self,
Schema,
SelectBuilder<'b, Schema, drizzle_sqlite::builder::select::SelectInitial, (), T::Marker>,
drizzle_sqlite::builder::select::SelectInitial,
>
where
T: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
{
let builder = QueryBuilder::new::<Schema>().select(query);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
#[cfg(feature = "sqlite")]
pub fn select_distinct<'a, 'b, T>(
&'a self,
query: T,
) -> DrizzleBuilder<
'a,
Self,
Schema,
SelectBuilder<'b, Schema, drizzle_sqlite::builder::select::SelectInitial, (), T::Marker>,
drizzle_sqlite::builder::select::SelectInitial,
>
where
T: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
{
let builder = QueryBuilder::new::<Schema>().select_distinct(query);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
#[cfg(feature = "sqlite")]
pub fn insert<'a, 'b, Table>(
&'a self,
table: Table,
) -> DrizzleBuilder<
'a,
Self,
Schema,
InsertBuilder<'b, Schema, drizzle_sqlite::builder::insert::InsertInitial, Table>,
drizzle_sqlite::builder::insert::InsertInitial,
>
where
Table: SQLiteTable<'b>,
{
let builder = QueryBuilder::new::<Schema>().insert(table);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
#[cfg(feature = "sqlite")]
pub fn update<'a, 'b, Table>(
&'a self,
table: Table,
) -> DrizzleBuilder<
'a,
Self,
Schema,
UpdateBuilder<'b, Schema, drizzle_sqlite::builder::update::UpdateInitial, Table>,
drizzle_sqlite::builder::update::UpdateInitial,
>
where
Table: SQLiteTable<'b>,
{
let builder = QueryBuilder::new::<Schema>().update(table);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
#[cfg(feature = "sqlite")]
pub fn delete<'a, 'b, Table>(
&'a self,
table: Table,
) -> DrizzleBuilder<
'a,
Self,
Schema,
DeleteBuilder<'b, Schema, drizzle_sqlite::builder::delete::DeleteInitial, Table>,
drizzle_sqlite::builder::delete::DeleteInitial,
>
where
Table: SQLiteTable<'b>,
{
let builder = QueryBuilder::new::<Schema>().delete(table);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
#[cfg(feature = "sqlite")]
pub fn with<'a, 'b, C>(
&'a self,
cte: &C,
) -> DrizzleBuilder<
'a,
Self,
Schema,
QueryBuilder<'b, Schema, builder::CTEInit>,
builder::CTEInit,
>
where
C: builder::CTEDefinition<'b>,
{
let builder = QueryBuilder::new::<Schema>().with(cte);
DrizzleBuilder {
runner: self,
builder,
state: PhantomData,
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
pub struct DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels = (),
Cols = drizzle_core::query::AllColumns,
Cl = drizzle_core::query::Clauses,
> {
pub(crate) runner: &'db Drizzle<Conn, Schema>,
pub(crate) builder: drizzle_core::query::QueryBuilder<'a, SQLiteValue<'a>, T, Rels, Cols, Cl>,
}
#[cfg(all(feature = "sqlite", feature = "query"))]
#[derive(Debug, Clone)]
pub struct DrizzlePreparedQuery<'a, Driver, T, Rels, Cols> {
pub(crate) inner: drizzle_core::prepared::PreparedStatement<'a, SQLiteValue<'a>>,
pub(crate) _marker: PhantomData<(Driver, T, Rels, Cols)>,
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'a, Driver, T, Rels, Cols> DrizzlePreparedQuery<'a, Driver, T, Rels, Cols> {
#[must_use]
pub fn sql(&self) -> &str {
self.inner.sql()
}
#[must_use]
pub fn param_count(&self) -> usize {
self.inner.external_param_count()
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<Driver, T, Rels, Cols> core::fmt::Display for DrizzlePreparedQuery<'_, Driver, T, Rels, Cols> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.sql())
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<Conn, Schema> Drizzle<Conn, Schema> {
pub fn query<'a, T>(&self, _table: T) -> DrizzleQueryBuilder<'_, 'a, Conn, Schema, T>
where
T: drizzle_core::query::QueryTable,
{
DrizzleQueryBuilder {
runner: self,
builder: drizzle_core::query::QueryBuilder::new(),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cl>
DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, drizzle_core::query::AllColumns, Cl>
where
T: drizzle_core::query::QueryTable,
Rels: drizzle_core::query::RenderRelations<'a, SQLiteValue<'a>>,
{
pub fn prepare(
self,
) -> DrizzlePreparedQuery<'a, Conn, T, Rels, drizzle_core::query::AllColumns> {
let builder = self.builder;
let mut rendered = Vec::new();
builder.relations.render_into(&mut rendered);
let query_sql = drizzle_core::query::build_query_sql(
T::TABLE_NAME,
T::COLUMN_NAMES,
T::BLOB_COLUMNS,
rendered,
builder.where_sql,
builder.order_by_sql,
builder.limit,
builder.offset,
false,
);
DrizzlePreparedQuery {
inner: drizzle_core::prepared::prepare_render(&query_sql),
_marker: PhantomData,
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cl>
DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, drizzle_core::query::PartialColumns, Cl>
where
T: drizzle_core::query::QueryTable,
Rels: drizzle_core::query::RenderRelations<'a, SQLiteValue<'a>>,
{
pub fn prepare(
self,
) -> DrizzlePreparedQuery<'a, Conn, T, Rels, drizzle_core::query::PartialColumns> {
let builder = self.builder;
let mut rendered = Vec::new();
builder.relations.render_into(&mut rendered);
let col_refs: Vec<&str> = builder.cols.columns;
let query_sql = drizzle_core::query::build_query_sql(
T::TABLE_NAME,
&col_refs,
T::BLOB_COLUMNS,
rendered,
builder.where_sql,
builder.order_by_sql,
builder.limit,
builder.offset,
true,
);
DrizzlePreparedQuery {
inner: drizzle_core::prepared::prepare_render(&query_sql),
_marker: PhantomData,
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cols, Cl>
DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, Cols, Cl>
{
#[allow(clippy::type_complexity)]
pub fn with<R, N, C, RCl>(
self,
handle: drizzle_core::query::RelationHandle<'a, SQLiteValue<'a>, R, N, C, RCl>,
) -> DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
(
drizzle_core::query::RelationHandle<'a, SQLiteValue<'a>, R, N, C, RCl>,
Rels,
),
Cols,
Cl,
>
where
R: drizzle_core::relation::RelationDef<Source = T> + 'static,
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.with(handle),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cols, Ord, Lim>
DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<drizzle_core::query::NoWhere, Ord, Lim>,
>
{
pub fn r#where<E>(
self,
condition: E,
) -> DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<drizzle_core::query::HasWhere, Ord, Lim>,
>
where
E: drizzle_core::expr::Expr<'a, SQLiteValue<'a>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.r#where(condition),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cols, W, Lim>
DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, drizzle_core::query::NoOrderBy, Lim>,
>
{
pub fn order_by<E>(
self,
expr: E,
) -> DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, drizzle_core::query::HasOrderBy, Lim>,
>
where
E: drizzle_core::traits::ToSQL<'a, SQLiteValue<'a>>,
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.order_by(expr),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cols, W, Ord>
DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, Ord, drizzle_core::query::NoLimit>,
>
{
pub fn limit<P>(
self,
n: P,
) -> DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, Ord, drizzle_core::query::HasLimit>,
>
where
P: drizzle_core::PaginationArg<'a, SQLiteValue<'a>>,
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.limit(n),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cols, W, Ord>
DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, Ord, drizzle_core::query::HasLimit>,
>
{
pub fn offset<P>(
self,
n: P,
) -> DrizzleQueryBuilder<
'db,
'a,
Conn,
Schema,
T,
Rels,
Cols,
drizzle_core::query::Clauses<W, Ord, drizzle_core::query::HasOffset>,
>
where
P: drizzle_core::PaginationArg<'a, SQLiteValue<'a>>,
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.offset(n),
}
}
}
#[cfg(all(feature = "sqlite", feature = "query"))]
impl<'db, 'a, Conn, Schema, T, Rels, Cl>
DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, drizzle_core::query::AllColumns, Cl>
where
T: drizzle_core::query::QueryTable,
{
pub fn columns<S: drizzle_core::query::IntoColumnSelection>(
self,
selector: S,
) -> DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, drizzle_core::query::PartialColumns, Cl>
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.columns(selector),
}
}
pub fn omit<S: drizzle_core::query::IntoColumnSelection>(
self,
selector: S,
) -> DrizzleQueryBuilder<'db, 'a, Conn, Schema, T, Rels, drizzle_core::query::PartialColumns, Cl>
{
DrizzleQueryBuilder {
runner: self.runner,
builder: self.builder.omit(selector),
}
}
}
impl<'a, Runner, S, T, State> ToSQL<'a, SQLiteValue<'a>> for DrizzleBuilder<'_, Runner, S, T, State>
where
T: ToSQL<'a, SQLiteValue<'a>>,
{
fn to_sql(&self) -> drizzle_core::sql::SQL<'a, SQLiteValue<'a>> {
self.builder.to_sql()
}
}
impl<'a, Runner, S, T, State> drizzle_core::expr::Expr<'a, SQLiteValue<'a>>
for DrizzleBuilder<'_, Runner, S, T, State>
where
T: drizzle_core::expr::Expr<'a, SQLiteValue<'a>>,
{
type SQLType = T::SQLType;
type Nullable = T::Nullable;
type Aggregate = T::Aggregate;
}
impl<'d, 'a, Runner, Schema>
DrizzleBuilder<'d, Runner, Schema, QueryBuilder<'a, Schema, builder::CTEInit>, builder::CTEInit>
{
#[inline]
pub fn select<T>(
self,
query: T,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, builder::select::SelectInitial, (), T::Marker>,
builder::select::SelectInitial,
>
where
T: ToSQL<'a, SQLiteValue<'a>> + drizzle_core::IntoSelectTarget,
{
let builder = self.builder.select(query);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
#[inline]
pub fn select_distinct<T>(
self,
query: T,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, builder::select::SelectInitial, (), T::Marker>,
builder::select::SelectInitial,
>
where
T: ToSQL<'a, SQLiteValue<'a>> + drizzle_core::IntoSelectTarget,
{
let builder = self.builder.select_distinct(query);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
#[inline]
pub fn with<C>(self, cte: &C) -> Self
where
C: builder::CTEDefinition<'a>,
{
let builder = self.builder.with(cte);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'d, 'a, Runner, Schema, M>
DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectInitial, (), M>,
SelectInitial,
>
{
#[inline]
pub fn from<T>(
self,
table: T,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<
'a,
Schema,
SelectFromSet,
T,
drizzle_core::Scoped<M, drizzle_core::Cons<T, drizzle_core::Nil>>,
<M as drizzle_core::ResolveRow<T>>::Row,
>,
SelectFromSet,
>
where
T: ToSQL<'a, SQLiteValue<'a>>,
M: drizzle_core::ResolveRow<T>,
{
let builder = self.builder.from(table);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
macro_rules! impl_select_methods {
($($state:ty => [$($method:ident),* $(,)?]),+ $(,)?) => {
$(
impl<'d, 'a, Runner, Schema, T, M, R, G>
DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, $state, T, M, R, G>, $state>
{
$( impl_select_methods!(@method $method); )*
}
)+
};
(@method r#where) => {
#[inline]
pub fn r#where<E>(
self,
condition: E,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectWhereSet, T, M, R, G>, SelectWhereSet>
where
E: drizzle_core::expr::Expr<'a, SQLiteValue<'a>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
let builder = self.builder.r#where(condition);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method group_by) => {
pub fn group_by<Gr>(
self,
columns: Gr,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectGroupSet, T, M, R, Gr::Columns>, SelectGroupSet>
where
Gr: drizzle_core::IntoGroupBy<'a, SQLiteValue<'a>>,
{
let builder = self.builder.group_by(columns);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method having) => {
pub fn having<E>(
self,
condition: E,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectGroupSet, T, M, R, G>, SelectGroupSet>
where
E: drizzle_core::expr::Expr<'a, SQLiteValue<'a>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
let builder = self.builder.having(condition);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method order_by) => {
pub fn order_by<TOrderBy>(
self,
expressions: TOrderBy,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectOrderSet, T, M, R, G>, SelectOrderSet>
where
TOrderBy: drizzle_core::traits::ToSQL<'a, SQLiteValue<'a>>,
{
let builder = self.builder.order_by(expressions);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method limit) => {
pub fn limit<P>(
self,
limit: P,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectLimitSet, T, M, R, G>, SelectLimitSet>
where
P: drizzle_core::PaginationArg<'a, SQLiteValue<'a>>,
{
let builder = self.builder.limit(limit);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method offset) => {
pub fn offset<P>(
self,
offset: P,
) -> DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, SelectOffsetSet, T, M, R, G>, SelectOffsetSet>
where
P: drizzle_core::PaginationArg<'a, SQLiteValue<'a>>,
{
let builder = self.builder.offset(offset);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
};
(@method join) => {
#[inline]
pub fn join<J: drizzle_sqlite::helpers::JoinArg<'a, T>>(
self,
arg: J,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<
'a,
Schema,
SelectJoinSet,
J::JoinedTable,
<M as drizzle_core::ScopePush<J::JoinedTable>>::Out,
<M as drizzle_core::AfterJoin<R, J::JoinedTable>>::NewRow,
G,
>,
SelectJoinSet,
>
where
M: drizzle_core::AfterJoin<R, J::JoinedTable> + drizzle_core::ScopePush<J::JoinedTable>,
{
let builder = self.builder.join(arg);
DrizzleBuilder { runner: self.runner, builder, state: PhantomData }
}
crate::drizzle_builder_join_impl!();
};
}
impl_select_methods! {
SelectFromSet => [r#where, group_by, order_by, limit, offset, join],
SelectJoinSet => [r#where, group_by, order_by, join],
SelectWhereSet => [group_by, order_by, limit],
SelectGroupSet => [having, order_by, limit],
SelectOrderSet => [limit],
SelectLimitSet => [offset],
SelectSetOpSet => [order_by, limit, offset],
}
impl<'a, Runner, Schema, State, T, M, R, G> IntoSelect<'a, Schema, M, R>
for DrizzleBuilder<'_, Runner, Schema, SelectBuilder<'a, Schema, State, T, M, R, G>, State>
where
State: drizzle_sqlite::builder::ExecutableState,
{
type State = State;
type Table = T;
fn into_select(self) -> SelectBuilder<'a, Schema, State, T, M, R> {
self.builder.into_select()
}
}
impl<'d, 'a, Runner, Schema, State, T, M, R>
DrizzleBuilder<'d, Runner, Schema, SelectBuilder<'a, Schema, State, T, M, R>, State>
where
State: drizzle_sqlite::builder::ExecutableState,
{
pub fn union(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.union(other),
state: PhantomData,
}
}
pub fn union_all(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.union_all(other),
state: PhantomData,
}
}
pub fn intersect(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.intersect(other),
state: PhantomData,
}
}
pub fn intersect_all(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.intersect_all(other),
state: PhantomData,
}
}
pub fn except(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.except(other),
state: PhantomData,
}
}
pub fn except_all(
self,
other: impl IntoSelect<'a, Schema, M, R>,
) -> DrizzleBuilder<
'd,
Runner,
Schema,
SelectBuilder<'a, Schema, SelectSetOpSet, T, M, R>,
SelectSetOpSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.except_all(other),
state: PhantomData,
}
}
}
impl<Runner, Schema, State, T, M, R, G>
DrizzleBuilder<'_, Runner, Schema, QueryBuilder<'_, Schema, State, T, M, R, G>, State>
where
State: drizzle_sqlite::builder::ExecutableState,
{
#[inline]
pub fn comment(self, text: impl AsRef<str>) -> Self {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.comment(text),
state: PhantomData,
}
}
#[inline]
pub fn comment_tags<I, K, V>(self, pairs: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<str>,
V: AsRef<str>,
{
DrizzleBuilder {
runner: self.runner,
builder: self.builder.comment_tags(pairs),
state: PhantomData,
}
}
}
impl<'a, Runner, Schema, State, T, M, R>
DrizzleBuilder<'_, Runner, Schema, SelectBuilder<'a, Schema, State, T, M, R>, State>
where
State: AsCteState,
T: SQLTable<'a, SQLiteSchemaType, SQLiteValue<'a>>,
{
#[inline]
pub fn into_cte<Tag: drizzle_core::Tag + 'static>(
self,
) -> CTEView<
'a,
<T as SQLTable<'a, SQLiteSchemaType, SQLiteValue<'a>>>::Aliased<Tag>,
SelectBuilder<'a, Schema, State, T, M, R>,
> {
self.builder.into_cte::<Tag>()
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertInitial, Table>,
InsertInitial,
>
{
#[inline]
pub fn value<T>(
self,
value: Table::Insert<T>,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertValuesSet, Table>,
InsertValuesSet,
>
where
Table: SQLiteTable<'b>,
Table::Insert<T>: SQLModel<'b, SQLiteValue<'b>>,
{
self.values([value])
}
#[inline]
pub fn values<T>(
self,
values: impl IntoIterator<Item = Table::Insert<T>>,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertValuesSet, Table>,
InsertValuesSet,
>
where
Table: SQLiteTable<'b>,
Table::Insert<T>: SQLModel<'b, SQLiteValue<'b>>,
{
let builder = self.builder.values(values);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
#[inline]
pub fn select<Q>(
self,
query: Q,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertValuesSet, Table>,
InsertValuesSet,
>
where
Table: SQLiteTable<'b>,
Q: ToSQL<'b, SQLiteValue<'b>>,
{
let builder = self.builder.select(query);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertValuesSet, Table>,
InsertValuesSet,
>
where
Table: SQLiteTable<'b>,
{
pub fn on_conflict<C: ConflictTarget<Table>>(
self,
target: C,
) -> DrizzleOnConflictBuilder<'a, 'b, Runner, Schema, Table> {
DrizzleOnConflictBuilder {
runner: self.runner,
builder: self.builder.on_conflict(target),
}
}
pub fn on_conflict_do_nothing(
self,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertOnConflictSet, Table>,
InsertOnConflictSet,
> {
DrizzleBuilder {
runner: self.runner,
builder: self.builder.on_conflict_do_nothing(),
state: PhantomData,
}
}
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<
'b,
Schema,
InsertReturningSet,
Table,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<Table, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<Table>>::Row,
>,
InsertReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<Table>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertOnConflictSet, Table>,
InsertOnConflictSet,
>
{
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<
'b,
Schema,
InsertReturningSet,
Table,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<Table, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<Table>>::Row,
>,
InsertReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<Table>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertDoUpdateSet, Table>,
InsertDoUpdateSet,
>
{
pub fn r#where<E>(
self,
condition: E,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<'b, Schema, InsertOnConflictSet, Table>,
InsertOnConflictSet,
>
where
E: drizzle_core::expr::Expr<'b, SQLiteValue<'b>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
DrizzleBuilder {
runner: self.runner,
builder: self.builder.r#where(condition),
state: PhantomData,
}
}
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
InsertBuilder<
'b,
Schema,
InsertReturningSet,
Table,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<Table, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<Table>>::Row,
>,
InsertReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<Table>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<'b, Schema, UpdateInitial, Table>,
UpdateInitial,
>
where
Table: SQLiteTable<'b>,
{
#[inline]
pub fn set(
self,
values: Table::Update,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<'b, Schema, UpdateSetClauseSet, Table>,
UpdateSetClauseSet,
> {
let builder = self.builder.set(values);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<'b, Schema, UpdateSetClauseSet, Table>,
UpdateSetClauseSet,
>
{
pub fn r#where<E>(
self,
condition: E,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<'b, Schema, UpdateWhereSet, Table>,
UpdateWhereSet,
>
where
E: drizzle_core::expr::Expr<'b, SQLiteValue<'b>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
let builder = self.builder.r#where(condition);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<
'b,
Schema,
UpdateReturningSet,
Table,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<Table, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<Table>>::Row,
>,
UpdateReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<Table>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, Table>
DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<'b, Schema, UpdateWhereSet, Table>,
UpdateWhereSet,
>
{
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
UpdateBuilder<
'b,
Schema,
UpdateReturningSet,
Table,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<Table, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<Table>>::Row,
>,
UpdateReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<Table>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, T>
DrizzleBuilder<'a, Runner, Schema, DeleteBuilder<'b, Schema, DeleteInitial, T>, DeleteInitial>
where
T: SQLiteTable<'b>,
{
pub fn r#where<E>(
self,
condition: E,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
DeleteBuilder<'b, Schema, DeleteWhereSet, T>,
DeleteWhereSet,
>
where
E: drizzle_core::expr::Expr<'b, SQLiteValue<'b>>,
E::SQLType: drizzle_core::types::BooleanLike,
{
let builder = self.builder.r#where(condition);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
DeleteBuilder<
'b,
Schema,
DeleteReturningSet,
T,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<T, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<T>>::Row,
>,
DeleteReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<T>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}
impl<'a, 'b, Runner, Schema, T>
DrizzleBuilder<'a, Runner, Schema, DeleteBuilder<'b, Schema, DeleteWhereSet, T>, DeleteWhereSet>
{
pub fn returning<Columns>(
self,
columns: Columns,
) -> DrizzleBuilder<
'a,
Runner,
Schema,
DeleteBuilder<
'b,
Schema,
DeleteReturningSet,
T,
drizzle_core::Scoped<Columns::Marker, drizzle_core::Cons<T, drizzle_core::Nil>>,
<Columns::Marker as drizzle_core::ResolveRow<T>>::Row,
>,
DeleteReturningSet,
>
where
Columns: ToSQL<'b, SQLiteValue<'b>> + drizzle_core::IntoSelectTarget,
Columns::Marker: drizzle_core::ResolveRow<T>,
{
let builder = self.builder.returning(columns);
DrizzleBuilder {
runner: self.runner,
builder,
state: PhantomData,
}
}
}