#[macro_export]
#[doc(hidden)]
macro_rules! diesel_internal_expr_conversion {
($e:expr) => { $e }
}
#[macro_export]
#[doc(hidden)]
macro_rules! column {
($($table:ident)::*, $column_name:ident -> $Type:ty) => {
#[allow(non_camel_case_types, dead_code)]
#[derive(Debug, Clone, Copy)]
pub struct $column_name;
impl $crate::expression::Expression for $column_name {
type SqlType = $Type;
}
impl<DB> $crate::query_builder::QueryFragment<DB> for $column_name where
DB: $crate::backend::Backend,
{
fn to_sql(&self, out: &mut DB::QueryBuilder) -> $crate::query_builder::BuildQueryResult {
try!(out.push_identifier($($table)::*::name()));
out.push_sql(".");
out.push_identifier(stringify!($column_name))
}
}
impl $crate::expression::SelectableExpression<$($table)::*> for $column_name {}
impl<'a, ST, Left, Right> SelectableExpression<
$crate::WithQuerySource<'a, Left, Right>, ST> for $column_name where
$column_name: SelectableExpression<Left, ST>
{
}
impl $crate::expression::NonAggregate for $column_name {}
impl $crate::query_source::Column for $column_name {
type Table = $($table)::*;
fn name() -> &'static str {
stringify!($column_name)
}
}
}
}
#[macro_export]
macro_rules! table {
(
$name:ident {
$($column_name:ident -> $Type:ty,)+
}
) => {
table! {
$name (id) {
$($column_name -> $Type,)+
}
}
};
(
$name:ident ($pk:ident) {
$($column_name:ident -> $Type:ty,)+
}
) => {
table_body! {
$name ($pk) {
$($column_name -> $Type,)+
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! table_body {
(
$name:ident ($pk:ident) {
$($column_name:ident -> $Type:ty,)+
}
) => {
pub mod $name {
use $crate::{
QuerySource,
Table,
};
use $crate::query_builder::*;
use $crate::query_builder::nodes::Identifier;
use $crate::types::*;
pub use self::columns::*;
pub mod dsl {
pub use super::columns::{$($column_name),+};
pub use super::table as $name;
}
#[allow(non_upper_case_globals, dead_code)]
pub const all_columns: ($($column_name,)+) = ($($column_name,)+);
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
pub struct table;
impl table {
#[allow(dead_code)]
pub fn star(&self) -> star {
star
}
}
pub type SqlType = ($($Type,)+);
pub type BoxedQuery<'a, DB, ST = SqlType> = BoxedSelectStatement<'a, ST, table, DB>;
impl QuerySource for table {
type FromClause = Identifier<'static>;
fn from_clause(&self) -> Self::FromClause {
Identifier(stringify!($name))
}
}
impl AsQuery for table {
type SqlType = SqlType;
type Query = SelectStatement<SqlType, ($($column_name,)+), Self>;
fn as_query(self) -> Self::Query {
SelectStatement::simple(all_columns, self)
}
}
impl Table for table {
type PrimaryKey = columns::$pk;
type AllColumns = ($($column_name,)+);
fn name() -> &'static str {
stringify!($name)
}
fn primary_key(&self) -> Self::PrimaryKey {
columns::$pk
}
fn all_columns() -> Self::AllColumns {
($($column_name,)+)
}
}
pub mod columns {
use super::table;
use $crate::{Table, Column, Expression, SelectableExpression};
use $crate::backend::Backend;
use $crate::query_builder::{QueryBuilder, BuildQueryResult, QueryFragment};
use $crate::types::*;
#[allow(non_camel_case_types, dead_code)]
#[derive(Debug, Clone, Copy)]
pub struct star;
impl Expression for star {
type SqlType = ();
}
impl<DB: Backend> QueryFragment<DB> for star {
fn to_sql(&self, out: &mut DB::QueryBuilder) -> BuildQueryResult {
try!(out.push_identifier(table::name()));
out.push_sql(".*");
Ok(())
}
}
impl SelectableExpression<table> for star {}
$(column!(table, $column_name -> $Type);)+
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! joinable {
($child:ident -> $parent:ident ($source:ident)) => {
joinable_inner!($child::table => $parent::table : ($child::$source = $parent::table));
joinable_inner!($parent::table => $child::table : ($child::$source = $parent::table));
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! joinable_inner {
($left_table:path => $right_table:path : ($foreign_key:path = $parent_table:path)) => {
impl<JoinType> $crate::JoinTo<$right_table, JoinType> for $left_table {
type JoinClause = $crate::query_builder::nodes::Join<
<$left_table as $crate::QuerySource>::FromClause,
<$right_table as $crate::QuerySource>::FromClause,
$crate::expression::helper_types::Eq<
$crate::expression::nullable::Nullable<$foreign_key>,
$crate::expression::nullable::Nullable<
<$parent_table as $crate::query_source::Table>::PrimaryKey>,
>,
JoinType,
>;
fn join_clause(&self, join_type: JoinType) -> Self::JoinClause {
use $crate::QuerySource;
$crate::query_builder::nodes::Join::new(
self.from_clause(),
$right_table.from_clause(),
$foreign_key.nullable().eq($parent_table.primary_key().nullable()),
join_type,
)
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! select_column_workaround {
($parent:ident -> $child:ident ($($column_name:ident),+)) => {
$(select_column_inner!($parent -> $child $column_name);)+
select_column_inner!($parent -> $child star);
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! select_column_inner {
($parent:ident -> $child:ident $column_name:ident) => {
impl $crate::expression::SelectableExpression<
$crate::query_source::InnerJoinSource<$child::table, $parent::table>,
> for $parent::$column_name
{
}
impl $crate::expression::SelectableExpression<
$crate::query_source::InnerJoinSource<$parent::table, $child::table>,
> for $parent::$column_name
{
}
impl $crate::expression::SelectableExpression<
$crate::query_source::LeftOuterJoinSource<$child::table, $parent::table>,
<<$parent::$column_name as $crate::Expression>::SqlType
as $crate::types::IntoNullable>::Nullable,
> for $parent::$column_name
{
}
impl $crate::expression::SelectableExpression<
$crate::query_source::LeftOuterJoinSource<$parent::table, $child::table>,
> for $parent::$column_name
{
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! join_through {
($parent:ident -> $through:ident -> $child:ident) => {
impl<JoinType: Copy> $crate::JoinTo<$child::table, JoinType> for $parent::table {
type JoinClause = <
<$parent::table as $crate::JoinTo<$through::table, JoinType>>::JoinClause
as $crate::query_builder::nodes::CombinedJoin<
<$through::table as $crate::JoinTo<$child::table, JoinType>>::JoinClause,
>>::Output;
fn join_clause(&self, join_type: JoinType) -> Self::JoinClause {
use $crate::query_builder::nodes::CombinedJoin;
let parent_to_through = $crate::JoinTo::<$through::table, JoinType>
::join_clause(&$parent::table, join_type);
let through_to_child = $crate::JoinTo::<$child::table, JoinType>
::join_clause(&$through::table, join_type);
parent_to_through.combine_with(through_to_child)
}
}
}
}
#[macro_export]
macro_rules! debug_sql {
($query:expr) => {{
use $crate::query_builder::QueryFragment;
use $crate::query_builder::debug::DebugQueryBuilder;
let mut query_builder = DebugQueryBuilder::new();
QueryFragment::<$crate::backend::Debug>::to_sql(&$query, &mut query_builder).unwrap();
query_builder.sql
}};
}
#[macro_export]
macro_rules! print_sql {
($query:expr) => {
println!("{}", &debug_sql!($query));
};
}