drizzle_core/traits/
column.rs1use crate::expr::Expr;
2use crate::{SQLParam, SQLSchema, SQLSchemaType, SQLTable, SQLTableInfo};
3
4pub trait SQLColumnInfo: Send + Sync {
8 fn is_not_null(&self) -> bool;
10 fn is_primary_key(&self) -> bool;
12 fn is_unique(&self) -> bool;
14 fn name(&self) -> &'static str;
16 fn r#type(&self) -> &'static str;
18 fn has_default(&self) -> bool;
20
21 fn table(&self) -> &'static dyn SQLTableInfo;
23}
24
25#[diagnostic::on_unimplemented(
31 message = "`{Self}` is not a SQL column for this dialect",
32 label = "ensure this column's table was derived with #[SQLiteTable], #[PostgresTable], or #[MySQLTable]"
33)]
34pub trait SQLColumn<'a, Value: SQLParam + 'a>:
35 SQLColumnInfo + Default + SQLSchema<'a, &'a str, Value> + Expr<'a, Value>
36{
37 type Table: SQLTable<'a, Self::TableType, Value>;
39 type TableType: SQLSchemaType;
41 type ForeignKeys;
43 type Type: TryInto<Value>;
45
46 const PRIMARY_KEY: bool = false;
48 const NOT_NULL: bool = false;
50 const UNIQUE: bool = false;
52 const DEFAULT: Option<Self::Type> = None;
54
55 fn default_fn(&'a self) -> Option<impl Fn() -> Self::Type> {
58 None::<fn() -> Self::Type>
59 }
60
61 fn placeholder(
67 &self,
68 name: &'static str,
69 ) -> crate::placeholder::TypedPlaceholder<
70 <Self as Expr<'a, Value>>::SQLType,
71 <Self as Expr<'a, Value>>::Nullable,
72 >
73 where
74 Self: Sized,
75 {
76 crate::placeholder::TypedPlaceholder::named(name)
77 }
78}
79
80impl<T: SQLColumnInfo> SQLColumnInfo for &T {
82 fn is_not_null(&self) -> bool {
83 (*self).is_not_null()
84 }
85
86 fn is_primary_key(&self) -> bool {
87 (*self).is_primary_key()
88 }
89
90 fn is_unique(&self) -> bool {
91 (*self).is_unique()
92 }
93
94 fn name(&self) -> &'static str {
95 (*self).name()
96 }
97
98 fn r#type(&self) -> &'static str {
99 (*self).r#type()
100 }
101
102 fn has_default(&self) -> bool {
103 (*self).has_default()
104 }
105
106 fn table(&self) -> &'static dyn SQLTableInfo {
107 (*self).table()
108 }
109}
110
111impl<'a, Value, T> SQLColumn<'a, Value> for &T
112where
113 Value: SQLParam + 'a,
114 T: SQLColumn<'a, Value>,
115 for<'r> &'r T: SQLColumnInfo + Default + SQLSchema<'a, &'a str, Value> + Expr<'a, Value>,
116{
117 type Table = T::Table;
118 type TableType = T::TableType;
119 type ForeignKeys = T::ForeignKeys;
120 type Type = T::Type;
121
122 const PRIMARY_KEY: bool = T::PRIMARY_KEY;
123 const NOT_NULL: bool = T::NOT_NULL;
124 const UNIQUE: bool = T::UNIQUE;
125 const DEFAULT: Option<Self::Type> = T::DEFAULT;
126
127 fn default_fn(&'a self) -> Option<impl Fn() -> Self::Type> {
128 <T as SQLColumn<'a, Value>>::default_fn(*self)
129 }
130}
131
132impl core::fmt::Debug for dyn SQLColumnInfo {
133 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
134 f.debug_struct("SQLColumnInfo")
135 .field("name", &self.name())
136 .field("type", &self.r#type())
137 .field("not_null", &self.is_not_null())
138 .field("primary_key", &self.is_primary_key())
139 .field("unique", &self.is_unique())
140 .field("table", &self.table().name())
141 .field("has_default", &self.has_default())
142 .finish()
143 }
144}