Skip to content

Commit

Permalink
resolves #159 - Added mysql subquery support. Added alias to subquery
Browse files Browse the repository at this point in the history
  • Loading branch information
chaseWillden committed Oct 21, 2024
1 parent 7aab98c commit d114a7a
Show file tree
Hide file tree
Showing 11 changed files with 359 additions and 190 deletions.
25 changes: 14 additions & 11 deletions njord/src/column.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,56 @@
use crate::{sqlite::select::SelectQueryBuilder, table::Table};
use crate::query::QueryBuilder;

/// Define the enum to represent a column as either a String or SelectQueryBuilder
#[derive(Clone)]
pub enum Column<'a, T: Table + Default> {
pub enum Column<'a> {
Text(String),
SubQuery(SelectQueryBuilder<'a, T>),
// Subquery with alias
SubQuery(Box<dyn QueryBuilder<'a> + 'a>, String),
}

// Implement the build method to convert the enum to a string
impl<'a, T: Table + Default> Column<'a, T> {
impl<'a> Column<'a> {
/// Helper function to convert the columns to a string
pub fn build(&self) -> String {
match self {
Column::Text(text) => text.clone(),
Column::SubQuery(sub_query) => "(".to_string() + &sub_query.build_query() + ")",
Column::SubQuery(sub_query, alias) => {
"(".to_string() + &sub_query.to_sql() + ") AS " + alias
}
}
}
}

// Implementation of fmt::Display for Column
impl<'a, T: Table + Default> std::fmt::Display for Column<'a, T> {
impl<'a> std::fmt::Display for Column<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.build())
}
}

