Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .github/workflows/pull-requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ jobs:
with:
command: test
args: --features sqlite
- uses: actions-rs/cargo@v1
name: Test MySQL syntax
with:
command: test
args: --features mysql
14 changes: 11 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@ description = "Write SQL queries in a simple and composable way"
documentation = "https://docs.rs/sql_query_builder"
repository = "https://github.com/belchior/sql_query_builder"
authors = ["Belchior Oliveira <belchior@outlook.com>"]
version = "2.4.2"
version = "2.5.2"
edition = "2021"
rust-version = "1.62"
license = "MIT"
keywords = ["sql", "query", "database", "postgres", "sqlite"]
keywords = ["sql", "query", "postgres", "sqlite", "mysql"]

[features]
#! SQL Query Builder comes with the following optional features:

## enable Postgres syntax
postgresql = []

## enable SQLite syntax
sqlite = []

## enable MySQL syntax
mysql = []

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
features = ["postgresql", "sqlite"]
features = ["postgresql", "sqlite", "mysql"]

[dev-dependencies]
pretty_assertions = "=1.4.0"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ SELECT id, login FROM users WHERE login = $1 AND is_admin = true
SQL Query Builder comes with the following optional features:
- `postgresql` enable Postgres syntax
- `sqlite` enable SQLite syntax
- `mysql` enable MySQL syntax

You can enable features like

Expand Down
21 changes: 19 additions & 2 deletions scripts/coverage_test.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/bin/sh

# Prerequisites
# cargo install rustfilt cargo-binutils
# rustup override set 1.82.0
# cargo install rustfilt@0.2.1 cargo-binutils@0.3.6
# rustup component add llvm-tools-preview
clear

PKG_NAME="$(grep 'name\s*=\s*"' Cargo.toml | sed -E 's/.*"(.*)"/\1/')"
COVERAGE_OUTPUT="coverage"
Expand All @@ -11,12 +13,27 @@ COVERAGE_TARGET="target/coverage"
rm -fr "$COVERAGE_TARGET"
mkdir -p "$COVERAGE_OUTPUT"
mkdir -p "$COVERAGE_TARGET"
clear

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing SQL Standard"
echo "-- ------------------------------------------------------------------------------\n"
RUSTFLAGS="-C instrument-coverage" LLVM_PROFILE_FILE="$COVERAGE_TARGET/$PKG_NAME-%m.profraw" cargo test --target-dir $COVERAGE_TARGET;

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing PostgreSQL syntax"
echo "-- ------------------------------------------------------------------------------\n"
RUSTFLAGS="-C instrument-coverage" LLVM_PROFILE_FILE="$COVERAGE_TARGET/$PKG_NAME-%m.profraw" cargo test --target-dir $COVERAGE_TARGET --features postgresql;

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing SQLite syntax"
echo "-- ------------------------------------------------------------------------------\n"
RUSTFLAGS="-C instrument-coverage" LLVM_PROFILE_FILE="$COVERAGE_TARGET/$PKG_NAME-%m.profraw" cargo test --target-dir $COVERAGE_TARGET --features sqlite;

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing MySQL syntax"
echo "-- ------------------------------------------------------------------------------\n"
RUSTFLAGS="-C instrument-coverage" LLVM_PROFILE_FILE="$COVERAGE_TARGET/$PKG_NAME-%m.profraw" cargo test --target-dir $COVERAGE_TARGET --features mysql;

cargo profdata -- merge -sparse $COVERAGE_TARGET/$PKG_NAME-*.profraw -o $COVERAGE_TARGET/$PKG_NAME.profdata;

OBJECT_PATH_LIB="$(ls $COVERAGE_TARGET/debug/deps/$PKG_NAME-???????????????? | xargs -I {} echo '--object {}')"
Expand Down
19 changes: 18 additions & 1 deletion scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
#!/bin/sh

test_names=$(git status -s | grep tests/ | sed -e 's/.* //' -e 's/tests\//--test /' -e 's/.rs//' | tr '\n' ' ')
test_names=$(git status -s | grep 'A[[:space:]]*tests/\|M[[:space:]]*tests/' | sed -e 's/.* //' -e 's/tests\//--test /' -e 's/\.rs//' | tr '\n' ' ')

clear
echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing SQL Standard"
echo "-- ------------------------------------------------------------------------------\n"
cargo test $test_names

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing PostgreSQL syntax"
echo "-- ------------------------------------------------------------------------------\n"
cargo test $test_names --features postgresql

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing SQLite syntax"
echo "-- ------------------------------------------------------------------------------\n"
cargo test $test_names --features sqlite
cargo test $test_names --features mysql

