Skip to main content

drizzle_core/traits/
mod.rs

1//! Traits for schema items (tables, columns, indexes, views, ...) and SQL
2//! rendering.
3//!
4//! The table, index, view and schema macros implement almost all of these.
5//! Users mostly call their methods, or meet them in error messages.
6
7use 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/// A schema item (table, column, index, view, enum) with a name and its
37/// `CREATE` SQL.
38///
39/// Generated by the schema macros. `'a` is the lifetime of borrowed
40/// parameter values in the SQL it renders.
41#[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    /// The item's SQL name.
47    const NAME: &'static str;
48    /// The kind of item (a dialect-specific enum, or the column's SQL type
49    /// name for columns).
50    const TYPE: T;
51    /// The statement that creates the item (`CREATE TABLE ...`), or an
52    /// empty string when it has none.
53    const SQL: &'static str;
54}
55
56impl<'a, S, T, V> SQLSchema<'a, T, V> for &S
57where
58    S: SQLSchema<'a, T, V>,
59    V: SQLParam + 'a,
60{
61    const NAME: &'static str = <S as SQLSchema<'a, T, V>>::NAME;
62    const TYPE: T = <S as SQLSchema<'a, T, V>>::TYPE;
63    const SQL: &'static str = <S as SQLSchema<'a, T, V>>::SQL;
64}
65
66/// The tables a schema item adds to its schema, as a type-level list.
67///
68/// A table adds itself (`Cons<Table, Nil>`); indexes, views and enums add
69/// nothing (`Nil`).
70#[diagnostic::on_unimplemented(
71    message = "`{Self}` is not a recognized schema item",
72    label = "schema items must be tables, views, indexes, or enums derived with drizzle macros"
73)]
74pub trait SchemaItemTables {
75    /// `Cons<Table, Nil>` for a table, `Nil` otherwise.
76    type Tables: TypeSet;
77    /// The table's metadata, or `None` for an item that is not a table.
78    const TABLE_REF_CONST: Option<&'static TableRef> = None;
79}
80
81/// Dialect marker for schema items: `SQLiteSchemaType`,
82/// `PostgresSchemaType` or `MySQLSchemaType`.
83///
84/// Keeps a SQLite table from being used with a PostgreSQL schema, and so on.
85#[diagnostic::on_unimplemented(
86    message = "`{Self}` is not a SQL schema type marker",
87    label = "expected a dialect marker like SQLiteSchemaType, PostgresSchemaType, or MySQLSchemaType"
88)]
89pub trait SQLSchemaType: core::fmt::Debug + Any + Send + Sync {}
90
91/// A schema struct (generated by `#[SQLiteSchema]`, `#[PostgresSchema]`,
92/// ...) that can list its tables and render its `CREATE` statements.
93pub trait SQLSchemaImpl: Any + Send + Sync {
94    /// Metadata of every table in the schema.
95    fn table_refs(&self) -> &'static [&'static TableRef];
96    /// Returns the `CREATE` statements for the schema's items.
97    ///
98    /// # Errors
99    ///
100    /// Returns an error if SQL generation for any table fails.
101    fn create_statements(&self) -> crate::error::Result<impl Iterator<Item = String>>;
102}