Skip to content

Commit

Permalink
Implementing MariaDB (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjovanc authored Nov 20, 2024
2 parents a1645fb + 6c7204a commit e0190e5
Show file tree
Hide file tree
Showing 29 changed files with 2,865 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"njord_examples/mysql",
"njord_examples/oracle",
"njord_examples/mssql",
"njord_examples/mariadb",
"njord_examples/sqlite_cli"
]

Expand Down
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
services:
mariadb:
image: mariadb
container_name: njord_mariadb
environment:
MARIADB_ROOT_PASSWORD: njord_rootpwd
MARIADB_DATABASE: njord_db
MARIADB_USER: njord_user
MARIADB_PASSWORD: njord_password
ports:
- "3307:3306"
volumes:
- mariadb_data:/var/lib/mysql
- ./njord_examples/mariadb/init.sql:/docker-entrypoint-initdb.d/init.sql
- ./njord/db/test/mariadb.sql:/docker-entrypoint-initdb.d/tests.sql

mysql:
image: mysql:8.0
container_name: njord_mysql
Expand Down Expand Up @@ -64,3 +79,4 @@ volumes:
mysql_data:
oracle_data:
mssql_data:
mariadb_data:
Binary file added njord/.DS_Store
Binary file not shown.
5 changes: 5 additions & 0 deletions njord/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ sqlite = ["dep:rusqlite"]
mysql = ["dep:mysql"]
oracle = ["dep:oracle"]
mssql = ["dep:tiberius", "dep:tokio", "dep:tokio-util"]
mariadb = ["dep:mysql"]

[[test]]
name = "sqlite_tests"
Expand All @@ -56,3 +57,7 @@ path = "tests/oracle/mod.rs"
[[test]]
name = "mssql_tests"
path = "tests/mssql/mod.rs"

[[test]]
name = "mariadb_tests"
path = "tests/mariadb/mod.rs"
Binary file added njord/db/.DS_Store
Binary file not shown.
31 changes: 31 additions & 0 deletions njord/db/test/mariadb.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
DROP DATABASE IF EXISTS njord_db;

CREATE DATABASE njord_db;

USE njord_db;

-- Table: users
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY, -- Auto incrementing primary key for the user ID
username VARCHAR(255) NOT NULL, -- Username field
email VARCHAR(255) NOT NULL, -- Email field
address VARCHAR(255) -- Address field
);

-- Table: categories
CREATE TABLE categories (
id INT PRIMARY KEY, -- Primary key for categories
name VARCHAR(255) NOT NULL -- Name of the category
);

-- Table: products
CREATE TABLE products (
id INT PRIMARY KEY, -- Primary key for products
name VARCHAR(255) NOT NULL, -- Product name
description TEXT, -- Product description
price DECIMAL(10, 2) NOT NULL, -- Price with up to two decimal places
stock_quantity INT NOT NULL, -- Stock quantity
category_id INT NOT NULL, -- Foreign key to categories (one-to-one relationship)
discount DECIMAL(5, 2) DEFAULT 0.00, -- Discount field with default value
FOREIGN KEY (category_id) REFERENCES categories(id) -- Foreign key constraint to categories table
);
3 changes: 3 additions & 0 deletions njord/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ pub mod oracle;

#[cfg(feature = "mssql")]
pub mod mssql;

#[cfg(feature = "mariadb")]
pub mod mariadb;
166 changes: 166 additions & 0 deletions njord/src/mariadb/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//! BSD 3-Clause License
//!
//! Copyright (c) 2024
//! Marcus Cvjeticanin
//! Chase Willden
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions are met:
//!
//! 1. Redistributions of source code must retain the above copyright notice, this
//! list of conditions and the following disclaimer.
//!
//! 2. Redistributions in binary form must reproduce the above copyright notice,
//! this list of conditions and the following disclaimer in the documentation
//! and/or other materials provided with the distribution.
//!
//! 3. Neither the name of the copyright holder nor the names of its
//! contributors may be used to endorse or promote products derived from
//! this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
//! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::collections::HashMap;

use crate::{
condition::Condition,
mariadb::util::{
generate_limit_str, generate_offset_str, generate_order_by_str,
generate_where_condition_str, remove_quotes_and_backslashes,
},
};

use log::info;
use mysql::{prelude::Queryable, PooledConn};

use crate::table::Table;

/// Constructs a new DELETE query builder.
///
/// # Returns
///
/// A `DeleteQueryBuilder` instance.
pub fn delete<T: Table + Default>() -> DeleteQueryBuilder<'static, T> {
DeleteQueryBuilder::new()
}