echo "\n-- ------------------------------------------------------------------------------"
echo "-- Testing MySQL syntax"
echo "-- ------------------------------------------------------------------------------\n"
cargo test $test_names --features mysql

# run only one test
# cargo test --features sqlite --test name_of_the_test_file name_of_the_test -- --nocapture --color always
2 changes: 1 addition & 1 deletion scripts/watch_doc.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

doc_path=$(realpath ./target/doc/sql_query_builder/index.html)
doc_path=$(pwd)/target/doc/sql_query_builder/index.html
c_blue='\033[34;1m'
c_no='\033[0m'

Expand Down
5 changes: 3 additions & 2 deletions scripts/watch_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
# ./scripts/watch_test.sh all # will enable all feature
# ./scripts/watch_test.sh postgresql # will enable only the postgresql feature

all_features='postgresql sqlite'
clear
all_features='postgresql sqlite mysql'
features=''
test_names=$(git status -s | grep tests/ | sed -e 's/.* //' -e 's/tests\//--test /' -e 's/.rs//' | tr '\n' ' ')
test_names=$(git status -s | grep 'A[[:space:]]*tests/\|M[[:space:]]*tests/' | sed -e 's/.* //' -e 's/tests\//--test /' -e 's/\.rs//' | tr '\n' ' ')

