drizzle_core/traits/
mod.rs1use crate::TableRef;
8use crate::prelude::*;
9use core::any::Any;
10
11#[macro_use]
12mod tuple;
13
14mod column;
15mod constraint;
16mod foreign_key;
17mod index;
18mod param;
19mod policy;
20mod table;
21mod to_sql;
22mod type_set;
23mod view;
24
25pub use column::*;
26pub use constraint::*;
27pub use foreign_key::*;
28pub use index::*;
29pub use param::*;
30pub use policy::*;
31pub use table::*;
32pub use to_sql::*;
33pub use type_set::*;
34pub use view::*;
35
36#[diagnostic::on_unimplemented(
42 message = "`{Self}` is not a SQL schema element",
43 label = "this type was not derived with a drizzle schema macro"
44)]
45pub trait SQLSchema<'a, T, V: SQLParam + 'a>: ToSQL<'a, V> {
46 const NAME: &'static str;
48 const TYPE: T;
51 const SQL: &'static str;
54 #[doc(hidden)]
59 const NAME_SCOPE: Option<(&'static str, &'static str)> = None;
60}
61
62impl<'a, S, T, V> SQLSchema<'a, T, V> for &S
63where
64 S: SQLSchema<'a, T, V>,
65 V: SQLParam + 'a,
66{
67 const NAME: &'static str = <S as SQLSchema<'a, T, V>>::NAME;
68 const TYPE: T = <S as SQLSchema<'a, T, V>>::TYPE;
69 const SQL: &'static str = <S as SQLSchema<'a, T, V>>::SQL;
70 const NAME_SCOPE: Option<(&'static str, &'static str)> = <S as SQLSchema<'a, T, V>>::NAME_SCOPE;
71}
72
73#[doc(hidden)]
76#[must_use]
77pub const fn first_duplicate_name(names: &[Option<(&str, &str)>]) -> Option<usize> {
78 const fn same(a: &str, b: &str) -> bool {
79 let (a, b) = (a.as_bytes(), b.as_bytes());
80 if a.len() != b.len() {
81 return false;
82 }
83 let mut i = 0;
84 while i < a.len() {
85 if a[i] != b[i] {
86 return false;
87 }
88 i += 1;
89 }
90 true
91 }
92 let mut later = 1;
93 while later < names.len() {
94 if let Some((scope, name)) = names[later] {
95 let mut earlier = 0;
96 while earlier < later {
97 if let Some((other_scope, other_name)) = names[earlier]
98 && same(scope, other_scope)
99 && same(name, other_name)
100 {
101 return Some(later);
102 }
103 earlier += 1;
104 }
105 }
106 later += 1;
107 }
108 None
109}
110
111#[diagnostic::on_unimplemented(
116 message = "`{Self}` is not a recognized schema item",
117 label = "schema items must be tables, views, indexes, or enums derived with drizzle macros"
118)]
119pub trait SchemaItemTables {
120 type Tables: TypeSet;
122 const TABLE_REF_CONST: Option<&'static TableRef> = None;
124}
125
126#[diagnostic::on_unimplemented(
131 message = "`{Self}` is not a SQL schema type marker",
132 label = "expected a dialect marker like SQLiteSchemaType, PostgresSchemaType, or MySQLSchemaType"
133)]
134pub trait SQLSchemaType: core::fmt::Debug + Any + Send + Sync {}
135
136pub trait SQLSchemaImpl: Any + Send + Sync {
139 fn table_refs(&self) -> &'static [&'static TableRef];
141 fn create_statements(&self) -> crate::error::Result<impl Iterator<Item = String>>;
147}