use crate::{
backend::QueryBuilder,
types::{DynIden, IntoIden, VacuumOption},
};
use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
#[derive(Debug, Clone, Default)]
pub struct VacuumStatement {
pub(crate) tables: Vec<DynIden>,
pub(crate) full: bool,
pub(crate) freeze: bool,
pub(crate) verbose: bool,
pub(crate) analyze: bool,
}
impl VacuumStatement {
pub fn new() -> Self {
Self::default()
}
pub fn take(&mut self) -> Self {
Self {
tables: std::mem::take(&mut self.tables),
full: std::mem::take(&mut self.full),
freeze: std::mem::take(&mut self.freeze),
verbose: std::mem::take(&mut self.verbose),
analyze: std::mem::take(&mut self.analyze),
}
}
pub fn table<T>(&mut self, table: T) -> &mut Self
where
T: IntoIden,
{
self.tables.push(table.into_iden());
self
}
pub fn full(&mut self) -> &mut Self {
self.full = true;
self
}
pub fn freeze(&mut self) -> &mut Self {
self.freeze = true;
self
}
pub fn verbose(&mut self) -> &mut Self {
self.verbose = true;
self
}
pub fn analyze(&mut self) -> &mut Self {
self.analyze = true;
self
}
pub fn options(&mut self, opt: VacuumOption) -> &mut Self {
self.full = opt.full;
self.freeze = opt.freeze;
self.verbose = opt.verbose;
self.analyze = opt.analyze;
self
}
}
impl QueryStatementBuilder for VacuumStatement {
fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
use std::any::Any;
if let Some(builder) =
(query_builder as &dyn Any).downcast_ref::<crate::backend::PostgresQueryBuilder>()
{
return builder.build_vacuum(self);
}
if let Some(builder) =
(query_builder as &dyn Any).downcast_ref::<crate::backend::MySqlQueryBuilder>()
{
return builder.build_vacuum(self);
}
if let Some(builder) =
(query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
{
return builder.build_vacuum(self);
}
if let Some(builder) =
(query_builder as &dyn Any).downcast_ref::<crate::backend::CockroachDBQueryBuilder>()
{
return builder.build_vacuum(self);
}
panic!("Unsupported query builder type");
}
}
impl QueryStatementWriter for VacuumStatement {}
#[cfg(test)]
mod tests {
use super::*;
use rstest::*;
#[rstest]
fn test_vacuum_new() {
let stmt = VacuumStatement::new();
assert!(stmt.tables.is_empty());
assert!(!stmt.full);
assert!(!stmt.freeze);
assert!(!stmt.verbose);
assert!(!stmt.analyze);
}
#[rstest]
fn test_vacuum_with_table() {
let mut stmt = VacuumStatement::new();
stmt.table("users");
assert_eq!(stmt.tables.len(), 1);
assert_eq!(stmt.tables[0].to_string(), "users");
}
#[rstest]
fn test_vacuum_with_multiple_tables() {
let mut stmt = VacuumStatement::new();
stmt.table("users").table("posts");
assert_eq!(stmt.tables.len(), 2);
assert_eq!(stmt.tables[0].to_string(), "users");
assert_eq!(stmt.tables[1].to_string(), "posts");
}
#[rstest]
fn test_vacuum_full() {
let mut stmt = VacuumStatement::new();
stmt.full();
assert!(stmt.full);
assert!(!stmt.freeze);
assert!(!stmt.verbose);
assert!(!stmt.analyze);
}
#[rstest]
fn test_vacuum_freeze() {
let mut stmt = VacuumStatement::new();
stmt.freeze();
assert!(!stmt.full);
assert!(stmt.freeze);
assert!(!stmt.verbose);
assert!(!stmt.analyze);
}
#[rstest]
fn test_vacuum_verbose() {
let mut stmt = VacuumStatement::new();
stmt.verbose();
assert!(!stmt.full);
assert!(!stmt.freeze);
assert!(stmt.verbose);
assert!(!stmt.analyze);
}
#[rstest]
fn test_vacuum_analyze() {
let mut stmt = VacuumStatement::new();
stmt.analyze();
assert!(!stmt.full);
assert!(!stmt.freeze);
assert!(!stmt.verbose);
assert!(stmt.analyze);
}
#[rstest]
fn test_vacuum_combined_options() {
let mut stmt = VacuumStatement::new();
stmt.table("users").full().freeze().verbose().analyze();
assert_eq!(stmt.tables.len(), 1);
assert_eq!(stmt.tables[0].to_string(), "users");
assert!(stmt.full);
assert!(stmt.freeze);
assert!(stmt.verbose);
assert!(stmt.analyze);
}
#[rstest]
fn test_vacuum_with_vacuum_option() {
let opt = VacuumOption::new().full(true).analyze(true);
let mut stmt = VacuumStatement::new();
stmt.table("users").options(opt);
assert_eq!(stmt.tables.len(), 1);
assert!(stmt.full);
assert!(!stmt.freeze);
assert!(!stmt.verbose);
assert!(stmt.analyze);
}
#[rstest]
fn test_vacuum_take() {
let mut stmt = VacuumStatement::new();
stmt.table("users").full().analyze();
let taken = stmt.take();
assert_eq!(taken.tables.len(), 1);
assert!(taken.full);
assert!(taken.analyze);
assert!(stmt.tables.is_empty());
assert!(!stmt.full);
assert!(!stmt.analyze);
}
}