1use crate::{
2 DefaultValueType, DynQuery, Expression, ExpressionVisitor, OpPrecedence, SqlWriter, TableRef,
3 Value, writer::Context,
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7use std::{borrow::Cow, collections::BTreeMap, hash::Hash};
8
9pub trait ColumnTrait {
11 fn column_def(&self) -> &ColumnDef;
13 fn column_ref(&self) -> &ColumnRef;
15}
16
17#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
19pub struct ColumnRef {
20 pub name: Cow<'static, str>,
22 pub table: Cow<'static, str>,
24 pub schema: Cow<'static, str>,
26}
27
28impl ColumnRef {
29 pub fn new(name: Cow<'static, str>) -> Self {
31 Self {
32 name,
33 ..Default::default()
34 }
35 }
36 pub fn table(&self) -> TableRef {
38 TableRef {
39 name: self.table.clone(),
40 schema: self.schema.clone(),
41 ..Default::default()
42 }
43 }
44}
45
46#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
48pub enum PrimaryKeyType {
49 PrimaryKey,
51 PartOfPrimaryKey,
53 #[default]
55 None,
56}
57
58impl ToTokens for PrimaryKeyType {
59 fn to_tokens(&self, tokens: &mut TokenStream) {
60 use PrimaryKeyType::*;
61 tokens.append_all(match self {
62 PrimaryKey => quote!(::tank::PrimaryKeyType::PrimaryKey),
63 PartOfPrimaryKey => quote!(::tank::PrimaryKeyType::PartOfPrimaryKey),
64 None => quote!(::tank::PrimaryKeyType::None),
65 });
66 }
67}
68
69#[derive(Default, Debug, PartialEq, Eq)]
71pub enum Action {
72 #[default]
74 NoAction,
75 Restrict,
77 Cascade,
79 SetNull,
81 SetDefault,
83}
84
85impl ToTokens for Action {
86 fn to_tokens(&self, tokens: &mut TokenStream) {
87 tokens.append_all(match self {
88 Action::NoAction => quote! { ::tank::Action::NoAction },
89 Action::Restrict => quote! { ::tank::Action::Restrict },
90 Action::Cascade => quote! { ::tank::Action::Cascade },
91 Action::SetNull => quote! { ::tank::Action::SetNull },
92 Action::SetDefault => quote! { ::tank::Action::SetDefault },
93 });
94 }
95}
96
97#[derive(Default, Debug)]
99pub struct ColumnDef {
100 pub column_ref: ColumnRef,
102 pub column_type: BTreeMap<&'static str, &'static str>,
104 pub value: Value,
106 pub nullable: bool,
108 pub default: DefaultValueType,
110 pub primary_key: PrimaryKeyType,
112 pub clustering_key: bool,
114 pub unique: bool,
116 pub references: Option<ColumnRef>,
118 pub on_delete: Option<Action>,
120 pub on_update: Option<Action>,
122 pub comment: &'static str,
124}
125
126impl ColumnDef {
127 pub fn name(&self) -> &str {
129 &self.column_ref.name
130 }
131 pub fn table(&self) -> &str {
133 &self.column_ref.table
134 }
135 pub fn schema(&self) -> &str {
137 &self.column_ref.schema
138 }
139}
140
141impl<'a> From<&'a ColumnDef> for &'a ColumnRef {
142 fn from(value: &'a ColumnDef) -> Self {
143 &value.column_ref
144 }
145}
146
147impl OpPrecedence for ColumnRef {
148 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
149 1_000_000
150 }
151}
152
153impl Expression for ColumnRef {
154 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
155 writer.write_column_ref(context, out, self);
156 }
157 fn accept_visitor(
158 &self,
159 matcher: &mut dyn ExpressionVisitor,
160 writer: &dyn SqlWriter,
161 context: &mut Context,
162 out: &mut DynQuery,
163 ) -> bool {
164 matcher.visit_column(writer, context, out, self)
165 }
166}
167
168impl OpPrecedence for ColumnDef {
169 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
170 1_000_000
171 }
172}
173
174impl Expression for ColumnDef {
175 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
176 writer.write_column_ref(context, out, &self.column_ref);
177 }
178
179 fn accept_visitor(
180 &self,
181 matcher: &mut dyn ExpressionVisitor,
182 writer: &dyn SqlWriter,
183 context: &mut Context,
184 out: &mut DynQuery,
185 ) -> bool {
186 matcher.visit_column(writer, context, out, &self.column_ref)
187 }
188}
189
190impl PartialEq for ColumnDef {
191 fn eq(&self, other: &Self) -> bool {
192 self.column_ref == other.column_ref
193 }
194}
195
196impl Eq for ColumnDef {}
197
198impl Hash for ColumnDef {
199 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
200 self.column_ref.hash(state)
201 }
202}