use std::marker::PhantomData;
use backend::Backend;
use expression::*;
use query_builder::*;
use query_dsl::RunQueryDsl;
use result::QueryResult;
#[derive(Debug, Clone, DieselNumericOps)]
#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
pub struct SqlLiteral<ST, T = ()> {
sql: String,
inner: T,
_marker: PhantomData<ST>,
}
impl<ST, T> SqlLiteral<ST, T> {
#[doc(hidden)]
pub fn new(sql: String, inner: T) -> Self {
SqlLiteral {
sql: sql,
inner: inner,
_marker: PhantomData,
}
}
pub fn bind<BindST, U>(self, bind_value: U) -> UncheckedBind<Self, U::Expression>
where
U: AsExpression<BindST>,
{
UncheckedBind::new(self, bind_value.as_expression())
}
pub fn sql(self, sql: &str) -> SqlLiteral<ST, Self> {
SqlLiteral::new(sql.into(), self)
}
}
impl<ST, T> Expression for SqlLiteral<ST, T> {
type SqlType = ST;
}
impl<ST, T, DB> QueryFragment<DB> for SqlLiteral<ST, T>
where
DB: Backend,
T: QueryFragment<DB>,
{
fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
out.unsafe_to_cache_prepared();
self.inner.walk_ast(out.reborrow())?;
out.push_sql(&self.sql);
Ok(())
}
}
impl<ST, T> QueryId for SqlLiteral<ST, T> {
type QueryId = ();
const HAS_STATIC_QUERY_ID: bool = false;
}
impl<ST, T> Query for SqlLiteral<ST, T> {
type SqlType = ST;
}
impl<ST, T, Conn> RunQueryDsl<Conn> for SqlLiteral<ST, T> {}
impl<QS, ST, T> SelectableExpression<QS> for SqlLiteral<ST, T> {}
impl<QS, ST, T> AppearsOnTable<QS> for SqlLiteral<ST, T> {}
impl<ST, T> NonAggregate for SqlLiteral<ST, T> {}
pub fn sql<ST>(sql: &str) -> SqlLiteral<ST> {
SqlLiteral::new(sql.into(), ())
}
#[derive(QueryId, Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
pub struct UncheckedBind<Query, Value> {
query: Query,
value: Value,
}
impl<Query, Value> UncheckedBind<Query, Value>
where
Query: Expression,
{
pub(crate) fn new(query: Query, value: Value) -> Self {
UncheckedBind { query, value }
}
pub fn sql(self, sql: &str) -> SqlLiteral<Query::SqlType, Self> {
SqlLiteral::new(sql.into(), self)
}
}
impl<Query, Value> Expression for UncheckedBind<Query, Value>
where
Query: Expression,
{
type SqlType = Query::SqlType;
}
impl<Query, Value, DB> QueryFragment<DB> for UncheckedBind<Query, Value>
where
DB: Backend,
Query: QueryFragment<DB>,
Value: QueryFragment<DB>,
{
fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
self.query.walk_ast(out.reborrow())?;
self.value.walk_ast(out.reborrow())?;
Ok(())
}
}
impl<Q, Value> Query for UncheckedBind<Q, Value>
where
Q: Query,
{
type SqlType = Q::SqlType;
}
impl<Query, Value> NonAggregate for UncheckedBind<Query, Value> where Self: Expression {}
impl<QS, Query, Value> SelectableExpression<QS> for UncheckedBind<Query, Value> where
Self: AppearsOnTable<QS>
{
}
impl<QS, Query, Value> AppearsOnTable<QS> for UncheckedBind<Query, Value> where Self: Expression {}
impl<Query, Value, Conn> RunQueryDsl<Conn> for UncheckedBind<Query, Value> {}