Skip to main content

reinhardt_query/query/sequence/
drop_sequence.rs

1//! DROP SEQUENCE statement builder
2//!
3//! This module provides the `DropSequenceStatement` type for building SQL DROP SEQUENCE queries.
4
5use crate::{
6	backend::QueryBuilder,
7	types::{DynIden, IntoIden},
8};
9
10use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
11
12/// DROP SEQUENCE statement builder
13///
14/// This struct provides a fluent API for constructing DROP SEQUENCE queries.
15///
16/// # Examples
17///
18/// ```rust
19/// use reinhardt_query::prelude::*;
20///
21/// // DROP SEQUENCE my_seq
22/// let query = Query::drop_sequence()
23///     .name("my_seq");
24///
25/// // DROP SEQUENCE IF EXISTS my_seq
26/// let query = Query::drop_sequence()
27///     .name("my_seq")
28///     .if_exists();
29///
30/// // DROP SEQUENCE my_seq CASCADE
31/// let query = Query::drop_sequence()
32///     .name("my_seq")
33///     .cascade();
34/// ```
35#[derive(Debug, Clone)]
36pub struct DropSequenceStatement {
37	pub(crate) name: DynIden,
38	pub(crate) if_exists: bool,
39	pub(crate) cascade: bool,
40	pub(crate) restrict: bool,
41}
42
43impl DropSequenceStatement {
44	/// Create a new DROP SEQUENCE statement
45	///
46	/// # Examples
47	///
48	/// ```rust
49	/// use reinhardt_query::prelude::*;
50	///
51	/// let query = Query::drop_sequence();
52	/// ```
53	pub fn new() -> Self {
54		Self {
55			name: "".into_iden(),
56			if_exists: false,
57			cascade: false,
58			restrict: false,
59		}
60	}
61
62	/// Take the ownership of data in the current [`DropSequenceStatement`]
63	pub fn take(&mut self) -> Self {
64		let taken = Self {
65			name: self.name.clone(),
66			if_exists: self.if_exists,
67			cascade: self.cascade,
68			restrict: self.restrict,
69		};
70		// Reset self to empty state
71		self.name = "".into_iden();
72		self.if_exists = false;
73		self.cascade = false;
74		self.restrict = false;
75		taken
76	}
77
78	/// Set the sequence name
79	///
80	/// # Examples
81	///
82	/// ```rust
83	/// use reinhardt_query::prelude::*;
84	///
85	/// let query = Query::drop_sequence()
86	///     .name("my_seq");
87	/// ```
88	pub fn name<N>(&mut self, name: N) -> &mut Self
89	where
90		N: IntoIden,
91	{
92		self.name = name.into_iden();
93		self
94	}
95
96	/// Add IF EXISTS clause
97	///
98	/// # Examples
99	///
100	/// ```rust
101	/// use reinhardt_query::prelude::*;
102	///
103	/// let query = Query::drop_sequence()
104	///     .name("my_seq")
105	///     .if_exists();
106	/// ```
107	pub fn if_exists(&mut self) -> &mut Self {
108		self.if_exists = true;
109		self
110	}
111
112	/// Add CASCADE clause
113	///
114	/// This will also drop objects that depend on the sequence.
115	///
116	/// # Examples
117	///
118	/// ```rust
119	/// use reinhardt_query::prelude::*;
120	///
121	/// let query = Query::drop_sequence()
122	///     .name("my_seq")
123	///     .cascade();
124	/// ```
125	pub fn cascade(&mut self) -> &mut Self {
126		self.cascade = true;
127		self.restrict = false;
128		self
129	}
130
131	/// Add RESTRICT clause
132	///
133	/// This will refuse to drop the sequence if any objects depend on it (default behavior).
134	///
135	/// # Examples
136	///
137	/// ```rust
138	/// use reinhardt_query::prelude::*;
139	///
140	/// let query = Query::drop_sequence()
141	///     .name("my_seq")
142	///     .restrict();
143	/// ```
144	pub fn restrict(&mut self) -> &mut Self {
145		self.restrict = true;
146		self.cascade = false;
147		self
148	}
149}
150
151impl Default for DropSequenceStatement {
152	fn default() -> Self {
153		Self::new()
154	}
155}
156
157impl QueryStatementBuilder for DropSequenceStatement {
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_sequence(self);
165		}
166		if let Some(builder) =
167			(query_builder as &dyn Any).downcast_ref::<crate::backend::MySqlQueryBuilder>()
168		{
169			return builder.build_drop_sequence(self);
170		}
171		if let Some(builder) =
172			(query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
173		{
174			return builder.build_drop_sequence(self);
175		}
176		panic!("Unsupported query builder type");
177	}
178}
179
180impl QueryStatementWriter for DropSequenceStatement {}
181
182#[cfg(test)]
183mod tests {
184	use super::*;
185	use rstest::*;
186
187	#[rstest]
188	fn test_drop_sequence_new() {
189		let stmt = DropSequenceStatement::new();
190		assert!(stmt.name.to_string().is_empty());
191		assert!(!stmt.if_exists);
192		assert!(!stmt.cascade);
193		assert!(!stmt.restrict);
194	}
195
196	#[rstest]
197	fn test_drop_sequence_with_name() {
198		let mut stmt = DropSequenceStatement::new();
199		stmt.name("my_seq");
200		assert_eq!(stmt.name.to_string(), "my_seq");
201	}
202
203	#[rstest]
204	fn test_drop_sequence_if_exists() {
205		let mut stmt = DropSequenceStatement::new();
206		stmt.name("my_seq").if_exists();
207		assert!(stmt.if_exists);
208	}
209
210	#[rstest]
211	fn test_drop_sequence_cascade() {
212		let mut stmt = DropSequenceStatement::new();
213		stmt.name("my_seq").cascade();
214		assert!(stmt.cascade);
215		assert!(!stmt.restrict);
216	}
217
218	#[rstest]
219	fn test_drop_sequence_restrict() {
220		let mut stmt = DropSequenceStatement::new();
221		stmt.name("my_seq").restrict();
222		assert!(stmt.restrict);
223		assert!(!stmt.cascade);
224	}
225
226	#[rstest]
227	fn test_drop_sequence_cascade_then_restrict() {
228		let mut stmt = DropSequenceStatement::new();
229		stmt.name("my_seq").cascade().restrict();
230		assert!(stmt.restrict);
231		assert!(!stmt.cascade);
232	}
233
234	#[rstest]
235	fn test_drop_sequence_restrict_then_cascade() {
236		let mut stmt = DropSequenceStatement::new();
237		stmt.name("my_seq").restrict().cascade();
238		assert!(stmt.cascade);
239		assert!(!stmt.restrict);
240	}
241
242	#[rstest]
243	fn test_drop_sequence_take() {
244		let mut stmt = DropSequenceStatement::new();
245		stmt.name("my_seq").if_exists().cascade();
246		let taken = stmt.take();
247		assert!(stmt.name.to_string().is_empty());
248		assert!(!stmt.if_exists);
249		assert!(!stmt.cascade);
250		assert_eq!(taken.name.to_string(), "my_seq");
251		assert!(taken.if_exists);
252		assert!(taken.cascade);
253	}
254}