Skip to content

Commit

Permalink
Cleanup and rust docs (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjovanc authored Nov 19, 2024
2 parents ab7a95a + f17f9e7 commit 13ac4fb
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 33 deletions.
11 changes: 10 additions & 1 deletion njord/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ pub trait Table {
/// Set the values of the columns.
fn set_column_value(&mut self, column: &str, value: &str);

// Check if a given field is of AutoincrementPrimaryKey
/// Determines if the provided value represents an auto-incrementing primary key.
///
/// # Arguments
///
/// * `value` - A string representing the value to check.
///
/// # Returns
///
/// * `true` if the value indicates an auto-incrementing primary key.
/// * `false` otherwise.
fn is_auto_increment_primary_key(&self, value: &str) -> bool;
}

Expand Down
70 changes: 69 additions & 1 deletion njord/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,90 @@ use std::sync::Arc;
use crate::condition::Condition;
use crate::table::Table;

#[derive(Clone)]
/// Represents the type of SQL join.
#[derive(Clone, Debug)]
pub enum JoinType {
/// Inner Join - Includes only matching rows from both tables.
Inner,
/// Left Join - Includes all rows from the left table and matching rows from the right table.
Left,
/// Right Join - Includes all rows from the right table and matching rows from the left table.
Right,
/// Full Join - Includes all rows from both tables.
Full,
}

/// Represents a join operation in an SQL query.
#[derive(Clone)]
pub struct Join<'a> {
/// The type of join (e.g., Inner, Left, Right, Full).
pub join_type: JoinType,
/// The table involved in the join.
pub table: Arc<dyn Table>,
/// The condition specifying how the tables are joined.
pub on_condition: Condition<'a>,
}

impl<'a> Join<'a> {
/// Creates a new `Join` instance representing an SQL join operation.
///
/// # Arguments
///
/// * `join_type` - The type of join to perform, such as `Inner`, `Left`, `Right`, or `Full`.
/// * `table` - A reference to the table being joined, wrapped in an `Arc<dyn Table>` for shared ownership.
/// * `on_condition` - A `Condition` specifying the criteria for joining the tables.
///
/// # Returns
///
/// A new `Join` instance representing the specified join operation.
///
/// # Example
///
/// ```rust
/// use std::sync::Arc;
/// use njord::condition::{Condition, Value};
/// use njord::util::{Join, JoinType};
/// use njord_derive::Table;
///
/// #[derive(Table)]
/// struct Categories {
/// id: i32,
/// name: String,
/// }
///
/// #[derive(Table)]
/// struct Products {
/// id: i32,
/// category_id: i32,
/// name: String,
/// price: f64,
/// }
///
/// fn main() {
/// let categories = Categories {
/// id: 1,
/// name: "Electronics".to_string(),
/// };
///
/// let products = Products {
/// id: 101,
/// category_id: 1,
/// name: "Smartphone".to_string(),
/// price: 699.99,
/// };
///
/// let join_condition = Condition::Eq(
/// "categories.id".to_string(),
/// Value::Literal("products.category_id".to_string()),
/// );
///
/// let join = Join::new(
/// JoinType::Inner,
/// Arc::new(products),
/// join_condition,
/// );
/// }
/// ```
pub fn new(join_type: JoinType, table: Arc<dyn Table>, on_condition: Condition<'a>) -> Self {
Join {
join_type,
Expand Down
77 changes: 46 additions & 31 deletions njord_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,33 @@ mod util;

/// Derives the `Table` trait for a struct.
///
/// This procedural macro generates implementations of the `Table` trait for a struct.
/// The `Table` trait provides methods for working with database tables.
/// This procedural macro generates an implementation of the `Table` trait for a struct,
/// enabling interaction with database tables. It derives functionality based on the struct's
/// field names and types, automatically mapping them to corresponding SQL column definitions.
///
/// This macro will generate implementations the `Table` trait
/// based on the struct's field names and types.
/// # Example
///
/// ```rust
/// use njord_derive::Table;
///
/// #[derive(Table)]
/// #[table_name = "users"]
/// struct User {
/// id: i32,
/// name: String,
/// email: Option<String>,
/// }
/// ```
///
/// The `Table` trait will provide:
/// - `get_name()` - Returns the table name.
/// - `get_columns()` - Returns column names and their SQL types.
/// - `get_column_fields()` - Returns the field names as a vector.
/// - `get_column_values()` - Returns the field values as strings.
/// - `set_column_value()` - Updates a field value by column name.
/// - `is_auto_increment_primary_key()` - Checks if a value is an auto-increment primary key.
///
/// Additional traits like `Default`, `Display`, and `FromStr` are also implemented if applicable.
#[proc_macro_derive(Table, attributes(table_name))]
pub fn table_derive(input: TokenStream) -> TokenStream {
let cloned_input = input.clone();
Expand Down Expand Up @@ -221,33 +243,26 @@ pub fn table_derive(input: TokenStream) -> TokenStream {
output.into()
}

/// The procedural macro `sql!` takes a SQL-like syntax and transforms it into a string.
// #[proc_macro]
// pub fn sql(input: TokenStream) -> TokenStream {
// /*
// GOAL:
// let id = 1;

// let query = sql! {
// SELECT *
// FROM user
// WHERE id = {id}
// };
// */
// let input_string = input.to_string();

// // Remove the outer quotes
// let input_string = input_string.trim_matches(|c| c == '"' || c == '`' || c == '\'');

// let expanded = quote! {
// {
// #input_string
// }
// };

// expanded.into()
// }

/// A procedural macro `sql!` that takes SQL-like syntax and transforms it into a formatted string.
///
/// # Example
///
/// ```rust
/// use njord_derive::sql;
/// let id = 1;
///
/// let query = sql! {
/// SELECT * FROM user WHERE id = {id}
/// };
/// assert_eq!(query, "SELECT * FROM user WHERE id = 1");
/// ```
///
/// This macro supports embedding expressions within SQL queries, ensuring proper formatting
/// for identifiers and values.
///
/// Note:
/// - Use `{}` syntax for expressions to embed Rust variables.
/// - Identifiers are automatically quoted if necessary.
#[proc_macro]
pub fn sql(input: TokenStream) -> TokenStream {
let input: proc_macro2::TokenStream = input.into();
Expand Down

0 comments on commit 13ac4fb

Please sign in to comment.