Skip to main content

drizzle_core/
schema.rs

1use crate::prelude::*;
2use crate::{ToSQL, sql::SQL, traits::SQLParam};
3use core::any::Any;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6pub struct SchemaName(pub &'static str);
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9pub struct TableName(pub &'static str);
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
12pub struct ColumnName(pub &'static str);
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
15pub struct IndexName(pub &'static str);
16
17/// Trait for database enum types that can be part of a schema
18pub trait SQLEnumInfo: Any + Send + Sync {
19    /// The name of this enum type
20    fn name(&self) -> &'static str;
21
22    /// The SQL CREATE TYPE statement for this enum
23    fn create_type_sql(&self) -> String;
24
25    /// All possible values of this enum
26    fn variants(&self) -> &'static [&'static str];
27}
28
29/// Helper trait for converting enum info objects to trait objects
30pub trait AsEnumInfo: SQLEnumInfo {
31    fn as_enum(&self) -> &dyn SQLEnumInfo;
32}
33
34impl<T: SQLEnumInfo> AsEnumInfo for T {
35    fn as_enum(&self) -> &dyn SQLEnumInfo {
36        self
37    }
38}
39
40impl core::fmt::Debug for dyn SQLEnumInfo {
41    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42        f.debug_struct("SQLEnumInfo")
43            .field("name", &self.name())
44            .field("variants", &self.variants())
45            .finish()
46    }
47}
48
49/// Sort direction for ORDER BY clauses
50#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub enum OrderBy {
52    Asc,
53    Desc,
54}
55
56impl OrderBy {
57    /// Creates an ascending ORDER BY clause: "column ASC"
58    pub fn asc<'a, V, T>(column: T) -> SQL<'a, V>
59    where
60        V: SQLParam + 'a,
61        T: ToSQL<'a, V>,
62    {
63        column.to_sql().append(&Self::Asc)
64    }
65
66    /// Creates a descending ORDER BY clause: "column DESC"
67    pub fn desc<'a, V, T>(column: T) -> SQL<'a, V>
68    where
69        V: SQLParam + 'a,
70        T: ToSQL<'a, V>,
71    {
72        column.to_sql().append(&Self::Desc)
73    }
74}
75
76impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for OrderBy {
77    fn to_sql(&self) -> SQL<'a, V> {
78        let sql_str = match self {
79            OrderBy::Asc => "ASC",
80            OrderBy::Desc => "DESC",
81        };
82        SQL::raw(sql_str)
83    }
84}