1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
//! The crate `derive_sql` is articulated around two traits.
//!
//! The trait `Sqlable` that defines a set of operation for
//! interacting with SQL tables:
//! - `count` to provide a count of the number of items in the table.
//! - `select` to return an array of the items in the table.
//! - `insert` to insert a new item in the table.
//! - `update` to update an existing item(s) with the values of the provided item.
//! - `delete` to delete items in the table.
//! - `delete_table` to drop the table.
//!
//! Implementation of the trait should allow the user of the trait to interact with the table via the above
//! interface...
//!
//! The trait `Selectable` provides a possible interface for selector queries
//! used in the `Sqlable` trait. It is a possible option - but not limited
//! to it as the `Sqlable` trait uses an associated type for `Selector`.
//!
//! This crate includes the derive macro `DeriveSqlite` [when compiled with the feature `--features sqlite`]
//! which provides an implementation of the `Sqlable` trait for SQLite as a wrapper around the `rusqlite`
//! crate.
//!
//! Please see examples here and the `DeriveSqlite` documentation.
//!
//! # Features:
//! - `sqlite` provide a derive macro to implement the `Sqlable` trait for SQLite database (implemented as a wrapper around the `rusqlite` crate);
//!
//! # Mocking:
//! The example of code below shows how the trait can be mocked using `mockall` for unit testing purposes. The
//! example uses `mockall` external trait functionality - ie works in a code using this crate as a dependency.
//! Note: one has to explicitely nominates the associated type in the method definitions.
//!
//! ```rust
//! mockall::mock! {
//! SqlableStruct {}
//! impl derive_sql::Sqlable for SqlableStruct {
//! type Item = String;
//! type Error = Box<dyn std::error::Error>;
//! type Selector = ();
//!
//! fn count(&self, s: ()) -> Result<usize, Box<dyn std::error::Error>>;
//! fn select(&self, s: ()) -> Result<Vec<String>, Box<dyn std::error::Error>>;
//! fn insert(&mut self, item: String) -> Result<String, Box<dyn std::error::Error>>;
//! fn update(&mut self, s: (), item: String) -> Result<String, Box<dyn std::error::Error>>;
//! fn delete(&mut self, s: ()) -> Result<(), Box<dyn std::error::Error>>;
//! fn delete_table(&mut self) -> Result<(), Box<dyn std::error::Error>>;
//! }
//! }
//!
//! fn my_function<S>(s: &mut S) -> Result<usize, Box<dyn std::error::Error>>
//! where S: derive_sql::Sqlable<Selector = (), Item = String, Error = Box<dyn std::error::Error>>,
//! {
//! let _ = s.insert("an item".to_string())?;
//! Ok(s.count(())?)
//! }
//!
//! // Create mock
//! let mut mock = MockSqlableStruct::new();
//! // Configure mock
//! mock.expect_insert()
//! .with(mockall::predicate::eq("an item".to_string()))
//! .returning(|s| Ok(s));
//! mock.expect_count().returning(|_| Ok(11));
//!
//! // Check result
//! assert!(matches!(my_function(&mut mock), Ok(11)));
//!
//! ```
//!
//!
mod sqlable; pub use sqlable::Sqlable;
mod selectable;
mod proxy;
#[cfg(feature="sqlite")]
pub use proxy::sqlite;
#[cfg(feature="mysql")]
pub use proxy::mysql;
pub use selectable::Selectable;
/// Convenient struct for implementing a simple filter, ie a struct that generates the content of a simple `WHERE a = value` clause
pub use selectable::SimpleFilter;
/// Convenient struct for implementing a limit, ie a struct that generates the content of a `LIMIT value` clause
pub use selectable::SimpleLimit;
/// Convenient struct for implementing an offset, ie a struct that generates the content of an `OFFSET value` clause
pub use selectable::SimpleOffset;
/// Convenient struct for implementing an order by, ie a struct that generates the content of an `ORDER BY value ASC|DESC` clause
pub use selectable::{SimpleOrder, Order};
#[cfg(feature="sqlite")]
/// Derive macro to implement the `Sqlable` trait for a struct with named fields so that instances of the struct
/// can be saved, queried, stored to/from an SQLite database. Uses `rusqlite`. Requires `--features sqlite`.
pub use derive_sql_sqlite::DeriveSqlite;
#[cfg(feature="mysql")]
/// Derive macro to implement the `Sqlable` trait for a struct with named fields so that instances of the struct
/// can be saved, queried, stored to/from a MySQL database. Uses `mysql`. Requires `--features mysql`.
pub use derive_sql_mysql::DeriveMysql;
mod error;
pub use error::DeriveSqlResult;
pub use error::Error;