Skip to main content

tank_core/
table_ref.rs

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