diff --git a/src/query/mod.rs b/src/query/mod.rs index 54cc12dd5..5d2be1422 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -8,6 +8,7 @@ mod json; mod select; mod traits; mod update; +mod util; pub use combine::{SelectA, SelectB}; pub use delete::*; @@ -19,5 +20,6 @@ pub use json::*; pub use select::*; pub use traits::*; pub use update::*; +pub use util::*; pub use crate::{InsertResult, Statement, UpdateResult, Value, Values}; diff --git a/src/query/util.rs b/src/query/util.rs new file mode 100644 index 000000000..7e771f7c2 --- /dev/null +++ b/src/query/util.rs @@ -0,0 +1,112 @@ +use crate::{DatabaseConnection, DbBackend, QueryTrait, Statement}; + +#[derive(Debug)] +pub struct DebugQuery<'a, Q, T> { + pub query: &'a Q, + pub value: T, +} + +macro_rules! debug_query_build { + ($impl_obj:ty, $db_expr:expr) => { + impl<'a, Q> DebugQuery<'a, Q, $impl_obj> + where + Q: QueryTrait, + { + pub fn build(&self) -> Statement { + let func = $db_expr; + let db_backend = func(self); + self.query.build(db_backend) + } + } + }; +} + +debug_query_build!(DbBackend, |x: &DebugQuery<_, DbBackend>| x.value); +debug_query_build!(&DbBackend, |x: &DebugQuery<_, &DbBackend>| *x.value); +debug_query_build!( + DatabaseConnection, + |x: &DebugQuery<_, DatabaseConnection>| x.value.get_database_backend() +); +debug_query_build!( + &DatabaseConnection, + |x: &DebugQuery<_, &DatabaseConnection>| x.value.get_database_backend() +); + +/// Helper to get a `Statement` from an object that impl `QueryTrait`. +/// +/// # Example +/// +/// ``` +/// # #[cfg(feature = "mock")] +/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend}; +/// # +/// # let conn = MockDatabase::new(DbBackend::Postgres) +/// # .into_connection(); +/// # +/// use sea_orm::{entity::*, query::*, tests_cfg::cake, debug_query_stmt}; +/// +/// let c = cake::Entity::insert( +/// cake::ActiveModel { +/// id: ActiveValue::set(1), +/// name: ActiveValue::set("Apple Pie".to_owned()), +/// }); +/// +/// let raw_sql = debug_query_stmt!(&c, &conn).to_string(); +/// assert_eq!(raw_sql, r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#); +/// +/// let raw_sql = debug_query_stmt!(&c, conn).to_string(); +/// assert_eq!(raw_sql, r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#); +/// +/// let raw_sql = debug_query_stmt!(&c, DbBackend::MySql).to_string(); +/// assert_eq!(raw_sql, r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#); +/// +/// let raw_sql = debug_query_stmt!(&c, &DbBackend::MySql).to_string(); +/// assert_eq!(raw_sql, r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#); +/// +/// ``` +#[macro_export] +macro_rules! debug_query_stmt { + ($query:expr,$value:expr) => { + $crate::DebugQuery { + query: $query, + value: $value, + } + .build(); + }; +} + +/// Helper to get a raw SQL string from an object that impl `QueryTrait`. +/// +/// # Example +/// +/// ``` +/// # #[cfg(feature = "mock")] +/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend}; +/// # +/// # let conn = MockDatabase::new(DbBackend::Postgres) +/// # .into_connection(); +/// # +/// use sea_orm::{entity::*, query::*, tests_cfg::cake,debug_query}; +/// +/// let c = cake::Entity::insert( +/// cake::ActiveModel { +/// id: ActiveValue::set(1), +/// name: ActiveValue::set("Apple Pie".to_owned()), +/// }); +/// +/// let raw_sql = debug_query!(&c, &conn); +/// assert_eq!(raw_sql, r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#); +/// +/// let raw_sql = debug_query!(&c, conn); +/// assert_eq!(raw_sql, r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#); +/// +/// let raw_sql = debug_query!(&c, DbBackend::Sqlite); +/// assert_eq!(raw_sql, r#"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')"#); +/// +/// ``` +#[macro_export] +macro_rules! debug_query { + ($query:expr,$value:expr) => { + $crate::debug_query_stmt!($query, $value).to_string(); + }; +}