reinhardt_query/query/database/
attach_database.rs1use crate::types::{DynIden, IntoIden};
7
8use crate::query::traits::{QueryBuilderTrait, QueryStatementBuilder, QueryStatementWriter};
9
10#[derive(Debug, Clone)]
26pub struct AttachDatabaseStatement {
27 pub(crate) file_path: Option<String>,
28 pub(crate) database_name: Option<DynIden>,
29}
30
31impl AttachDatabaseStatement {
32 pub fn new() -> Self {
42 Self {
43 file_path: None,
44 database_name: None,
45 }
46 }
47
48 pub fn take(&mut self) -> Self {
50 Self {
51 file_path: self.file_path.take(),
52 database_name: self.database_name.take(),
53 }
54 }
55
56 pub fn file_path<S>(&mut self, path: S) -> &mut Self
67 where
68 S: Into<String>,
69 {
70 self.file_path = Some(path.into());
71 self
72 }
73
74 pub fn as_name<N>(&mut self, name: N) -> &mut Self
86 where
87 N: IntoIden,
88 {
89 self.database_name = Some(name.into_iden());
90 self
91 }
92}
93
94impl Default for AttachDatabaseStatement {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100impl QueryStatementBuilder for AttachDatabaseStatement {
101 fn build_any(&self, query_builder: &dyn QueryBuilderTrait) -> (String, crate::value::Values) {
102 use std::any::Any;
103 if (query_builder as &dyn Any)
104 .downcast_ref::<crate::backend::PostgresQueryBuilder>()
105 .is_some()
106 {
107 panic!("ATTACH DATABASE is SQLite-specific and not supported in PostgreSQL");
108 }
109 if (query_builder as &dyn Any)
110 .downcast_ref::<crate::backend::MySqlQueryBuilder>()
111 .is_some()
112 {
113 panic!("ATTACH DATABASE is SQLite-specific and not supported in MySQL");
114 }
115 if (query_builder as &dyn Any)
116 .downcast_ref::<crate::backend::SqliteQueryBuilder>()
117 .is_some()
118 {
119 let file_path = self
120 .file_path
121 .as_deref()
122 .expect("ATTACH DATABASE requires a file path");
123 let db_name = self
124 .database_name
125 .as_ref()
126 .expect("ATTACH DATABASE requires a schema name (AS clause)");
127 let quote = query_builder.quote_char();
128 let sql = format!(
129 "ATTACH DATABASE '{}' AS {}{}{}",
130 file_path,
131 quote,
132 db_name.to_string(),
133 quote,
134 );
135 return (sql, crate::value::Values::new());
136 }
137 if (query_builder as &dyn Any)
138 .downcast_ref::<crate::backend::CockroachDBQueryBuilder>()
139 .is_some()
140 {
141 panic!("ATTACH DATABASE is SQLite-specific and not supported in CockroachDB");
142 }
143 panic!("Unsupported query builder type");
144 }
145}
146
147impl QueryStatementWriter for AttachDatabaseStatement {}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use rstest::*;
153
154 #[rstest]
155 fn test_attach_database_new() {
156 let stmt = AttachDatabaseStatement::new();
157 assert!(stmt.file_path.is_none());
158 assert!(stmt.database_name.is_none());
159 }
160
161 #[rstest]
162 fn test_attach_database_with_file_path() {
163 let mut stmt = AttachDatabaseStatement::new();
164 stmt.file_path("path/to/db.sqlite");
165 assert_eq!(stmt.file_path.as_ref().unwrap(), "path/to/db.sqlite");
166 }
167
168 #[rstest]
169 fn test_attach_database_with_as_name() {
170 let mut stmt = AttachDatabaseStatement::new();
171 stmt.as_name("auxiliary");
172 assert_eq!(
173 stmt.database_name.as_ref().unwrap().to_string(),
174 "auxiliary"
175 );
176 }
177
178 #[rstest]
179 fn test_attach_database_full() {
180 let mut stmt = AttachDatabaseStatement::new();
181 stmt.file_path("path/to/db.sqlite").as_name("auxiliary");
182 assert_eq!(stmt.file_path.as_ref().unwrap(), "path/to/db.sqlite");
183 assert_eq!(
184 stmt.database_name.as_ref().unwrap().to_string(),
185 "auxiliary"
186 );
187 }
188
189 #[rstest]
190 fn test_attach_database_take() {
191 let mut stmt = AttachDatabaseStatement::new();
192 stmt.file_path("path/to/db.sqlite").as_name("auxiliary");
193 let taken = stmt.take();
194 assert!(stmt.file_path.is_none());
195 assert!(stmt.database_name.is_none());
196 assert_eq!(taken.file_path.as_ref().unwrap(), "path/to/db.sqlite");
197 assert_eq!(
198 taken.database_name.as_ref().unwrap().to_string(),
199 "auxiliary"
200 );
201 }
202
203 #[rstest]
204 fn test_attach_database_default() {
205 let stmt = AttachDatabaseStatement::default();
206 assert!(stmt.file_path.is_none());
207 assert!(stmt.database_name.is_none());
208 }
209}