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};
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)]
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 {
30 Self {
31 name,
32 ..Default::default()
33 }
34 }
35 pub fn table(&self) -> TableRef {
37 TableRef {
38 name: self.table.clone(),
39 schema: self.schema.clone(),
40 ..Default::default()
41 }
42 }
43}
44
45#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
47pub enum PrimaryKeyType {
48 PrimaryKey,
50 PartOfPrimaryKey,
52 #[default]
54 None,
55}
56
57impl ToTokens for PrimaryKeyType {
58 fn to_tokens(&self, tokens: &mut TokenStream) {
59 use PrimaryKeyType::*;
60 tokens.append_all(match self {
61 PrimaryKey => quote!(::tank::PrimaryKeyType::PrimaryKey),
62 PartOfPrimaryKey => quote!(::tank::PrimaryKeyType::PartOfPrimaryKey),
63 None => quote!(::tank::PrimaryKeyType::None),
64 });
65 }
66}
67
68#[derive(Default, Debug, PartialEq, Eq)]
70pub enum Action {
71 #[default]
73 NoAction,
74 Restrict,
76 Cascade,
78 SetNull,
80 SetDefault,
82}
83
84impl ToTokens for Action {
85 fn to_tokens(&self, tokens: &mut TokenStream) {
86 tokens.append_all(match self {
87 Action::NoAction => quote! { ::tank::Action::NoAction },
88 Action::Restrict => quote! { ::tank::Action::Restrict },
89 Action::Cascade => quote! { ::tank::Action::Cascade },
90 Action::SetNull => quote! { ::tank::Action::SetNull },
91 Action::SetDefault => quote! { ::tank::Action::SetDefault },
92 });
93 }
94}
95
96#[derive(Default, Debug)]
98pub struct ColumnDef {
99 pub column_ref: ColumnRef,
101 pub column_type: BTreeMap<&'static str, &'static str>,
103 pub value: Value,
105 pub nullable: bool,
107 pub default: DefaultValueType,
109 pub primary_key: PrimaryKeyType,
111 pub clustering_key: bool,
113 pub unique: bool,
115 pub references: Option<ColumnRef>,
117 pub on_delete: Option<Action>,
119 pub on_update: Option<Action>,
121 pub passive: bool,
123 pub comment: &'static str,
125}
126
127impl ColumnDef {
128 pub fn name(&self) -> &str {
130 &self.column_ref.name
131 }
132 pub fn table(&self) -> &str {
134 &self.column_ref.table
135 }
136 pub fn schema(&self) -> &str {
138 &self.column_ref.schema
139 }
140}
141
142impl<'a> From<&'a ColumnDef> for &'a ColumnRef {
143 fn from(value: &'a ColumnDef) -> Self {
144 &value.column_ref
145 }
146}
147
148impl OpPrecedence for ColumnRef {
149 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
150 1_000_000
151 }
152}
153
154impl Expression for ColumnRef {
155 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
156 writer.write_column_ref(context, out, self);
157 }
158 fn accept_visitor(
159 &self,
160 matcher: &mut dyn ExpressionVisitor,
161 writer: &dyn SqlWriter,
162 context: &mut Context,
163 out: &mut DynQuery,
164 ) -> bool {
165 matcher.visit_column(writer, context, out, self)
166 }
167}
168
169impl OpPrecedence for ColumnDef {
170 fn precedence(&self, _writer: &dyn SqlWriter) -> i32 {
171 1_000_000
172 }
173}
174
175impl Expression for ColumnDef {
176 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, out: &mut DynQuery) {
177 writer.write_column_ref(context, out, &self.column_ref);
178 }
179
180 fn accept_visitor(
181 &self,
182 matcher: &mut dyn ExpressionVisitor,
183 writer: &dyn SqlWriter,
184 context: &mut Context,
185 out: &mut DynQuery,
186 ) -> bool {
187 matcher.visit_column(writer, context, out, &self.column_ref)
188 }
189}