/// A builder for constructing DELETE queries.
pub struct DeleteQueryBuilder<'a, T: Table + Default> {
table: Option<T>,
where_condition: Option<Condition<'a>>,
order_by: Option<HashMap<Vec<String>, String>>,
limit: Option<usize>,
offset: Option<usize>,
}

impl<'a, T: Table + Default> DeleteQueryBuilder<'a, T> {
/// Creates a new `DeleteQueryBuilder` instance.
pub fn new() -> Self {
DeleteQueryBuilder {
table: None,
where_condition: None,
order_by: None,
limit: None,
offset: None,
}
}

/// Sets the table from which to delete data.
///
/// # Arguments
///
/// * `table` - An instance of the table from which to delete data.
pub fn from(mut self, table: T) -> Self {
self.table = Some(table);
self
}

/// Sets the WHERE clause condition.
///
/// # Arguments
///
/// * `condition` - The condition to be applied in the WHERE clause.
pub fn where_clause(mut self, condition: Condition<'a>) -> Self {
self.where_condition = Some(condition);
self
}

/// Sets the ORDER BY clause columns and order direction.
///
/// # Arguments
///
/// * `col_and_order` - A hashmap representing the columns and their order directions.
pub fn order_by(mut self, col_and_order: HashMap<Vec<String>, String>) -> Self {
self.order_by = Some(col_and_order);
self
}

/// Sets the LIMIT clause for the query.
///
/// # Arguments
///
/// * `count` - The maximum number of rows to be deleted.
pub fn limit(mut self, count: usize) -> Self {
self.limit = Some(count);
self
}

/// Sets the OFFSET clause for the query.
///
/// # Arguments
///
/// * `offset` - The offset from which to start deleting rows.
pub fn offset(mut self, offset: usize) -> Self {
self.offset = Some(offset);
self
}

/// Builds and executes the DELETE query.
///
/// # Arguments
///
/// * `conn` - A `PooledConn` to the MariaDB database.
///
/// # Returns
///
/// A `Result` indicating success or failure of the deletion operation.
pub fn build(self, conn: &mut PooledConn) -> Result<(), String> {
let table_name = self
.table
.as_ref()
.map(|t| t.get_name().to_string())
.unwrap_or("".to_string());

// Sanitize table name from unwanted quotations or backslashes
let table_name_str = remove_quotes_and_backslashes(&table_name);
let where_condition_str = generate_where_condition_str(self.where_condition);
let order_by_str = generate_order_by_str(&self.order_by);
let limit_str = generate_limit_str(self.limit);
let offset_str = generate_offset_str(self.offset);

// Construct the query based on defined variables above
let query = format!(
"DELETE FROM {} {} {} {}",
table_name_str,
where_condition_str,
order_by_str,
format!("{} {}", limit_str, offset_str),
);

info!("{}", query);

// Execute SQL
let _ = conn.query_drop(&query.to_string());

Ok(())
}
}
52 changes: 52 additions & 0 deletions njord/src/mariadb/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! BSD 3-Clause License
//!
//! Copyright (c) 2024
//! Marcus Cvjeticanin
//! Chase Willden
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions are met:
//!
//! 1. Redistributions of source code must retain the above copyright notice, this
//! list of conditions and the following disclaimer.
//!
//! 2. Redistributions in binary form must reproduce the above copyright notice,
//! this list of conditions and the following disclaimer in the documentation
//! and/or other materials provided with the distribution.
//!
//! 3. Neither the name of the copyright holder nor the names of its
//! contributors may be used to endorse or promote products derived from
//! this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
//! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use mysql::Error as MariaDBLibError;

/// Represents errors that can occur during SQLite operations.
#[derive(Debug)]
pub enum MariaDBError {
/// Error that occurs during a SELECT operation.
SelectError(MariaDBLibError),
/// Error that occurs during an INSERT operation.
InsertError(MariaDBLibError),
/// Error that occurs during an UPDATE operation.
UpdateError(MariaDBLibError),
/// Error that occurs during a DELETE operation.
DeleteError(MariaDBLibError),
}

impl From<MariaDBLibError> for MariaDBError {
/// Converts a `rusqlite::Error` into a `MariaDBError`.
fn from(error: MariaDBLibError) -> Self {
MariaDBError::InsertError(error)
}
}
Loading

0 comments on commit e0190e5

Please sign in to comment.