drizzle_core/traits/
column.rs1use crate::expr::Expr;
2use crate::{SQLParam, SQLSchema, SQLSchemaType, SQLTable, SQLTableInfo};
3
4pub trait SQLColumnInfo: Send + Sync {
5 fn is_not_null(&self) -> bool;
6 fn is_primary_key(&self) -> bool;
7 fn is_unique(&self) -> bool;
8 fn name(&self) -> &'static str;
9 fn r#type(&self) -> &'static str;
10 fn has_default(&self) -> bool;
11
12 fn table(&self) -> &'static dyn SQLTableInfo;
13}
14
15#[diagnostic::on_unimplemented(
17 message = "`{Self}` is not a SQL column for this dialect",
18 label = "ensure this column's table was derived with #[SQLiteTable] or #[PostgresTable]"
19)]
20pub trait SQLColumn<'a, Value: SQLParam + 'a>:
21 SQLColumnInfo + Default + SQLSchema<'a, &'a str, Value> + Expr<'a, Value>
22{
23 type Table: SQLTable<'a, Self::TableType, Value>;
24 type TableType: SQLSchemaType;
25 type ForeignKeys;
26 type Type: TryInto<Value>;
27
28 const PRIMARY_KEY: bool = false;
29 const NOT_NULL: bool = false;
30 const UNIQUE: bool = false;
31 const DEFAULT: Option<Self::Type> = None;
32
33 fn default_fn(&'a self) -> Option<impl Fn() -> Self::Type> {
34 None::<fn() -> Self::Type>
35 }
36
37 fn placeholder(
39 &self,
40 name: &'static str,
41 ) -> crate::placeholder::TypedPlaceholder<
42 <Self as Expr<'a, Value>>::SQLType,
43 <Self as Expr<'a, Value>>::Nullable,
44 >
45 where
46 Self: Sized,
47 {
48 crate::placeholder::TypedPlaceholder::named(name)
49 }
50}
51
52impl<T: SQLColumnInfo> SQLColumnInfo for &T {
54 fn is_not_null(&self) -> bool {
55 (*self).is_not_null()
56 }
57
58 fn is_primary_key(&self) -> bool {
59 (*self).is_primary_key()
60 }
61
62 fn is_unique(&self) -> bool {
63 (*self).is_unique()
64 }
65
66 fn name(&self) -> &'static str {
67 (*self).name()
68 }
69
70 fn r#type(&self) -> &'static str {
71 (*self).r#type()
72 }
73
74 fn has_default(&self) -> bool {
75 (*self).has_default()
76 }
77
78 fn table(&self) -> &'static dyn SQLTableInfo {
79 (*self).table()
80 }
81}
82
83impl<'a, Value, T> SQLColumn<'a, Value> for &T
84where
85 Value: SQLParam + 'a,
86 T: SQLColumn<'a, Value>,
87 for<'r> &'r T: SQLColumnInfo + Default + SQLSchema<'a, &'a str, Value> + Expr<'a, Value>,
88{
89 type Table = T::Table;
90 type TableType = T::TableType;
91 type ForeignKeys = T::ForeignKeys;
92 type Type = T::Type;
93
94 const PRIMARY_KEY: bool = T::PRIMARY_KEY;
95 const NOT_NULL: bool = T::NOT_NULL;
96 const UNIQUE: bool = T::UNIQUE;
97 const DEFAULT: Option<Self::Type> = T::DEFAULT;
98
99 fn default_fn(&'a self) -> Option<impl Fn() -> Self::Type> {
100 <T as SQLColumn<'a, Value>>::default_fn(*self)
101 }
102}
103
104impl core::fmt::Debug for dyn SQLColumnInfo {
105 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
106 f.debug_struct("SQLColumnInfo")
107 .field("name", &self.name())
108 .field("type", &self.r#type())
109 .field("not_null", &self.is_not_null())
110 .field("primary_key", &self.is_primary_key())
111 .field("unique", &self.is_unique())
112 .field("table", &self.table().name())
113 .field("has_default", &self.has_default())
114 .finish()
115 }
116}