reinhardt_query/query/database/
alter_database.rs1use crate::{
6 backend::QueryBuilder,
7 types::{DatabaseOperation, DynIden, IntoIden, ZoneConfig},
8};
9
10use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
11
12#[derive(Debug, Clone)]
38pub struct AlterDatabaseStatement {
39 pub(crate) database_name: Option<DynIden>,
40 pub(crate) operations: Vec<DatabaseOperation>,
41}
42
43impl AlterDatabaseStatement {
44 pub fn new() -> Self {
54 Self {
55 database_name: None,
56 operations: Vec::new(),
57 }
58 }
59
60 pub fn take(&mut self) -> Self {
62 Self {
63 database_name: self.database_name.take(),
64 operations: std::mem::take(&mut self.operations),
65 }
66 }
67
68 pub fn name<N>(&mut self, name: N) -> &mut Self
79 where
80 N: IntoIden,
81 {
82 self.database_name = Some(name.into_iden());
83 self
84 }
85
86 pub fn rename_to<N>(&mut self, new_name: N) -> &mut Self
98 where
99 N: IntoIden,
100 {
101 self.operations
102 .push(DatabaseOperation::RenameDatabase(new_name.into_iden()));
103 self
104 }
105
106 pub fn owner_to<O>(&mut self, new_owner: O) -> &mut Self
118 where
119 O: IntoIden,
120 {
121 self.operations
122 .push(DatabaseOperation::OwnerTo(new_owner.into_iden()));
123 self
124 }
125
126 pub fn add_region<S>(&mut self, region: S) -> &mut Self
138 where
139 S: Into<String>,
140 {
141 self.operations
142 .push(DatabaseOperation::AddRegion(region.into()));
143 self
144 }
145
146 pub fn drop_region<S>(&mut self, region: S) -> &mut Self
158 where
159 S: Into<String>,
160 {
161 self.operations
162 .push(DatabaseOperation::DropRegion(region.into()));
163 self
164 }
165
166 pub fn set_primary_region<S>(&mut self, region: S) -> &mut Self
178 where
179 S: Into<String>,
180 {
181 self.operations
182 .push(DatabaseOperation::SetPrimaryRegion(region.into()));
183 self
184 }
185
186 pub fn configure_zone(&mut self, zone: ZoneConfig) -> &mut Self {
203 self.operations.push(DatabaseOperation::ConfigureZone(zone));
204 self
205 }
206}
207
208impl Default for AlterDatabaseStatement {
209 fn default() -> Self {
210 Self::new()
211 }
212}
213
214impl QueryStatementBuilder for AlterDatabaseStatement {
215 fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
216 use std::any::Any;
218 if let Some(builder) =
219 (query_builder as &dyn Any).downcast_ref::<crate::backend::PostgresQueryBuilder>()
220 {
221 return builder.build_alter_database(self);
222 }
223 if let Some(builder) =
224 (query_builder as &dyn Any).downcast_ref::<crate::backend::MySqlQueryBuilder>()
225 {
226 return builder.build_alter_database(self);
227 }
228 if let Some(builder) =
229 (query_builder as &dyn Any).downcast_ref::<crate::backend::SqliteQueryBuilder>()
230 {
231 return builder.build_alter_database(self);
232 }
233 if let Some(builder) =
234 (query_builder as &dyn Any).downcast_ref::<crate::backend::CockroachDBQueryBuilder>()
235 {
236 return builder.build_alter_database(self);
237 }
238 panic!("Unsupported query builder type");
239 }
240}
241
242impl QueryStatementWriter for AlterDatabaseStatement {}
243
244#[cfg(test)]
245mod tests {
246 use super::*;
247 use rstest::*;
248
249 #[rstest]
250 fn test_alter_database_new() {
251 let stmt = AlterDatabaseStatement::new();
252 assert!(stmt.database_name.is_none());
253 assert!(stmt.operations.is_empty());
254 }
255
256 #[rstest]
257 fn test_alter_database_with_name() {
258 let mut stmt = AlterDatabaseStatement::new();
259 stmt.name("mydb");
260 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
261 }
262
263 #[rstest]
264 fn test_alter_database_rename_to() {
265 let mut stmt = AlterDatabaseStatement::new();
266 stmt.name("old_db").rename_to("new_db");
267 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "old_db");
268 assert_eq!(stmt.operations.len(), 1);
269 match &stmt.operations[0] {
270 DatabaseOperation::RenameDatabase(name) => {
271 assert_eq!(name.to_string(), "new_db");
272 }
273 _ => panic!("Expected RenameDatabase operation"),
274 }
275 }
276
277 #[rstest]
278 fn test_alter_database_owner_to() {
279 let mut stmt = AlterDatabaseStatement::new();
280 stmt.name("mydb").owner_to("new_owner");
281 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
282 assert_eq!(stmt.operations.len(), 1);
283 match &stmt.operations[0] {
284 DatabaseOperation::OwnerTo(owner) => {
285 assert_eq!(owner.to_string(), "new_owner");
286 }
287 _ => panic!("Expected OwnerTo operation"),
288 }
289 }
290
291 #[rstest]
292 fn test_alter_database_add_region() {
293 let mut stmt = AlterDatabaseStatement::new();
294 stmt.name("mydb").add_region("us-east-1");
295 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
296 assert_eq!(stmt.operations.len(), 1);
297 match &stmt.operations[0] {
298 DatabaseOperation::AddRegion(region) => {
299 assert_eq!(region, "us-east-1");
300 }
301 _ => panic!("Expected AddRegion operation"),
302 }
303 }
304
305 #[rstest]
306 fn test_alter_database_drop_region() {
307 let mut stmt = AlterDatabaseStatement::new();
308 stmt.name("mydb").drop_region("us-west-1");
309 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
310 assert_eq!(stmt.operations.len(), 1);
311 match &stmt.operations[0] {
312 DatabaseOperation::DropRegion(region) => {
313 assert_eq!(region, "us-west-1");
314 }
315 _ => panic!("Expected DropRegion operation"),
316 }
317 }
318
319 #[rstest]
320 fn test_alter_database_set_primary_region() {
321 let mut stmt = AlterDatabaseStatement::new();
322 stmt.name("mydb").set_primary_region("us-east-1");
323 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
324 assert_eq!(stmt.operations.len(), 1);
325 match &stmt.operations[0] {
326 DatabaseOperation::SetPrimaryRegion(region) => {
327 assert_eq!(region, "us-east-1");
328 }
329 _ => panic!("Expected SetPrimaryRegion operation"),
330 }
331 }
332
333 #[rstest]
334 fn test_alter_database_multiple_operations() {
335 let mut stmt = AlterDatabaseStatement::new();
336 stmt.name("mydb")
337 .add_region("us-east-1")
338 .add_region("us-west-1")
339 .set_primary_region("us-east-1");
340 assert_eq!(stmt.operations.len(), 3);
341 }
342
343 #[rstest]
344 fn test_alter_database_take() {
345 let mut stmt = AlterDatabaseStatement::new();
346 stmt.name("mydb").add_region("us-east-1");
347 let taken = stmt.take();
348 assert!(stmt.database_name.is_none());
349 assert!(stmt.operations.is_empty());
350 assert_eq!(taken.database_name.as_ref().unwrap().to_string(), "mydb");
351 assert_eq!(taken.operations.len(), 1);
352 }
353
354 #[rstest]
355 fn test_alter_database_configure_zone() {
356 let mut stmt = AlterDatabaseStatement::new();
357 let zone = ZoneConfig::new()
358 .num_replicas(3)
359 .add_constraint("+region=us-east-1");
360 stmt.name("mydb").configure_zone(zone);
361 assert_eq!(stmt.database_name.as_ref().unwrap().to_string(), "mydb");
362 assert_eq!(stmt.operations.len(), 1);
363 match &stmt.operations[0] {
364 DatabaseOperation::ConfigureZone(config) => {
365 assert_eq!(config.num_replicas, Some(3));
366 assert_eq!(config.constraints.len(), 1);
367 }
368 _ => panic!("Expected ConfigureZone operation"),
369 }
370 }
371
372 #[rstest]
373 fn test_alter_database_configure_zone_multiple_options() {
374 let mut stmt = AlterDatabaseStatement::new();
375 let zone = ZoneConfig::new()
376 .num_replicas(5)
377 .add_constraint("+region=us-east-1")
378 .add_constraint("+zone=a")
379 .add_lease_preference("+region=us-east-1");
380 stmt.name("mydb").configure_zone(zone);
381 assert_eq!(stmt.operations.len(), 1);
382 match &stmt.operations[0] {
383 DatabaseOperation::ConfigureZone(config) => {
384 assert_eq!(config.num_replicas, Some(5));
385 assert_eq!(config.constraints.len(), 2);
386 assert_eq!(config.lease_preferences.len(), 1);
387 }
388 _ => panic!("Expected ConfigureZone operation"),
389 }
390 }
391}