Skip to main content

tank_core/
table_ref.rs

1use crate::{
2    ColumnDef, Dataset, DynQuery, quote_cow,
3    writer::{Context, SqlWriter},
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7use std::borrow::Cow;
8
9/// Table reference.
10#[derive(Default, Clone, PartialEq, Eq, Hash, Debug)]
11pub struct TableRef {
12    /// Table name.
13    pub name: Cow<'static, str>,
14    /// Schema name.
15    pub schema: Cow<'static, str>,
16    /// Alias.
17    pub alias: Cow<'static, str>,
18    /// Columns
19    pub columns: &'static [ColumnDef],
20    /// Primary key
21    pub primary_key: &'static [&'static ColumnDef],
22}
23
24impl TableRef {
25    /// New table reference.
26    pub const fn new(name: Cow<'static, str>) -> Self {
27        Self {
28            name,
29            schema: Cow::Borrowed(""),
30            alias: Cow::Borrowed(""),
31            columns: &[],
32            primary_key: &[],
33        }
34    }
35    /// Get the display name.
36    pub fn full_name(&self, separator: &str) -> Cow<'static, str> {
37        if !self.alias.is_empty() {
38            return self.alias.clone();
39        }
40        let mut name = self.name.clone();
41        if !self.schema.is_empty() {
42            name = format!("{}{}{}", self.schema, separator, name).into();
43        }
44        name
45    }
46    /// Set the alias.
47    pub fn with_alias(&self, alias: Cow<'static, str>) -> Self {
48        let mut result = self.clone();
49        result.alias = alias.into();
50        result
51    }
52    /// True if empty.
53    pub fn is_empty(&self) -> bool {
54        self.name.is_empty() && self.schema.is_empty() && self.alias.is_empty()
55    }
56}
57
58impl Dataset for TableRef {
59    fn qualified_columns() -> bool
60    where
61        Self: Sized,
62    {
63        false
64    }
65    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
66        writer.write_table_ref(context, out, self)
67    }
68    fn table_ref(&self) -> TableRef {
69        self.clone()
70    }
71}
72
73impl Dataset for &TableRef {
74    fn qualified_columns() -> bool
75    where
76        Self: Sized,
77    {
78        false
79    }
80    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
81        (*writer).write_table_ref(context, out, self)
82    }
83    fn table_ref(&self) -> TableRef {
84        (*self).clone()
85    }
86}
87
88impl From<&'static str> for TableRef {
89    fn from(value: &'static str) -> Self {
90        TableRef::new(value.into())
91    }
92}
93
94impl ToTokens for TableRef {
95    fn to_tokens(&self, tokens: &mut TokenStream) {
96        let name = &self.name;
97        let schema = &self.schema;
98        let alias = quote_cow(&self.alias);
99        tokens.append_all(quote! {
100            ::tank::TableRef {
101                name: #name,
102                schema: #schema,
103                alias: #alias,
104            }
105        });
106    }
107}
108
109/// Wrapper used when declaring table references in generated macros.
110#[derive(Default, Clone, PartialEq, Eq, Debug)]
111pub struct DeclareTableRef(pub TableRef);
112
113impl Dataset for DeclareTableRef {
114    fn qualified_columns() -> bool
115    where
116        Self: Sized,
117    {
118        false
119    }
120    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
121        writer.write_table_ref(context, out, &self.0)
122    }
123    fn table_ref(&self) -> TableRef {
124        self.0.clone()
125    }
126}
127
128impl ToTokens for DeclareTableRef {
129    fn to_tokens(&self, tokens: &mut TokenStream) {
130        let table_ref = &self.0;
131        tokens.append_all(quote!(::tank::DeclareTableRef(#table_ref)));
132    }
133}