Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolves #159 - Added mysql subquery support. Added alias to subquery #173

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading