Skip to main content

reinhardt_query/query/materialized_view/
drop_materialized_view.rs

1//! DROP MATERIALIZED VIEW statement builder
2//!
3//! This module provides the `DropMaterializedViewStatement` type for building
4//! SQL DROP MATERIALIZED VIEW queries.
5
6use crate::backend::QueryBuilder;
7use crate::types::{DynIden, IntoIden};
8
9use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
10
11/// DROP MATERIALIZED VIEW statement builder
12///
13/// This struct provides a fluent API for constructing DROP MATERIALIZED VIEW queries.
14///
15/// # Examples
16///
17/// ```rust,ignore
18/// use reinhardt_query::prelude::*;
19///
20/// // Drop single materialized view
21/// let query = Query::drop_materialized_view()
22///     .name("my_mv");
23///
24/// // Drop with IF EXISTS
25/// let query = Query::drop_materialized_view()
26///     .name("my_mv")
27///     .if_exists();
28///
29/// // Drop with CASCADE
30/// let query = Query::drop_materialized_view()
31///     .name("my_mv")
32///     .cascade();
33/// ```
34#[derive(Debug, Clone)]
35pub struct DropMaterializedViewStatement {
36	pub(crate) names: Vec<DynIden>,
37	pub(crate) if_exists: bool,
38	pub(crate) cascade: bool,
39	pub(crate) restrict: bool,
40}
41
42impl DropMaterializedViewStatement {
43	/// Create a new DROP MATERIALIZED VIEW statement
44	pub fn new() -> Self {
45		Self {
46			names: Vec::new(),
47			if_exists: false,
48			cascade: false,
49			restrict: false,
50		}
51	}
52
53	/// Take the ownership of data in the current statement
54	pub fn take(&mut self) -> Self {
55		Self {
56			names: std::mem::take(&mut self.names),
57			if_exists: self.if_exists,
58			cascade: self.cascade,
59			restrict: self.restrict,
60		}
61	}
62
63	/// Set the materialized view name
64	///
65	/// # Examples
66	///
67	/// ```rust,ignore
68	/// use reinhardt_query::prelude::*;
69	///
70	/// let query = Query::drop_materialized_view()
71	///     .name("my_mv");
72	/// ```
73	pub fn name<N>(&mut self, name: N) -> &mut Self
74	where
75		N: IntoIden,
76	{
77		self.names.push(name.into_iden());
78		self
79	}
80
81	/// Add multiple materialized view names
82	///
83	/// # Examples
84	///
85	/// ```rust,ignore
86	/// use reinhardt_query::prelude::*;
87	///
88	/// let query = Query::drop_materialized_view()
89	///     .names(["mv1", "mv2", "mv3"]);
90	/// ```
91	pub fn names<I, N>(&mut self, names: I) -> &mut Self
92	where
93		I: IntoIterator<Item = N>,
94		N: IntoIden,
95	{
96		for name in names {
97			self.names.push(name.into_iden());
98		}
99		self
100	}
101
102	/// Add IF EXISTS clause
103	///
104	/// # Examples
105	///
106	/// ```rust,ignore
107	/// use reinhardt_query::prelude::*;
108	///
109	/// let query = Query::drop_materialized_view()
110	///     .name("my_mv")
111	///     .if_exists();
112	/// ```
113	pub fn if_exists(&mut self) -> &mut Self {
114		self.if_exists = true;
115		self
116	}
117
118	/// Add CASCADE clause
119	///
120	/// # Examples
121	///
122	/// ```rust,ignore
123	/// use reinhardt_query::prelude::*;
124	///
125	/// let query = Query::drop_materialized_view()
126	///     .name("my_mv")
127	///     .cascade();
128	/// ```
129	pub fn cascade(&mut self) -> &mut Self {
130		self.cascade = true;
131		self
132	}
133
134	/// Add RESTRICT clause
135	///
136	/// # Examples
137	///
138	/// ```rust,ignore
139	/// use reinhardt_query::prelude::*;
140	///
141	/// let query = Query::drop_materialized_view()
142	///     .name("my_mv")
143	///     .restrict();
144	/// ```
145	pub fn restrict(&mut self) -> &mut Self {
146		self.restrict = true;
147		self
148	}
149}
150
151impl Default for DropMaterializedViewStatement {
152	fn default() -> Self {
153		Self::new()
154	}
155}
156
157impl QueryStatementBuilder for DropMaterializedViewStatement {
158	fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
159		// Downcast to concrete QueryBuilder type
160		use std::any::Any;
161		if let Some(builder) =
162			(query_builder as &dyn Any).downcast_ref::<crate::backend::PostgresQueryBuilder>()
163		{
164			return builder.build_drop_materialized_view(self);
165		}
166		if let Some(builder) =
167			(query_builder as &dyn Any).downcast_ref::<crate::backend::CockroachDBQueryBuilder>()
168		{
169			return builder.build_drop_materialized_view(self);
170		}
171		if let Some(_builder) =
172			(query_builder as &dyn Any).downcast_ref::<crate::backend::MySqlQueryBuilder>()
173		{
174			panic!("MySQL does not support materialized views");
175		}
176		if let Some(_builder) =
177			(query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
178		{
179			panic!("SQLite does not support materialized views");
180		}
181		panic!("Unsupported query builder type");
182	}
183}
184
185impl QueryStatementWriter for DropMaterializedViewStatement {}
186
187#[cfg(test)]
188mod tests {
189	use super::*;
190	use rstest::*;
191
192	#[rstest]
193	fn test_drop_materialized_view_basic() {
194		let mut stmt = DropMaterializedViewStatement::new();
195		stmt.name("my_mv");
196		assert_eq!(stmt.names.len(), 1);
197		assert_eq!(stmt.names[0].to_string(), "my_mv");
198		assert!(!stmt.if_exists);
199		assert!(!stmt.cascade);
200		assert!(!stmt.restrict);
201	}
202
203	#[rstest]
204	fn test_drop_materialized_view_if_exists() {
205		let mut stmt = DropMaterializedViewStatement::new();
206		stmt.name("my_mv").if_exists();
207		assert!(stmt.if_exists);
208	}
209
210	#[rstest]
211	fn test_drop_materialized_view_cascade() {
212		let mut stmt = DropMaterializedViewStatement::new();
213		stmt.name("my_mv").cascade();
214		assert!(stmt.cascade);
215	}
216
217	#[rstest]
218	fn test_drop_materialized_view_restrict() {
219		let mut stmt = DropMaterializedViewStatement::new();
220		stmt.name("my_mv").restrict();
221		assert!(stmt.restrict);
222	}
223
224	#[rstest]
225	fn test_drop_materialized_view_multiple_names() {
226		let mut stmt = DropMaterializedViewStatement::new();
227		stmt.names(["mv1", "mv2", "mv3"]);
228		assert_eq!(stmt.names.len(), 3);
229		assert_eq!(stmt.names[0].to_string(), "mv1");
230		assert_eq!(stmt.names[1].to_string(), "mv2");
231		assert_eq!(stmt.names[2].to_string(), "mv3");
232	}
233
234	#[rstest]
235	fn test_drop_materialized_view_all_options() {
236		let mut stmt = DropMaterializedViewStatement::new();
237		stmt.name("my_mv").if_exists().cascade();
238		assert_eq!(stmt.names.len(), 1);
239		assert!(stmt.if_exists);
240		assert!(stmt.cascade);
241	}
242
243	#[rstest]
244	fn test_drop_materialized_view_default() {
245		let stmt = DropMaterializedViewStatement::default();
246		assert!(stmt.names.is_empty());
247		assert!(!stmt.if_exists);
248		assert!(!stmt.cascade);
249		assert!(!stmt.restrict);
250	}
251
252	#[rstest]
253	fn test_drop_materialized_view_take() {
254		let mut stmt = DropMaterializedViewStatement::new();
255		stmt.name("my_mv").if_exists();
256		let taken = stmt.take();
257		assert_eq!(taken.names.len(), 1);
258		assert!(taken.if_exists);
259		assert!(stmt.names.is_empty());
260	}
261}