use crate::TableRef;
use crate::prelude::*;
use core::any::Any;
#[macro_use]
mod tuple;
mod column;
mod constraint;
mod foreign_key;
mod index;
mod param;
mod policy;
mod table;
mod to_sql;
mod type_set;
mod view;
pub use column::*;
pub use constraint::*;
pub use foreign_key::*;
pub use index::*;
pub use param::*;
pub use policy::*;
pub use table::*;
pub use to_sql::*;
pub use type_set::*;
pub use view::*;
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a SQL schema element",
label = "this type was not derived with a drizzle schema macro"
)]
pub trait SQLSchema<'a, T, V: SQLParam + 'a>: ToSQL<'a, V> {
const NAME: &'static str;
const TYPE: T;
const SQL: &'static str;
#[doc(hidden)]
const NAME_SCOPE: Option<(&'static str, &'static str)> = None;
}
impl<'a, S, T, V> SQLSchema<'a, T, V> for &S
where
S: SQLSchema<'a, T, V>,
V: SQLParam + 'a,
{
const NAME: &'static str = <S as SQLSchema<'a, T, V>>::NAME;
const TYPE: T = <S as SQLSchema<'a, T, V>>::TYPE;
const SQL: &'static str = <S as SQLSchema<'a, T, V>>::SQL;
const NAME_SCOPE: Option<(&'static str, &'static str)> = <S as SQLSchema<'a, T, V>>::NAME_SCOPE;
}
#[doc(hidden)]
#[must_use]
pub const fn first_duplicate_name(names: &[Option<(&str, &str)>]) -> Option<usize> {
const fn same(a: &str, b: &str) -> bool {
let (a, b) = (a.as_bytes(), b.as_bytes());
if a.len() != b.len() {
return false;
}
let mut i = 0;
while i < a.len() {
if a[i] != b[i] {
return false;
}
i += 1;
}
true
}
let mut later = 1;
while later < names.len() {
if let Some((scope, name)) = names[later] {
let mut earlier = 0;
while earlier < later {
if let Some((other_scope, other_name)) = names[earlier]
&& same(scope, other_scope)
&& same(name, other_name)
{
return Some(later);
}
earlier += 1;
}
}
later += 1;
}
None
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a recognized schema item",
label = "schema items must be tables, views, indexes, or enums derived with drizzle macros"
)]
pub trait SchemaItemTables {
type Tables: TypeSet;
const TABLE_REF_CONST: Option<&'static TableRef> = None;
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a SQL schema type marker",
label = "expected a dialect marker like SQLiteSchemaType, PostgresSchemaType, or MySQLSchemaType"
)]
pub trait SQLSchemaType: core::fmt::Debug + Any + Send + Sync {}
pub trait SQLSchemaImpl: Any + Send + Sync {
fn table_refs(&self) -> &'static [&'static TableRef];
fn create_statements(&self) -> crate::error::Result<impl Iterator<Item = String>>;
}