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 passive: bool,
124 pub comment: &'static str,
126}
127
128impl ColumnDef {
129 pub fn name(&self) -> &str {
131 &self.column_ref.name
132 }
133 pub fn table(&self) -> &str {
135 &self.column_ref.table
136 }
137 pub fn schema(&self) -> &str {
139 &self.column_ref.schema
140 }
141}
142
143impl<'a> From<&'a ColumnDef> for &'a ColumnRef {
144 fn from(value: &'a ColumnDef) -> Self {
145 &value.column_ref
146 }
147}
148
149impl OpPrecedence for ColumnRef {
150 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
151 1_000_000
152 }
153}
154
155impl Expression for ColumnRef {
156 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
157 writer.write_column_ref(context, out, self);
158 }
159 fn accept_visitor(
160 &self,
161 matcher: &mut dyn ExpressionVisitor,
162 writer: &dyn SqlWriter,
163 context: &mut Context,
164 out: &mut DynQuery,
165 ) -> bool {
166 matcher.visit_column(writer, context, out, self)
167 }
168}
169
170impl OpPrecedence for ColumnDef {
171 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
172 1_000_000
173 }
174}
175
176impl Expression for ColumnDef {
177 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
178 writer.write_column_ref(context, out, &self.column_ref);
179 }
180
181 fn accept_visitor(
182 &self,
183 matcher: &mut dyn ExpressionVisitor,
184 writer: &dyn SqlWriter,
185 context: &mut Context,
186 out: &mut DynQuery,
187 ) -> bool {
188 matcher.visit_column(writer, context, out, &self.column_ref)
189 }
190}
191
192impl PartialEq for ColumnDef {
193 fn eq(&self, other: &Self) -> bool {
194 self.column_ref == other.column_ref
195 }
196}
197
198impl Eq for ColumnDef {}
199
200impl Hash for ColumnDef {
201 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
202 self.column_ref.hash(state)
203 }
204}