tank_core/
table_ref.rs

1use crate::{
2    DataSet, quote_cow,
3    writer::{Context, SqlWriter},
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7use std::borrow::Cow;
8
9/// Schema-qualified table reference (optional alias).
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    /// Optional alias used when rendering.
17    pub alias: Cow<'static, str>,
18}
19
20impl TableRef {
21    pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
22        Self {
23            name: name.into(),
24            schema: "".into(),
25            alias: "".into(),
26        }
27    }
28    pub fn full_name(&self) -> String {
29        let mut result = String::new();
30        if !self.alias.is_empty() {
31            result.push_str(&self.alias);
32        } else {
33            if !self.schema.is_empty() {
34                result.push_str(&self.schema);
35                result.push('.');
36            }
37            result.push_str(&self.name);
38        }
39        result
40    }
41    pub fn with_alias(&self, alias: Cow<'static, str>) -> Self {
42        let mut result = self.clone();
43        result.alias = alias.into();
44        result
45    }
46    pub fn name<'s>(&'s self) -> &'s str {
47        // TODO: replace with .as_str() and make the function const once https://github.com/rust-lang/rust/issues/130366 is stable
48        &self.name
49    }
50    pub fn schema<'s>(&'s self) -> &'s str {
51        // TODO: replace with .as_str() and make the function const once https://github.com/rust-lang/rust/issues/130366 is stable
52        &self.schema
53    }
54    pub fn alias<'s>(&'s self) -> &'s str {
55        // TODO: replace with .as_str() and make the function const once https://github.com/rust-lang/rust/issues/130366 is stable
56        &self.alias
57    }
58}
59
60impl DataSet for TableRef {
61    fn qualified_columns() -> bool
62    where
63        Self: Sized,
64    {
65        false
66    }
67    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut String) {
68        writer.write_table_ref(context, out, self)
69    }
70}
71
72impl DataSet for &TableRef {
73    fn qualified_columns() -> bool
74    where
75        Self: Sized,
76    {
77        false
78    }
79    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut String) {
80        (*writer).write_table_ref(context, out, self)
81    }
82}
83
84impl ToTokens for TableRef {
85    fn to_tokens(&self, tokens: &mut TokenStream) {
86        let name = &self.name;
87        let schema = &self.schema;
88        let alias = quote_cow(&self.alias);
89        tokens.append_all(quote! {
90            ::tank::TableRef {
91                name: #name,
92                schema: #schema,
93                alias: #alias,
94            }
95        });
96    }
97}
98
99/// Wrapper used when declaring table references in generated macros.
100#[derive(Default, Clone, PartialEq, Eq, Debug)]
101pub struct DeclareTableRef(pub TableRef);
102
103impl DataSet for DeclareTableRef {
104    fn qualified_columns() -> bool
105    where
106        Self: Sized,
107    {
108        false
109    }
110    fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut String) {
111        writer.write_table_ref(context, out, &self.0)
112    }
113}
114
115impl ToTokens for DeclareTableRef {
116    fn to_tokens(&self, tokens: &mut TokenStream) {
117        let table_ref = &self.0;
118        tokens.append_all(quote!(::tank::DeclareTableRef(#table_ref)));
119    }
120}