Skip to main content

oxide_sql_core/schema/
mod.rs

1//! Schema traits for type-safe table and column definitions.
2//!
3//! This module provides traits that are implemented by the `#[derive(Table)]`
4//! macro to enable compile-time checked SQL queries.
5
6/// Trait for table metadata.
7///
8/// Implemented by types generated from `#[derive(Table)]` to provide
9/// table-level information.
10pub trait Table {
11    /// The row type (the original struct).
12    type Row;
13
14    /// The SQL table name.
15    const NAME: &'static str;
16
17    /// List of all column names.
18    const COLUMNS: &'static [&'static str];
19
20    /// The primary key column name, if any.
21    const PRIMARY_KEY: Option<&'static str>;
22}
23
24/// Trait for column metadata.
25///
26/// Implemented by column types generated from `#[derive(Table)]` to provide
27/// column-level information and enable type-safe queries.
28pub trait Column {
29    /// The table this column belongs to.
30    type Table: Table;
31
32    /// The Rust type of this column.
33    type Type;
34
35    /// The SQL column name.
36    const NAME: &'static str;
37
38    /// Whether this column is nullable.
39    const NULLABLE: bool;
40
41    /// Whether this column is the primary key.
42    const PRIMARY_KEY: bool;
43}
44
45/// Marker trait for columns with a specific Rust type.
46///
47/// Used for compile-time type checking of values in queries.
48pub trait TypedColumn<T>: Column<Type = T> {}
49
50/// Trait for selecting specific columns from a table.
51///
52/// Implemented for tuples of column types to enable type-safe SELECT queries.
53pub trait Selectable<T: Table> {
54    /// Returns the column names to select.
55    fn column_names() -> &'static [&'static str];
56}
57
58// Implement Selectable for single columns
59impl<T: Table, C: Column<Table = T>> Selectable<T> for C {
60    fn column_names() -> &'static [&'static str] {
61        // Return as a slice containing just this column
62        // This is a compile-time constant
63        &[C::NAME]
64    }
65}
66
67// Implement Selectable for tuples of columns (up to 12)
68macro_rules! impl_selectable_tuple {
69    ($($idx:tt: $col:ident),+) => {
70        impl<T: Table, $($col: Column<Table = T>),+> Selectable<T> for ($($col,)+) {
71            fn column_names() -> &'static [&'static str] {
72                &[$($col::NAME),+]
73            }
74        }
75    };
76}
77
78impl_selectable_tuple!(0: C0);
79impl_selectable_tuple!(0: C0, 1: C1);
80impl_selectable_tuple!(0: C0, 1: C1, 2: C2);
81impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3);
82impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4);
83impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5);
84impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6);
85impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7);
86impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8);
87impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9);
88impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10);
89impl_selectable_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11);