diff --git a/README.md b/README.md index 90ec10c..bc51c9c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ if is_admin { let query = select.as_string(); -println!("{}", query); +println!("{query}"); ``` Output diff --git a/scripts/watch_test.sh b/scripts/watch_test.sh index 752a0eb..cc1ae1a 100755 --- a/scripts/watch_test.sh +++ b/scripts/watch_test.sh @@ -10,6 +10,7 @@ all_features='postgresql sqlite' features='' +test_names=$(git status -s | grep tests/ | sed -e 's/.* //' -e 's/tests\//--test /' -e 's/.rs//' | tr '\n' ' ') case "$@" in "") features="";; @@ -19,6 +20,5 @@ esac [ ! -z "$features" ] && features="--features $features" -# cargo watch -w ./src -w ./tests -x 'test --test command_alter_table_spec' # cargo watch -w ./src -w ./tests -x 'test --features postgresql -- --nocapture --color always' -cargo watch -w ./src -w ./tests -x "test $features" +cargo watch -w ./src -w ./tests -x "test $features $test_names" diff --git a/src/create_table/create_table.rs b/src/create_table/create_table.rs index 8b17d5a..4ede0ae 100644 --- a/src/create_table/create_table.rs +++ b/src/create_table/create_table.rs @@ -212,7 +212,7 @@ impl CreateTable { self } - /// Creates instance of the CreateTable command + /// Creates instance of the [CreateTable] command pub fn new() -> Self { Self::default() } diff --git a/src/drop_table/drop_table.rs b/src/drop_table/drop_table.rs new file mode 100644 index 0000000..ffc291b --- /dev/null +++ b/src/drop_table/drop_table.rs @@ -0,0 +1,271 @@ +use crate::{ + behavior::{push_unique, Concat, TransactionQuery}, + fmt, + structure::{DropTable, DropTableParams}, +}; + +impl TransactionQuery for DropTable {} + +impl DropTable { + /// Gets the current state of the [DropTable] and returns it as string + /// + /// ### Example + /// + /// ``` + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .as_string(); + /// + /// # let expected = "DROP TABLE users"; + /// # assert_eq!(expected, query); + /// ``` + /// + /// Output + /// + /// ```sql + /// DROP TABLE users + /// ``` + pub fn as_string(&self) -> String { + let fmts = fmt::one_line(); + self.concat(&fmts) + } + + /// Defines a drop table command, this method overrides the previous value + /// + /// ### Example 1 + /// + ///``` + /// # #[cfg(not(feature = "postgresql"))] + /// # { + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .drop_table("orders") + /// .as_string(); + /// + /// # let expected = "DROP TABLE orders"; + /// # assert_eq!(expected, query); + /// # } + /// ``` + /// + /// Outputs + /// + /// ```sql + /// DROP TABLE orders + /// ``` + /// + /// ### Example 2 `crate features postgresql only` + /// + /// Multiples call will concatenates all values + /// + ///``` + /// # #[cfg(feature = "postgresql")] + /// # { + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .drop_table("orders") + /// .as_string(); + /// + /// # let expected = "DROP TABLE users, orders"; + /// # assert_eq!(expected, query); + /// # } + /// ``` + /// + /// Outputs + /// + /// ```sql + /// DROP TABLE users, orders + /// ``` + pub fn drop_table(mut self, table_name: &str) -> Self { + push_unique(&mut self._drop_table, table_name.trim().to_string()); + self + } + + /// Defines a drop table comand with the modifer `if exists`, this method overrides the previous value + /// + /// ### Example 1 + /// + /// ``` + /// # #[cfg(not(feature = "postgresql"))] + /// # { + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .drop_table_if_exists("orders") + /// .to_string(); + /// + /// # let expected = "DROP TABLE IF EXISTS orders"; + /// # assert_eq!(expected, query); + /// # } + /// ``` + /// + /// Outputs + /// + /// ```sql + /// DROP TABLE IF EXISTS orders + /// ``` + /// + /// ### Example 2 `crate features postgresql only` + /// + /// Multiples call will concatenates all values + /// + /// ``` + /// # #[cfg(feature = "postgresql")] + /// # { + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .drop_table_if_exists("orders") + /// .to_string(); + /// + /// # let expected = "DROP TABLE IF EXISTS users, orders"; + /// # assert_eq!(expected, query); + /// # } + /// ``` + /// + /// Outputs + /// + /// ```sql + /// DROP TABLE IF EXISTS users, orders + /// ``` + pub fn drop_table_if_exists(mut self, table_name: &str) -> Self { + push_unique(&mut self._drop_table, table_name.trim().to_string()); + self._if_exists = true; + self + } + + /// Prints the current state of the [DropTable] to the standard output in a more ease to read version. + /// This method is useful to debug complex queries or just print the generated SQL while you type + /// + /// ### Example + /// + /// ``` + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .debug() + /// .as_string(); + /// ``` + /// + /// Prints to the standard output + /// + /// ```sql + /// -- ------------------------------------------------------------------------------ + /// DROP TABLE users + /// -- ------------------------------------------------------------------------------ + /// ``` + pub fn debug(self) -> Self { + let fmts = fmt::multiline(); + println!("{}", fmt::format(self.concat(&fmts), &fmts)); + self + } + + /// Creates instance of the [DropTable] command + pub fn new() -> Self { + Self::default() + } + + /// Prints the current state of the [DropTable] to the standard output similar to debug method, + /// the difference is that this method prints in one line. + pub fn print(self) -> Self { + let fmts = fmt::one_line(); + println!("{}", fmt::format(self.concat(&fmts), &fmts)); + self + } + + /// Adds at the beginning a raw SQL query. Is useful to create a more complex drop table signature like the example below. + /// + /// ### Example + /// + /// ``` + /// # use sql_query_builder as sql; + /// let drop_table_query = sql::DropTable::new() + /// .raw("/* drop command */") + /// .drop_table("users_temp") + /// .as_string(); + /// + /// # let expected = "/* drop command */ DROP TABLE users_temp"; + /// # assert_eq!(expected, drop_table_query); + /// ``` + /// + /// Output + /// + /// ```sql + /// /* drop command */ DROP TABLE users_temp + /// ``` + pub fn raw(mut self, raw_sql: &str) -> Self { + push_unique(&mut self._raw, raw_sql.trim().to_string()); + self + } + + /// Adds a raw SQL query after a specified parameter. + /// + /// The `DropTableParams::DropTable` works for both `.drop_table` and `.drop_table_if_exist` methods + /// + /// ### Example + /// + /// ``` + /// # use sql_query_builder as sql; + /// let query = sql::DropTable::new() + /// .drop_table("users") + /// .raw_after(sql::DropTableParams::DropTable, "CASCADE RESTRICT") + /// .as_string(); + /// + /// # let expected = "DROP TABLE users CASCADE RESTRICT"; + /// # assert_eq!(expected, query); + /// ``` + /// + /// Output + /// + /// ```sql + /// DROP TABLE users CASCADE RESTRICT + /// ``` + pub fn raw_after(mut self, param: DropTableParams, raw_sql: &str) -> Self { + self._raw_after.push((param, raw_sql.trim().to_string())); + self + } + + /// Adds a raw SQL query before a specified parameter. + /// + /// The `DropTableParams::DropTable` works for both `.drop_table` and `.drop_table_if_exist` methods + /// + /// ### Example + /// + /// ``` + /// # use sql_query_builder as sql; + /// let raw = "CREATE TABLE users_temp;"; + /// + /// let query = sql::DropTable::new() + /// .raw_before(sql::DropTableParams::DropTable, raw) + /// .drop_table("users_temp") + /// .as_string(); + /// + /// # let expected = "CREATE TABLE users_temp; DROP TABLE users_temp"; + /// # assert_eq!(expected, query); + /// ``` + /// + /// Output + /// + /// ```sql + /// CREATE TABLE users_temp; DROP TABLE users_temp + /// ``` + pub fn raw_before(mut self, param: DropTableParams, raw_sql: &str) -> Self { + self._raw_before.push((param, raw_sql.trim().to_string())); + self + } +} + +impl std::fmt::Display for DropTable { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.as_string()) + } +} + +impl std::fmt::Debug for DropTable { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let fmts = fmt::multiline(); + write!(f, "{}", fmt::format(self.concat(&fmts), &fmts)) + } +} diff --git a/src/drop_table/drop_table_internal.rs b/src/drop_table/drop_table_internal.rs new file mode 100644 index 0000000..593d074 --- /dev/null +++ b/src/drop_table/drop_table_internal.rs @@ -0,0 +1,51 @@ +use crate::{ + behavior::{concat_raw_before_after, Concat, ConcatSqlStandard}, + fmt, + structure::{DropTable, DropTableParams}, +}; + +impl ConcatSqlStandard for DropTable {} + +impl DropTable { + fn concat_drop_table(&self, query: String, fmts: &fmt::Formatter) -> String { + let fmt::Formatter { comma, lb, space, .. } = fmts; + + let sql = if self._drop_table.len() != 0 { + let if_exists = if self._if_exists { + format!("IF EXISTS{space}") + } else { + "".to_string() + }; + + let table_names = if cfg!(any(feature = "postgresql")) { + self._drop_table.join(comma) + } else { + self._drop_table.last().unwrap().to_string() + }; + + format!("DROP TABLE{space}{if_exists}{table_names}{space}{lb}") + } else { + "".to_string() + }; + + concat_raw_before_after( + &self._raw_before, + &self._raw_after, + query, + fmts, + DropTableParams::DropTable, + sql, + ) + } +} + +impl Concat for DropTable { + fn concat(&self, fmts: &fmt::Formatter) -> String { + let mut query = "".to_string(); + + query = self.concat_raw(query, &fmts, &self._raw); + query = self.concat_drop_table(query, &fmts); + + query.trim_end().to_string() + } +} diff --git a/src/drop_table/mod.rs b/src/drop_table/mod.rs new file mode 100644 index 0000000..0864a58 --- /dev/null +++ b/src/drop_table/mod.rs @@ -0,0 +1,2 @@ +mod drop_table; +mod drop_table_internal; diff --git a/src/lib.rs b/src/lib.rs index 620ca7d..48d0e28 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ mod alter_table; mod behavior; mod create_table; mod delete; +mod drop_table; mod fmt; mod insert; mod select; @@ -14,6 +15,6 @@ mod update; mod values; pub use crate::structure::{ - AlterTable, AlterTableAction, CreateTable, CreateTableParams, Delete, DeleteClause, Insert, InsertClause, Select, - SelectClause, Transaction, Update, UpdateClause, Values, ValuesClause, + AlterTable, AlterTableAction, CreateTable, CreateTableParams, Delete, DeleteClause, DropTable, DropTableParams, + Insert, InsertClause, Select, SelectClause, Transaction, Update, UpdateClause, Values, ValuesClause, }; diff --git a/src/structure.rs b/src/structure.rs index 6d2d4a4..e82d9ac 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -136,6 +136,41 @@ pub enum CreateTableParams { PrimaryKey, } +/// Builder to contruct a [DropTable] command +/// +/// Basic API +/// ``` +/// use sql_query_builder as sql; +/// +/// let query = sql::DropTable::new() +/// .drop_table("users") +/// .as_string(); +/// +/// # let expected = "DROP TABLE users"; +/// # assert_eq!(expected, query); +/// ``` +/// +/// +/// Output +/// +/// ```sql +/// DROP TABLE users +/// ``` +#[derive(Default, Clone)] +pub struct DropTable { + pub(crate) _drop_table: Vec, + pub(crate) _if_exists: bool, + pub(crate) _raw_after: Vec<(DropTableParams, String)>, + pub(crate) _raw_before: Vec<(DropTableParams, String)>, + pub(crate) _raw: Vec, +} + +/// All available params to be used in [DropTable::raw_before] and [DropTable::raw_after] methods on [DropTable] builder +#[derive(PartialEq, Clone)] +pub enum DropTableParams { + DropTable, +} + /// Builder to contruct a [Delete] command #[derive(Default, Clone)] pub struct Delete { diff --git a/src/transaction/transaction.rs b/src/transaction/transaction.rs index 3e8014e..759c725 100644 --- a/src/transaction/transaction.rs +++ b/src/transaction/transaction.rs @@ -1,7 +1,9 @@ use crate::{ behavior::{push_unique, Concat}, fmt, - structure::{AlterTable, CreateTable, Delete, Insert, Select, TrCmd::*, Transaction, TransactionCommand, Update}, + structure::{ + AlterTable, CreateTable, Delete, DropTable, Insert, Select, TrCmd::*, Transaction, TransactionCommand, Update, + }, }; impl Transaction { @@ -225,6 +227,45 @@ impl Transaction { self } + /// The `drop table` command, access the [DropTable] for more info + /// + /// # Example + /// + /// ``` + /// # #[cfg(not(feature = "sqlite"))] + /// # { + /// # use sql_query_builder as sql; + /// let drop_users = sql::DropTable::new() + /// .drop_table("users"); + /// + /// let query = sql::Transaction::new() + /// .start_transaction("") + /// .drop_table(drop_users) + /// .commit("") + /// .as_string(); + /// + /// # let expected = "\ + /// # START TRANSACTION; \ + /// # DROP TABLE users; \ + /// # COMMIT;\ + /// # "; + /// # assert_eq!(expected, query); + /// # } + /// ``` + /// + /// Output (indented for readability) + /// + /// ```sql + /// START TRANSACTION; + /// DROP TABLE users; + /// COMMIT; + /// ``` + pub fn drop_table(mut self, drop_table: DropTable) -> Self { + let cmd = Box::new(drop_table); + self._ordered_commands.push(cmd); + self + } + /// The `insert` command, access the [Insert] for more info /// /// # Example diff --git a/src/values/values_internal.rs b/src/values/values_internal.rs index 147b7dd..022d190 100644 --- a/src/values/values_internal.rs +++ b/src/values/values_internal.rs @@ -33,7 +33,6 @@ impl Concat for Values { let mut query = "".to_string(); query = self.concat_raw(query, &fmts, &self._raw); - query = self.concat_values(query, &fmts); query.trim_end().to_string() diff --git a/tests/clause_select_spec.rs b/tests/clause_select_spec.rs index 18c0583..74adb60 100644 --- a/tests/clause_select_spec.rs +++ b/tests/clause_select_spec.rs @@ -21,7 +21,7 @@ mod insert_command { WHERE active = true\ "; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -34,7 +34,7 @@ mod insert_command { let expected_query = "INSERT INTO users SELECT *"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -46,7 +46,7 @@ mod insert_command { let expected_query = "insert into users SELECT *"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -58,7 +58,7 @@ mod insert_command { .as_string(); let expected_query = "INSERT INTO users SELECT * from users_bk"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -69,7 +69,7 @@ mod insert_command { .as_string(); let expected_query = "INSERT INTO users (login, name) SELECT login, name"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } } @@ -82,7 +82,7 @@ mod select_command { let query = sql::Select::new().select("id, login").as_string(); let expected_query = "SELECT id, login"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -90,7 +90,7 @@ mod select_command { let query = sql::Select::new().select("id, login").select("created_at").as_string(); let expected_query = "SELECT id, login, created_at"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -98,7 +98,7 @@ mod select_command { let query = sql::Select::new().select(" login, name ").as_string(); let expected_query = "SELECT login, name"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -109,7 +109,7 @@ mod select_command { .as_string(); let expected_query = "SELECT login, name"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -120,7 +120,7 @@ mod select_command { .as_string(); let expected_query = "/* list orders */ SELECT id, name"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } #[test] @@ -131,6 +131,6 @@ mod select_command { .as_string(); let expected_query = "SELECT id, name from addresses"; - assert_eq!(query, expected_query); + assert_eq!(expected_query, query); } } diff --git a/tests/command_drop_table_spec.rs b/tests/command_drop_table_spec.rs new file mode 100644 index 0000000..c04c6d6 --- /dev/null +++ b/tests/command_drop_table_spec.rs @@ -0,0 +1,374 @@ +mod builder_features { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn drop_table_builder_should_be_displayable() { + let drop_table = sql::DropTable::new().drop_table("orders"); + + println!("{}", drop_table); + + let query = drop_table.as_string(); + let expected_query = "DROP TABLE orders"; + + assert_eq!(expected_query, query); + } + + #[test] + fn drop_table_builder_should_be_debuggable() { + let drop_table = sql::DropTable::new().drop_table("orders"); + + println!("{:?}", drop_table); + + let expected_query = "DROP TABLE orders"; + let query = drop_table.as_string(); + + assert_eq!(expected_query, query); + } + + #[cfg(not(feature = "postgresql"))] + #[test] + fn drop_table_builder_should_be_cloneable() { + let drop_users = sql::DropTable::new().drop_table("users"); + let drop_users_and_orders = drop_users.clone().drop_table("orders"); + + let expected_drop_users = "DROP TABLE users"; + let expected_drop_users_and_orders = "DROP TABLE orders"; + + assert_eq!(expected_drop_users, drop_users.as_string()); + assert_eq!(expected_drop_users_and_orders, drop_users_and_orders.as_string()); + } + + #[cfg(not(feature = "postgresql"))] + #[test] + fn drop_table_builder_should_be_able_to_conditionally_add_clauses() { + let mut drop_table = sql::DropTable::new().drop_table("orders"); + + if true { + drop_table = drop_table.drop_table("users"); + } + + let query = drop_table.as_string(); + let expected_query = "DROP TABLE users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn drop_table_builder_should_be_composable() { + fn add_comment(select: sql::DropTable) -> sql::DropTable { + select.raw("/* drop command */") + } + + fn drop_orders(select: sql::DropTable) -> sql::DropTable { + select.drop_table("orders") + } + + fn as_string(select: sql::DropTable) -> String { + select.as_string() + } + + let query = Some(sql::DropTable::new()) + .map(add_comment) + .map(drop_orders) + .map(as_string) + .unwrap(); + + let expected_query = "/* drop command */ DROP TABLE orders"; + + assert_eq!(expected_query, query); + } +} + +mod builder_methods { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn method_new_should_initialize_as_empty_string() { + let query = sql::DropTable::new().as_string(); + let expected_query = ""; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_as_string_should_convert_the_current_state_into_string() { + let query = sql::DropTable::new().as_string(); + let expected_query = ""; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_debug_should_print_at_console_in_a_human_readable_format() { + let query = sql::DropTable::new().drop_table_if_exists("users").debug().as_string(); + + let expected_query = "DROP TABLE IF EXISTS users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_print_should_print_in_one_line_the_current_state_of_builder() { + let query = sql::DropTable::new().drop_table_if_exists("users").print().as_string(); + + let expected_query = "DROP TABLE IF EXISTS users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_should_add_raw_sql() { + let query = sql::DropTable::new().raw("drop table users cascade").as_string(); + + let expected_query = "drop table users cascade"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_should_accumulate_values_on_consecutive_calls() { + let query = sql::DropTable::new().raw("drop table users").raw("cascade").as_string(); + + let expected_query = "drop table users cascade"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_should_be_the_first_to_be_concatenated() { + let query = sql::DropTable::new() + .raw("/* drop table command */") + .drop_table("users") + .as_string(); + + let expected_query = "/* drop table command */ DROP TABLE users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_should_not_accumulate_arguments_with_the_same_content() { + let query = sql::DropTable::new() + .raw("drop table users") + .raw("drop table users") + .as_string(); + + let expected_query = "drop table users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_after_should_trim_space_of_the_argument() { + let query = sql::DropTable::new() + .drop_table("users") + .raw_after(sql::DropTableParams::DropTable, " CASCADE ") + .as_string(); + let expected_query = "DROP TABLE users CASCADE"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_before_should_trim_space_of_the_argument() { + let query = sql::DropTable::new() + .raw_before(sql::DropTableParams::DropTable, " /* drop table command */ ") + .drop_table("users") + .as_string(); + let expected_query = "/* drop table command */ DROP TABLE users"; + + assert_eq!(expected_query, query); + } +} + +mod method_drop_table { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn method_drop_table_should_add_the_drop_table_signature() { + let query = sql::DropTable::new().drop_table("films").as_string(); + let expected_query = "DROP TABLE films"; + + assert_eq!(expected_query, query); + } + + #[cfg(not(feature = "postgresql"))] + #[test] + fn method_drop_table_should_overrides_previous_value_on_consecutive_calls() { + let query = sql::DropTable::new() + .drop_table("films") + .drop_table("series") + .as_string(); + + let expected_query = "DROP TABLE series"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_should_trim_space_of_the_argument() { + let query = sql::DropTable::new().drop_table(" films ").as_string(); + let expected_query = "DROP TABLE films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_should_not_accumulate_arguments_with_the_same_content() { + let query = sql::DropTable::new() + .drop_table("films") + .drop_table("films") + .as_string(); + let expected_query = "DROP TABLE films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_before_should_add_raw_sql_before_method_drop_table() { + let query = sql::DropTable::new() + .raw_before(sql::DropTableParams::DropTable, "/* drop command */") + .drop_table("films") + .as_string(); + let expected_query = "/* drop command */ DROP TABLE films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_after_should_add_raw_sql_after_method_drop_table() { + let query = sql::DropTable::new() + .drop_table("films") + .raw_after(sql::DropTableParams::DropTable, "RESTRICT") + .as_string(); + let expected_query = "DROP TABLE films RESTRICT"; + + assert_eq!(expected_query, query); + } +} + +mod method_drop_table_if_exists { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn method_drop_table_if_exists_should_add_the_drop_table_signature() { + let query = sql::DropTable::new().drop_table_if_exists("films").as_string(); + let expected_query = "DROP TABLE IF EXISTS films"; + + assert_eq!(expected_query, query); + } + + #[cfg(not(feature = "postgresql"))] + #[test] + fn method_drop_table_if_exists_should_overrides_previous_value_on_consecutive_calls() { + let query = sql::DropTable::new() + .drop_table_if_exists("films") + .drop_table_if_exists("series") + .as_string(); + + let expected_query = "DROP TABLE IF EXISTS series"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_if_exists_should_trim_space_of_the_argument() { + let query = sql::DropTable::new().drop_table_if_exists(" films ").as_string(); + let expected_query = "DROP TABLE IF EXISTS films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_if_exists_should_not_accumulate_arguments_with_the_same_content() { + let query = sql::DropTable::new() + .drop_table_if_exists("films") + .drop_table_if_exists("films") + .as_string(); + let expected_query = "DROP TABLE IF EXISTS films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_before_should_add_raw_sql_before_method_drop_table_if_exists() { + let query = sql::DropTable::new() + .raw_before(sql::DropTableParams::DropTable, "/* drop command */") + .drop_table_if_exists("films") + .as_string(); + let expected_query = "/* drop command */ DROP TABLE IF EXISTS films"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_raw_after_should_add_raw_sql_after_method_drop_table_if_exists() { + let query = sql::DropTable::new() + .drop_table_if_exists("films") + .raw_after(sql::DropTableParams::DropTable, "RESTRICT") + .as_string(); + let expected_query = "DROP TABLE IF EXISTS films RESTRICT"; + + assert_eq!(expected_query, query); + } +} + +#[cfg(feature = "postgresql")] +mod postgres_feature_flag { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn drop_table_builder_should_be_able_to_conditionally_add_clauses() { + let mut drop_table = sql::DropTable::new().drop_table("orders"); + + if true { + drop_table = drop_table.drop_table("users"); + } + + let query = drop_table.as_string(); + let expected_query = "DROP TABLE orders, users"; + + assert_eq!(expected_query, query); + } + + #[test] + fn drop_table_builder_should_be_cloneable() { + let drop_users = sql::DropTable::new().drop_table("users"); + let drop_users_and_orders = drop_users.clone().drop_table("orders"); + + let expected_drop_users = "DROP TABLE users"; + let expected_drop_users_and_orders = "DROP TABLE users, orders"; + + assert_eq!(expected_drop_users, drop_users.as_string()); + assert_eq!(expected_drop_users_and_orders, drop_users_and_orders.as_string()); + } + + #[test] + fn method_drop_table_should_accumulate_values_on_consecutive_calls() { + let query = sql::DropTable::new() + .drop_table("films") + .drop_table("series") + .as_string(); + + let expected_query = "DROP TABLE films, series"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_if_exists_should_accumulate_values_on_consecutive_calls() { + let query = sql::DropTable::new() + .drop_table_if_exists("films") + .drop_table_if_exists("series") + .as_string(); + + let expected_query = "DROP TABLE IF EXISTS films, series"; + + assert_eq!(expected_query, query); + } +} diff --git a/tests/command_transaction_spec.rs b/tests/command_transaction_spec.rs index fd4e4e0..0bd4e91 100644 --- a/tests/command_transaction_spec.rs +++ b/tests/command_transaction_spec.rs @@ -385,6 +385,34 @@ mod delete_method { } } +mod drop_table_method { + use pretty_assertions::assert_eq; + use sql_query_builder as sql; + + #[test] + fn method_drop_table_should_add_a_drop_table_command() { + let query = sql::Transaction::new() + .drop_table(sql::DropTable::new().drop_table("users")) + .as_string(); + + let expected_query = "DROP TABLE users;"; + + assert_eq!(expected_query, query); + } + + #[test] + fn method_drop_table_should_accumulate_values_on_consecutive_calls() { + let query = sql::Transaction::new() + .drop_table(sql::DropTable::new().drop_table("users")) + .drop_table(sql::DropTable::new().drop_table("orders")) + .as_string(); + + let expected_query = "DROP TABLE users; DROP TABLE orders;"; + + assert_eq!(expected_query, query); + } +} + mod insert_method { use pretty_assertions::assert_eq; use sql_query_builder as sql;