drizzle_sqlite/
common.rs

1use drizzle_core::traits::SQLViewInfo;
2use drizzle_core::{SQLIndexInfo, SQLSchemaType};
3
4use crate::traits::SQLiteTableInfo;
5
6/// The type of database object
7#[derive(Debug, Clone)]
8pub enum SQLiteSchemaType {
9    /// A regular table
10    Table(&'static dyn SQLiteTableInfo),
11    /// A view
12    View(&'static dyn SQLViewInfo),
13    /// An index
14    Index(&'static dyn SQLIndexInfo),
15    /// A trigger
16    Trigger,
17}
18
19impl SQLSchemaType for SQLiteSchemaType {}
20
21//------------------------------------------------------------------------------
22// Number Type
23//------------------------------------------------------------------------------
24
25/// Numeric type that can be either an integer or a floating point value
26#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
27pub enum Number {
28    /// Integer value
29    Integer(i64),
30    /// Floating point value
31    Real(f64),
32}
33
34impl Default for Number {
35    fn default() -> Self {
36        Self::Integer(Default::default())
37    }
38}
39
40impl From<i64> for Number {
41    fn from(value: i64) -> Self {
42        Self::Integer(value)
43    }
44}
45
46impl From<f64> for Number {
47    fn from(value: f64) -> Self {
48        Self::Real(value)
49    }
50}
51
52// Note: Generic From implementation is removed to avoid conflicts.
53// The table macro will generate specific implementations using SQLiteEnumVisitor.
54
55// Re-export Join from core
56pub use drizzle_core::{Join, JoinType};
57
58//------------------------------------------------------------------------------
59// Tests
60//------------------------------------------------------------------------------
61
62#[cfg(any(feature = "turso", feature = "libsql", feature = "rusqlite"))]
63#[cfg(test)]
64mod tests {
65    use crate::common::{Join, JoinType, Number};
66    use crate::*;
67    use std::borrow::Cow;
68
69    #[test]
70    fn test_into_sqlite_value_impls() {
71        assert_eq!(
72            SQLiteValue::from("hello"),
73            SQLiteValue::Text(Cow::Borrowed("hello"))
74        );
75        assert_eq!(
76            SQLiteValue::from(String::from("world")),
77            SQLiteValue::Text(Cow::Owned("world".to_string()))
78        );
79        assert_eq!(SQLiteValue::from(42i64), SQLiteValue::Integer(42));
80        assert_eq!(SQLiteValue::from(123i32), SQLiteValue::Integer(123));
81        assert_eq!(SQLiteValue::from(3.14f64), SQLiteValue::Real(3.14));
82        assert_eq!(SQLiteValue::from(true), SQLiteValue::Integer(1));
83        assert_eq!(SQLiteValue::from(false), SQLiteValue::Integer(0));
84        let blob_vec: Vec<u8> = vec![1, 2, 3];
85        assert_eq!(
86            SQLiteValue::from(blob_vec.clone()),
87            SQLiteValue::Blob(Cow::Owned(blob_vec.clone()))
88        );
89        let blob_slice: &[u8] = &[4, 5, 6];
90        assert_eq!(
91            SQLiteValue::from(blob_slice),
92            SQLiteValue::Blob(Cow::Borrowed(blob_slice))
93        );
94        assert_eq!(SQLiteValue::from(Option::<String>::None), SQLiteValue::Null);
95        assert_eq!(
96            SQLiteValue::from(Some("optional")),
97            SQLiteValue::Text(Cow::Borrowed("optional"))
98        );
99    }
100
101    #[test]
102    fn test_number_enum() {
103        let int_num = Number::Integer(42);
104        let real_num = Number::Real(3.14);
105
106        assert_eq!(int_num, Number::from(42i64));
107        assert_eq!(real_num, Number::from(3.14f64));
108        assert_eq!(Number::default(), Number::Integer(0));
109    }
110
111    #[test]
112    fn test_join_type_and_join() {
113        let join = Join::new().inner().natural();
114        assert_eq!(join.join_type, JoinType::Inner);
115        assert_eq!(join.natural, true);
116        assert_eq!(join.outer, false);
117
118        let outer_join = Join::new().left().outer();
119        assert_eq!(outer_join.join_type, JoinType::Left);
120        assert_eq!(outer_join.outer, true);
121
122        let cross_join = Join::new().cross();
123        assert_eq!(cross_join.join_type, JoinType::Cross);
124    }
125
126    #[test]
127    fn test_join_to_sql() {
128        use drizzle_core::{SQL, ToSQL};
129
130        let inner_join = Join::new().inner();
131        let sql: SQL<SQLiteValue> = inner_join.to_sql();
132        assert_eq!(sql.sql(), "INNER JOIN");
133
134        let natural_left_outer = Join::new().natural().left().outer();
135        let sql: SQL<SQLiteValue> = natural_left_outer.to_sql();
136        assert_eq!(sql.sql(), "NATURAL LEFT OUTER JOIN");
137
138        let cross_join = Join::new().cross();
139        let sql: SQL<SQLiteValue> = cross_join.to_sql();
140        assert_eq!(sql.sql(), "CROSS JOIN");
141    }
142}