1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use crate::DbBackend; use sea_query::{inject_parameters, MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder}; pub use sea_query::{Value, Values}; use std::fmt; #[derive(Debug, Clone, PartialEq)] pub struct Statement { pub sql: String, pub values: Option<Values>, pub db_backend: DbBackend, } pub trait StatementBuilder { fn build(&self, db_backend: &DbBackend) -> Statement; } impl Statement { pub fn from_string(db_backend: DbBackend, stmt: String) -> Statement { Statement { sql: stmt, values: None, db_backend, } } pub fn from_sql_and_values<I>(db_backend: DbBackend, sql: &str, values: I) -> Self where I: IntoIterator<Item = Value>, { Self::from_string_values_tuple( db_backend, (sql.to_owned(), Values(values.into_iter().collect())), ) } pub(crate) fn from_string_values_tuple( db_backend: DbBackend, stmt: (String, Values), ) -> Statement { Statement { sql: stmt.0, values: Some(stmt.1), db_backend, } } } impl fmt::Display for Statement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self.values { Some(values) => { let string = inject_parameters( &self.sql, values.0.clone(), self.db_backend.get_query_builder().as_ref(), ); write!(f, "{}", &string) } None => { write!(f, "{}", &self.sql) } } } } macro_rules! build_any_stmt { ($stmt: expr, $db_backend: expr) => { match $db_backend { DbBackend::MySql => $stmt.build(MysqlQueryBuilder), DbBackend::Postgres => $stmt.build(PostgresQueryBuilder), DbBackend::Sqlite => $stmt.build(SqliteQueryBuilder), } }; } macro_rules! build_query_stmt { ($stmt: ty) => { impl StatementBuilder for $stmt { fn build(&self, db_backend: &DbBackend) -> Statement { let stmt = build_any_stmt!(self, db_backend); Statement::from_string_values_tuple(*db_backend, stmt) } } }; } build_query_stmt!(sea_query::InsertStatement); build_query_stmt!(sea_query::SelectStatement); build_query_stmt!(sea_query::UpdateStatement); build_query_stmt!(sea_query::DeleteStatement); macro_rules! build_schema_stmt { ($stmt: ty) => { impl StatementBuilder for $stmt { fn build(&self, db_backend: &DbBackend) -> Statement { let stmt = build_any_stmt!(self, db_backend); Statement::from_string(*db_backend, stmt) } } }; } build_schema_stmt!(sea_query::TableCreateStatement); build_schema_stmt!(sea_query::TableDropStatement); build_schema_stmt!(sea_query::TableAlterStatement); build_schema_stmt!(sea_query::TableRenameStatement); build_schema_stmt!(sea_query::TableTruncateStatement);