drizzle_postgres/
common.rs

1use drizzle_core::{SQL, SQLEnumInfo, SQLIndexInfo, SQLSchemaType, ToSQL, traits::SQLParam};
2
3use crate::traits::PostgresTableInfo;
4
5/// The type of database object
6#[derive(Debug, Clone)]
7pub enum PostgresSchemaType {
8    /// A regular table
9    Table(&'static dyn PostgresTableInfo),
10    /// A view
11    View,
12    /// An index
13    Index(&'static dyn SQLIndexInfo),
14    /// A trigger
15    Trigger,
16    /// A database enum type (PostgreSQL)
17    Enum(&'static dyn SQLEnumInfo),
18}
19
20impl SQLSchemaType for PostgresSchemaType {}
21
22//------------------------------------------------------------------------------
23// Number Type
24//------------------------------------------------------------------------------
25
26/// Numeric type that can be either an integer or a floating point value
27#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
28pub enum Number {
29    /// Integer value
30    Integer(i64),
31    /// Floating point value
32    Real(f64),
33}
34
35impl Default for Number {
36    fn default() -> Self {
37        Self::Integer(Default::default())
38    }
39}
40
41impl From<i64> for Number {
42    fn from(value: i64) -> Self {
43        Self::Integer(value)
44    }
45}
46
47impl From<f64> for Number {
48    fn from(value: f64) -> Self {
49        Self::Real(value)
50    }
51}
52
53// Note: Generic From implementation is removed to avoid conflicts.
54// The table macro will generate specific implementations using PostgresEnumVisitor.
55#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
56pub enum JoinType {
57    #[default]
58    Join,
59    Inner,
60    Left,
61    Right,
62    Full,
63    Cross,
64}
65
66#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
67pub struct Join {
68    pub natural: bool,
69    pub join_type: JoinType,
70    pub outer: bool, // only meaningful for LEFT/RIGHT/FULL
71}
72
73impl Join {
74    pub fn new() -> Self {
75        Self::default()
76    }
77
78    pub fn natural(mut self) -> Self {
79        self.natural = true;
80        self
81    }
82
83    pub fn inner(mut self) -> Self {
84        self.join_type = JoinType::Inner;
85        self
86    }
87
88    pub fn left(mut self) -> Self {
89        self.join_type = JoinType::Left;
90        self
91    }
92
93    pub fn right(mut self) -> Self {
94        self.join_type = JoinType::Right;
95        self
96    }
97
98    pub fn full(mut self) -> Self {
99        self.join_type = JoinType::Full;
100        self
101    }
102
103    pub fn cross(mut self) -> Self {
104        self.join_type = JoinType::Cross;
105        self
106    }
107
108    pub fn outer(mut self) -> Self {
109        self.outer = true;
110        self
111    }
112}
113impl<'a, V: SQLParam + 'a> ToSQL<'a, V> for Join {
114    fn to_sql(&self) -> SQL<'a, V> {
115        let mut parts = Vec::new();
116
117        if self.natural {
118            parts.push("NATURAL");
119        }
120
121        match self.join_type {
122            JoinType::Inner => parts.push("INNER"),
123            JoinType::Left => {
124                parts.push("LEFT");
125                if self.outer {
126                    parts.push("OUTER");
127                }
128            }
129            JoinType::Right => {
130                parts.push("RIGHT");
131                if self.outer {
132                    parts.push("OUTER");
133                }
134            }
135            JoinType::Full => {
136                parts.push("FULL");
137                if self.outer {
138                    parts.push("OUTER");
139                }
140            }
141            JoinType::Cross => parts.push("CROSS"),
142            JoinType::Join => {}
143        }
144
145        parts.push("JOIN");
146        SQL::raw(parts.join(" "))
147    }
148}