// Implementation of PartialEq for Column
impl<'a, T: Table + Default> PartialEq for Column<'a, T> {
impl<'a> PartialEq for Column<'a> {
fn eq(&self, other: &Self) -> bool {
self.build() == other.build()
}
}

// Implementation of PartialEq<String> for Column
impl<'a, T: Table + Default> PartialEq<String> for Column<'a, T> {
impl<'a> PartialEq<String> for Column<'a> {
fn eq(&self, other: &String) -> bool {
match self {
Column::Text(text) => text == other,
Column::SubQuery(sub_query) => sub_query.build_query() == *other,
Column::SubQuery(sub_query, _) => sub_query.to_sql() == *other,
}
}
}

// Implementation of PartialEq<&str> for Column
impl<'a, T: Table + Default> PartialEq<&str> for Column<'a, T> {
impl<'a> PartialEq<&str> for Column<'a> {
fn eq(&self, other: &&str) -> bool {
match self {
Column::Text(text) => text == other,
Column::SubQuery(sub_query) => sub_query.build_query() == *other,
Column::SubQuery(sub_query, _) => sub_query.to_sql() == *other,
}
}
}
4 changes: 2 additions & 2 deletions njord/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use serde::{Deserialize, Deserializer};
/// # Type Parameters
///
/// * `T` - The type of the primary key value, which can be any type.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct PrimaryKey<T>(T);

impl<T> PrimaryKey<T> {
Expand Down Expand Up @@ -216,4 +216,4 @@ impl<T: PartialEq> PartialEq for AutoIncrementPrimaryKey<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
}
8 changes: 4 additions & 4 deletions njord/src/mysql/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ use crate::util::{Join, JoinType};
/// # Returns
///
/// A `SelectQueryBuilder` instance.
pub fn select<T: Table + Default>(columns: Vec<Column<T>>) -> SelectQueryBuilder<T> {
pub fn select<T: Table + Default>(columns: Vec<Column>) -> SelectQueryBuilder<T> {
SelectQueryBuilder::new(columns)
}

/// A builder for constructing SELECT queries.
#[derive(Clone)]
pub struct SelectQueryBuilder<'a, T: Table + Default> {
table: Option<T>,
columns: Vec<Column<'a, T>>,
columns: Vec<Column<'a>>,
where_condition: Option<Condition<'a>>,
distinct: bool,
group_by: Option<Vec<String>>,
Expand All @@ -85,7 +85,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> {
///
/// * `conn` - A `PooledConn` to the MySql database.
/// * `columns` - A vector of strings representing the columns to be selected.
pub fn new(columns: Vec<Column<'a, T>>) -> Self {
pub fn new(columns: Vec<Column<'a>>) -> Self {
SelectQueryBuilder {
table: None,
columns,
Expand All @@ -107,7 +107,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> {
/// # Arguments
///
/// * `columns` - A vector of strings representing the columns to be selected.
pub fn select(mut self, columns: Vec<Column<'a, T>>) -> Self {
pub fn select(mut self, columns: Vec<Column<'a>>) -> Self {
self.columns = columns;
self
}
Expand Down
8 changes: 4 additions & 4 deletions njord/src/sqlite/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use crate::util::{Join, JoinType};
/// A `SelectQueryBuilder` instance.
pub fn select<'a, T: Table + Default>(
conn: &'a Connection,
columns: Vec<Column<'a, T>>,
columns: Vec<Column<'a>>,
) -> SelectQueryBuilder<'a, T> {
SelectQueryBuilder::new(conn, columns)
}
Expand All @@ -67,7 +67,7 @@ pub fn select<'a, T: Table + Default>(
pub struct SelectQueryBuilder<'a, T: Table + Default> {
conn: &'a Connection,
table: Option<T>,
columns: Vec<Column<'a, T>>,
columns: Vec<Column<'a>>,
where_condition: Option<Condition<'a>>,
distinct: bool,
group_by: Option<Vec<String>>,
Expand All @@ -87,7 +87,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> {
///
/// * `conn` - A `rusqlite::Connection` to the SQLite database.
/// * `columns` - A vector of strings representing the columns to be selected.
pub fn new(conn: &'a Connection, columns: Vec<Column<'a, T>>) -> Self {
pub fn new(conn: &'a Connection, columns: Vec<Column<'a>>) -> Self {
SelectQueryBuilder {
conn,
table: None,
Expand All @@ -110,7 +110,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> {
/// # Arguments
///
/// * `columns` - A vector of strings representing the columns to be selected.
pub fn select(mut self, columns: Vec<Column<'a, T>>) -> Self {
pub fn select(mut self, columns: Vec<Column<'a>>) -> Self {
self.columns = columns;
self
}
Expand Down
26 changes: 19 additions & 7 deletions njord/tests/mysql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod select_joins_test;
mod select_test;
mod update_test;

use njord::keys::{AutoIncrementPrimaryKey, PrimaryKey};
use njord::keys::AutoIncrementPrimaryKey;
use njord::table::Table;
use njord_derive::Table;

Expand All @@ -18,7 +18,7 @@ pub struct User {
pub address: String,
}

#[derive(Table)]
#[derive(Table, Clone)]
#[table_name = "users"]
pub struct UserWithSubQuery {
pub id: AutoIncrementPrimaryKey<usize>,
Expand All @@ -28,22 +28,23 @@ pub struct UserWithSubQuery {
pub additional_address: String,
}

#[derive(Table)]
#[derive(Table, Clone)]
#[table_name = "categories"]
pub struct Category {
pub id: PrimaryKey<usize>,
pub id: AutoIncrementPrimaryKey<usize>,
pub name: String,
}

#[derive(Table)]
#[derive(Table, Clone)]
#[table_name = "products"]
pub struct Product {
pub id: PrimaryKey<usize>,
pub id: AutoIncrementPrimaryKey<usize>,
pub name: String,
pub description: String,
pub price: f64,
pub stock_quantity: usize,
pub category: Category, // one-to-one relationship
// pub category: Category, // one-to-one relationship
pub category_id: usize,
pub discount: f64,
}

Expand All @@ -54,3 +55,14 @@ pub struct UsersWithJoin {
price: f64,
name: String,
}

#[derive(Table)]
#[table_name = "categories"]
pub struct CategoryWithJoin {
name: String,
description: String,
price: f64,
stock_quantity: usize,
discount: f64,
category_name: String,
}
Loading

0 comments on commit d114a7a

Please sign in to comment.