taitan_orm_parser/template_parser/
to_sql.rs

1use proc_macro2::TokenStream;
2use quote::{format_ident, quote};
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum SqlSegment {
6    Simple(String),
7    Hash(String),
8    At(String),
9    Dollar(String),
10}
11
12impl SqlSegment {
13    pub fn to_sql(&self, indexed: bool) -> TokenStream {
14        match self {
15
16            SqlSegment::Simple(s) => {
17                let content = format!("{} ", s);
18                quote! { s.push_str(#content); }
19            }
20            SqlSegment::Hash(s) => {
21                if indexed {
22                    quote! {
23                        index += 1;
24                        sql.push_str(format!("${}", index).as_str());
25                    }
26                } else {
27                    quote! { sql.push('?'); }
28                }
29            }
30            SqlSegment::At(s) => {
31                let ident = format_ident!("{}", s);
32                if indexed {
33                    quote! {
34                        if self.#ident.is_some() {
35                            index += 1;
36                            sql.push_str(format!("${}", index).as_str());
37                        }
38                    }
39                } else {
40                    quote! {
41                        if self.#ident.is_some() {
42                            s.push('?');
43                        }
44                    }
45                }
46            }
47            SqlSegment::Dollar(s) => {
48                let template = format!("{{ {} }}", s);
49                quote! { s.push_str(#template); }
50            }
51        }
52    }
53}
54
55pub trait ToSqlSegment {
56    // ${ name } 在to_sql的时候替换为 {{ name }}
57    // #{ name } 替换为 ?,并且variables里面返回名称,保证后续的绑定
58
59    fn gen_sql_segment(&self) -> SqlSegment {
60        unimplemented!()
61    }
62
63    fn gen_sql_segments(&self) -> Vec<SqlSegment> {
64        vec![self.gen_sql_segment()]
65    }
66
67    // #{ name } 替换为 ?,并且variables里面返回名称,保证后续的绑定
68    // @{ name } 替换为 if self.name.is_some() { v.push("name".to_string()); }
69}