geekorm_core/
lib.rs

1#![allow(dead_code)]
2#![forbid(unsafe_code)]
3#![deny(missing_docs)]
4#![doc = include_str!("../README.md")]
5#![doc(
6    html_logo_url = "https://raw.githubusercontent.com/42ByteLabs/geekorm/main/assets/geekorm.png"
7)]
8
9pub mod backends;
10pub mod builder;
11pub mod error;
12#[cfg(feature = "migrations")]
13pub mod migrations;
14pub mod queries;
15pub mod utils;
16
17pub use crate::backends::{GeekConnection, GeekConnector};
18#[cfg(feature = "migrations")]
19pub use crate::builder::alter::AlterQuery;
20pub use crate::builder::columns::{Column, Columns};
21pub use crate::builder::columntypes::{ColumnType, ColumnTypeOptions};
22pub use crate::builder::database::Database;
23pub use crate::builder::keys::{ForeignKey, PrimaryKey};
24pub use crate::builder::table::Table;
25pub use crate::builder::values::{Value, Values};
26pub use crate::error::Error;
27#[cfg(feature = "pagination")]
28pub use crate::queries::pages::Page;
29#[cfg(feature = "pagination")]
30pub use crate::queries::pagination::Pagination;
31pub use crate::queries::{Query, QueryBuilder};
32#[cfg(feature = "two-factor-auth")]
33pub use crate::utils::tfa::TwoFactorAuth;
34#[cfg(feature = "libsql")]
35pub use backends::libsql;
36#[cfg(feature = "migrations")]
37pub use migrations::Migration;
38
39/// Trait for basic creation of tables
40///
41/// This trait is used to define the table structure for the database.
42/// It is used to define the table name and the columns in the table.
43pub trait TableBuilder
44where
45    Self: Sized,
46{
47    /// Get the table struct
48    fn table() -> Table;
49
50    /// Get the table struct for the current instance
51    fn get_table(&self) -> Table;
52
53    /// Get the name of the table
54    fn table_name() -> String;
55}
56
57/// Trait for Building Queries
58pub trait QueryBuilderTrait
59where
60    Self: TableBuilder + Sized,
61{
62    /// Create a new table
63    fn query_create() -> QueryBuilder;
64
65    /// Select rows in the table
66    fn query_select() -> QueryBuilder {
67        QueryBuilder::select()
68    }
69
70    /// Select all rows in the table
71    fn query_all() -> Query {
72        Self::query_select()
73            .table(Self::table())
74            .build()
75            .expect("Failed to build SELECT ALL query")
76    }
77
78    /// Insert a row into the table
79    fn query_insert(item: &Self) -> Query;
80
81    /// Update a row in the table
82    fn query_update(item: &Self) -> Query;
83
84    /// Detete a row from the table
85    fn query_delete(item: &Self) -> Query;
86
87    /// Count the rows in the table
88    fn query_count() -> QueryBuilder;
89}
90
91/// Trait for Tables with a primary key
92///
93pub trait TablePrimaryKey
94where
95    Self: TableBuilder + QueryBuilderTrait + Sized,
96{
97    /// Get the name of the primary key column
98    fn primary_key() -> String;
99
100    /// Get the primary key column name
101    fn primary_key_value(&self) -> Value;
102
103    /// Select a row by the primary key
104    fn query_select_by_primary_key(pk: impl Into<Value>) -> Query {
105        Self::query_select()
106            .table(Self::table())
107            .where_eq(&Self::primary_key(), pk)
108            .build()
109            .expect("Failed to build SELECT BY PRIMARY KEY query")
110    }
111}
112
113/// Trait for converting a struct to SQLite
114///
115/// This does not need to be implemented by the user and is used internally
116pub trait ToSqlite {
117    /// Convert to generic SQLite (only use for some generic types)
118    fn to_sqlite(&self) -> String {
119        String::new()
120    }
121
122    /// Convert to SQLite for creating a table
123    #[allow(unused_variables)]
124    fn on_create(&self, query: &QueryBuilder) -> Result<String, Error> {
125        Ok(String::new())
126    }
127
128    /// Convert to SQLite for selecting a row
129    fn on_select(&self, query: &QueryBuilder) -> Result<String, Error> {
130        Err(Error::QueryBuilderError(
131            format!("on_select not implemented for table: {}", query.table),
132            String::from("on_select"),
133        ))
134    }
135
136    /// Convert to SQLite for inserting a row
137    fn on_insert(&self, query: &QueryBuilder) -> Result<(String, Values), Error> {
138        Err(Error::QueryBuilderError(
139            format!("on_insert not implemented for table: {}", query.table),
140            String::from("on_insert"),
141        ))
142    }
143
144    /// Convert to SQLite for updating a row
145    fn on_update(&self, query: &QueryBuilder) -> Result<(String, Values), Error> {
146        Err(Error::QueryBuilderError(
147            format!("on_update not implemented for table: {}", query.table),
148            String::from("on_update"),
149        ))
150    }
151
152    /// Convert to SQLite for deleting a row
153    fn on_delete(&self, query: &QueryBuilder) -> Result<(String, Values), Error> {
154        Err(Error::QueryBuilderError(
155            format!("on_delete not implemented for table: {}", query.table),
156            String::from("on_delete"),
157        ))
158    }
159
160    /// Convert to SQLite for altering a table
161    #[allow(unused_variables)]
162    #[cfg(feature = "migrations")]
163    fn on_alter(&self, query: &AlterQuery) -> Result<String, crate::Error> {
164        Err(Error::QueryBuilderError(
165            "on_alter not implemented for table".to_string(),
166            String::from("on_alter"),
167        ))
168    }
169}