case "$@" in
"") features="";;
Expand Down
64 changes: 54 additions & 10 deletions src/alter_table/alter_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@ impl AlterTable {
/// ADD COLUMN age int not null
/// ```
///
///
/// Available on crate feature `postgresql` only.
/// ### Available on crate feature `postgresql` and `mysql` only.
/// Multiples call of this method will build the SQL respecting the order of the calls
///
/// ### Example
///
/// ```
/// # #[cfg(any(feature = "postgresql"))]
/// # #[cfg(any(feature = "postgresql", feature = "mysql"))]
/// # {
/// # use sql_query_builder as sql;
/// let query = sql::AlterTable::new()
Expand Down Expand Up @@ -161,13 +160,13 @@ impl AlterTable {
/// DROP column login
/// ```
///
/// Available on crate feature `postgresql` only.
/// ### Available on crate feature `postgresql` and `mysql` only.
/// Multiples call of this method will build the SQL respecting the order of the calls
///
/// ### Example
///
/// ```
/// # #[cfg(any(feature = "postgresql"))]
/// # #[cfg(any(feature = "postgresql", feature = "mysql"))]
/// # {
/// # use sql_query_builder as sql;
/// let query = sql::AlterTable::new()
Expand Down Expand Up @@ -284,16 +283,17 @@ impl AlterTable {
}
}

#[cfg(any(doc, feature = "postgresql", feature = "sqlite"))]
#[cfg(any(doc, feature = "postgresql", feature = "sqlite", feature = "mysql"))]
#[cfg_attr(docsrs, doc(cfg(feature = "postgresql")))]
#[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
#[cfg_attr(docsrs, doc(cfg(feature = "mysql")))]
impl AlterTable {
/// Changes the column name or table constraints, this method overrides the previous value
///
/// ### Example
///
///```
/// # #[cfg(any(feature = "postgresql", feature = "sqlite"))]
/// # #[cfg(any(feature = "postgresql", feature = "sqlite", feature = "mysql"))]
/// # {
/// # use sql_query_builder as sql;
/// let query = sql::AlterTable::new()
Expand All @@ -311,11 +311,54 @@ impl AlterTable {
/// ```sql
/// ALTER TABLE users RENAME COLUMN address TO city
/// ```
///
/// ### Available on crate feature `mysql` only.
/// Changes the table name, column name or table constraints,
/// multiples call of this method will build the SQL respecting the order of the calls
///
/// ### Example
///
///```
/// # #[cfg(feature = "mysql")]
/// # {
/// # use sql_query_builder as sql;
/// let query = sql::AlterTable::new()
/// .alter_table("users")
/// .rename("TO users_old")
/// .rename("COLUMN name TO full_name")
/// .to_string();
///
/// # let expected = "ALTER TABLE users RENAME TO users_old, RENAME COLUMN name TO full_name";
/// # assert_eq!(expected, query);
/// # }
/// ```
///
/// Outputs
///
/// ```sql
/// ALTER TABLE users
/// RENAME TO users_old,
/// RENAME COLUMN name TO full_name
/// ```
pub fn rename(mut self, action: &str) -> Self {
self._rename = action.trim().to_string();
#[cfg(feature = "mysql")]
{
let action = AlterTableActionItem(AlterTableOrderedAction::Rename, action.trim().to_string());
push_unique(&mut self._ordered_actions, action);
}
#[cfg(not(feature = "mysql"))]
{
self._rename = action.trim().to_string();
}

self
}
}

#[cfg(any(doc, feature = "postgresql", feature = "sqlite"))]
#[cfg_attr(docsrs, doc(cfg(feature = "postgresql")))]
#[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
impl AlterTable {
/// Changes the name of the table, this method overrides the previous value
///
/// ### Example
Expand Down Expand Up @@ -345,16 +388,17 @@ impl AlterTable {
}
}

#[cfg(any(doc, feature = "postgresql"))]
#[cfg(any(doc, feature = "postgresql", feature = "mysql"))]
#[cfg_attr(docsrs, doc(cfg(feature = "postgresql")))]
#[cfg_attr(docsrs, doc(cfg(feature = "mysql")))]
impl AlterTable {
/// Alter columns or table constraints.
/// Multiples call of this method will build the SQL respecting the order of the calls
///
/// ### Example
///
///```
/// # #[cfg(any(feature = "postgresql"))]
/// # #[cfg(any(feature = "postgresql", feature = "mysql"))]
/// # {
/// # use sql_query_builder as sql;
/// let query = sql::AlterTable::new()
Expand Down
7 changes: 4 additions & 3 deletions src/alter_table/alter_table_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl AlterTable {
fn concat_ordered_actions(&self, query: String, fmts: &fmt::Formatter) -> String {
let actions = self._ordered_actions.iter().filter(|item| item.1.is_empty() == false);

#[cfg(any(feature = "postgresql"))]
#[cfg(any(feature = "postgresql", feature = "mysql"))]
{
use crate::structure::AlterTableActionItem;

Expand All @@ -63,8 +63,9 @@ impl AlterTable {
match action {
AlterTableOrderedAction::Add => format!("{lb}{indent}ADD{space}{content}"),
AlterTableOrderedAction::Drop => format!("{lb}{indent}DROP{space}{content}"),
#[cfg(any(feature = "postgresql"))]
AlterTableOrderedAction::Alter => format!("{lb}{indent}ALTER{space}{content}"),
#[cfg(feature = "mysql")]
AlterTableOrderedAction::Rename => format!("{lb}{indent}RENAME{space}{content}"),
}
})
.collect::<Vec<_>>()
Expand All @@ -74,7 +75,7 @@ impl AlterTable {
format!("{query}{sql}{space}")
}

#[cfg(not(any(feature = "postgresql")))]
#[cfg(not(any(feature = "postgresql", feature = "mysql")))]
{
let fmt::Formatter { lb, space, .. } = fmts;

Expand Down
2 changes: 1 addition & 1 deletion src/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ use crate::concat::Concat;
pub trait TransactionQuery: Concat {}

/// Represents all commands that can be used inside the with method
#[cfg(any(feature = "postgresql", feature = "sqlite"))]
#[cfg(any(feature = "postgresql", feature = "sqlite", feature = "mysql"))]
pub trait WithQuery: Concat {}
1 change: 1 addition & 0 deletions src/concat/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::fmt;

pub(crate) mod mysql;
pub(crate) mod non_standard;
pub(crate) mod sql_standard;
pub(crate) mod sqlite;
Expand Down
31 changes: 31 additions & 0 deletions src/concat/mysql.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[cfg(feature = "mysql")]
use crate::{concat::concat_raw_before_after, fmt, utils};

#[cfg(feature = "mysql")]
pub(crate) trait ConcatPartition<Clause: PartialEq> {
fn concat_partition(
&self,
items_raw_before: &Vec<(Clause, String)>,
items_raw_after: &Vec<(Clause, String)>,
query: String,
fmts: &fmt::Formatter,
clause: Clause,
items: &Vec<String>,
) -> String {
let fmt::Formatter { comma, lb, space, .. } = fmts;

let sql = if items.is_empty() == false {
let column_names = utils::join(items, comma);

if column_names.is_empty() == false {
format!("PARTITION{space}({column_names}){space}{lb}")
} else {
"".to_string()
}
} else {
"".to_string()
};

concat_raw_before_after(items_raw_before, items_raw_after, query, fmts, clause, sql)
}
}
Loading
Loading