use crate::types::{DynIden, IntoIden};
use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
#[derive(Debug, Clone)]
pub struct DetachDatabaseStatement {
pub(crate) database_name: Option<DynIden>,
}
impl DetachDatabaseStatement {
pub fn new() -> Self {
Self {
database_name: None,
}
}
pub fn take(&mut self) -> Self {
Self {
database_name: self.database_name.take(),
}
}
pub fn name<N>(&mut self, name: N) -> &mut Self
where
N: IntoIden,
{
self.database_name = Some(name.into_iden());
self
}
}
impl Default for DetachDatabaseStatement {
fn default() -> Self {
Self::new()
}
}
impl QueryStatementBuilder for DetachDatabaseStatement {
fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
use std::any::Any;
if (query_builder as &dyn Any)
.downcast_ref::<crate::backend::PostgresQueryBuilder>()
.is_some()
{
panic!("DETACH DATABASE is SQLite-specific and not supported in PostgreSQL");
}
if (query_builder as &dyn Any)
.downcast_ref::<crate::backend::MySqlQueryBuilder>()
.is_some()
{
panic!("DETACH DATABASE is SQLite-specific and not supported in MySQL");
}
if let Some(sqlite_builder) =
(query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
{
use crate::backend::QueryBuilder as _;
let db_name = self
.database_name
.as_ref()
.expect("DETACH DATABASE requires a database name");
let escaped_db_name = sqlite_builder.escape_identifier(&db_name.to_string());
let sql = format!("DETACH DATABASE {}", escaped_db_name);
return (sql, crate::value::Values::new());
}
if (query_builder as &dyn Any)
.downcast_ref::<crate::backend::CockroachDBQueryBuilder>()
.is_some()
{
panic!("DETACH DATABASE is SQLite-specific and not supported in CockroachDB");
}
panic!("Unsupported query builder type");
}
}
impl QueryStatementWriter for DetachDatabaseStatement {}
#[cfg(test)]
mod tests {
use super::*;
use rstest::*;
#[rstest]
fn test_detach_database_new() {
let stmt = DetachDatabaseStatement::new();
assert!(stmt.database_name.is_none());
}
#[rstest]
fn test_detach_database_with_name() {
let mut stmt = DetachDatabaseStatement::new();
stmt.name("auxiliary");
assert_eq!(
stmt.database_name.as_ref().unwrap().to_string(),
"auxiliary"
);
}
#[rstest]
fn test_detach_database_take() {
let mut stmt = DetachDatabaseStatement::new();
stmt.name("auxiliary");
let taken = stmt.take();
assert!(stmt.database_name.is_none());
assert_eq!(
taken.database_name.as_ref().unwrap().to_string(),
"auxiliary"
);
}
#[rstest]
fn test_detach_database_default() {
let stmt = DetachDatabaseStatement::default();
assert!(stmt.database_name.is_none());
}
#[rstest]
fn test_detach_database_fluent_api() {
let mut stmt = DetachDatabaseStatement::new();
let result = stmt.name("test_db");
assert_eq!(
result.database_name.as_ref().unwrap().to_string(),
"test_db"
);
}
#[rstest]
fn test_detach_database_build_sql() {
let mut stmt = DetachDatabaseStatement::new();
stmt.name("auxiliary");
let (sql, values) = stmt.build_any(&crate::backend::SqliteQueryBuilder);
assert_eq!(sql, r#"DETACH DATABASE "auxiliary""#);
assert!(values.0.is_empty());
}
#[rstest]
fn test_detach_database_db_name_with_double_quotes() {
let mut stmt = DetachDatabaseStatement::new();
stmt.name(r#"my"db"#);
let (sql, _) = stmt.build_any(&crate::backend::SqliteQueryBuilder);
assert_eq!(sql, r#"DETACH DATABASE "my""db""#);
}
#[rstest]
fn test_detach_database_db_name_with_special_chars() {
let mut stmt = DetachDatabaseStatement::new();
stmt.name(r#"test"schema"name"#);
let (sql, _) = stmt.build_any(&crate::backend::SqliteQueryBuilder);
assert_eq!(sql, r#"DETACH DATABASE "test""schema""name""#);
}
}