1use sea_query::backend::{
73 EscapeBuilder, ForeignKeyBuilder, GenericBuilder, IndexBuilder, OperLeftAssocDecider,
74 PrecedenceDecider, QueryBuilder, QuotedBuilder, SchemaBuilder, TableBuilder, TableRefBuilder,
75};
76use sea_query::{
77 BinOper, ColumnDef, ColumnType, ExplainStatement, Expr, ForeignKeyCreateStatement,
78 ForeignKeyDropStatement, IndexCreateStatement, IndexDropStatement, Oper, PostgresQueryBuilder,
79 Quote, SelectInto, SubQueryStatement, TableAlterStatement, TableRef, TableRenameStatement,
80 Value,
81};
82
83#[derive(Debug, Clone, Copy, Default)]
127pub struct HyperQueryBuilder;
128
129impl QuotedBuilder for HyperQueryBuilder {
130 fn quote(&self) -> Quote {
131 PostgresQueryBuilder.quote()
132 }
133}
134
135impl EscapeBuilder for HyperQueryBuilder {}
136
137impl TableRefBuilder for HyperQueryBuilder {}
138
139impl OperLeftAssocDecider for HyperQueryBuilder {
140 fn well_known_left_associative(&self, op: &BinOper) -> bool {
141 PostgresQueryBuilder.well_known_left_associative(op)
142 }
143}
144
145impl PrecedenceDecider for HyperQueryBuilder {
146 fn inner_expr_well_known_greater_precedence(&self, inner: &Expr, outer_oper: &Oper) -> bool {
147 PostgresQueryBuilder.inner_expr_well_known_greater_precedence(inner, outer_oper)
148 }
149}
150
151impl QueryBuilder for HyperQueryBuilder {
152 fn prepare_query_statement(
153 &self,
154 query: &SubQueryStatement,
155 sql: &mut impl sea_query::SqlWriter,
156 ) {
157 PostgresQueryBuilder.prepare_query_statement(query, sql);
158 }
159
160 fn prepare_select_into(&self, into_table: &SelectInto, sql: &mut impl sea_query::SqlWriter) {
161 PostgresQueryBuilder.prepare_select_into(into_table, sql);
162 }
163
164 fn prepare_explain_statement(
165 &self,
166 explain: &ExplainStatement,
167 sql: &mut impl sea_query::SqlWriter,
168 ) {
169 PostgresQueryBuilder.prepare_explain_statement(explain, sql);
170 }
171
172 fn prepare_value(&self, value: Value, sql: &mut impl sea_query::SqlWriter) {
173 PostgresQueryBuilder.prepare_value(value, sql);
174 }
175
176 fn placeholder(&self) -> (&'static str, bool) {
177 PostgresQueryBuilder.placeholder()
178 }
179}
180
181impl ForeignKeyBuilder for HyperQueryBuilder {
182 fn prepare_table_ref_fk_stmt(&self, table_ref: &TableRef, sql: &mut impl sea_query::SqlWriter) {
183 PostgresQueryBuilder.prepare_table_ref_fk_stmt(table_ref, sql);
184 }
185
186 fn prepare_foreign_key_create_statement_internal(
187 &self,
188 create: &ForeignKeyCreateStatement,
189 sql: &mut impl sea_query::SqlWriter,
190 mode: sea_query::backend::Mode,
191 ) {
192 PostgresQueryBuilder.prepare_foreign_key_create_statement_internal(create, sql, mode);
193 }
194
195 fn prepare_foreign_key_drop_statement_internal(
196 &self,
197 drop: &ForeignKeyDropStatement,
198 sql: &mut impl sea_query::SqlWriter,
199 mode: sea_query::backend::Mode,
200 ) {
201 PostgresQueryBuilder.prepare_foreign_key_drop_statement_internal(drop, sql, mode);
202 }
203}
204
205impl IndexBuilder for HyperQueryBuilder {
206 fn prepare_index_create_statement(
207 &self,
208 create: &IndexCreateStatement,
209 sql: &mut impl sea_query::SqlWriter,
210 ) {
211 PostgresQueryBuilder.prepare_index_create_statement(create, sql);
212 }
213
214 fn prepare_table_ref_index_stmt(
215 &self,
216 table_ref: &TableRef,
217 sql: &mut impl sea_query::SqlWriter,
218 ) {
219 PostgresQueryBuilder.prepare_table_ref_index_stmt(table_ref, sql);
220 }
221
222 fn prepare_index_drop_statement(
223 &self,
224 drop: &IndexDropStatement,
225 sql: &mut impl sea_query::SqlWriter,
226 ) {
227 PostgresQueryBuilder.prepare_index_drop_statement(drop, sql);
228 }
229
230 fn prepare_index_prefix(
231 &self,
232 create: &IndexCreateStatement,
233 sql: &mut impl sea_query::SqlWriter,
234 ) {
235 PostgresQueryBuilder.prepare_index_prefix(create, sql);
236 }
237}
238
239impl TableBuilder for HyperQueryBuilder {
240 fn prepare_column_def(&self, column_def: &ColumnDef, sql: &mut impl sea_query::SqlWriter) {
241 PostgresQueryBuilder.prepare_column_def(column_def, sql);
242 }
243
244 fn prepare_column_type(&self, column_type: &ColumnType, sql: &mut impl sea_query::SqlWriter) {
245 PostgresQueryBuilder.prepare_column_type(column_type, sql);
246 }
247
248 fn column_spec_auto_increment_keyword(&self) -> &str {
249 PostgresQueryBuilder.column_spec_auto_increment_keyword()
250 }
251
252 fn prepare_table_alter_statement(
253 &self,
254 alter: &TableAlterStatement,
255 sql: &mut impl sea_query::SqlWriter,
256 ) {
257 PostgresQueryBuilder.prepare_table_alter_statement(alter, sql);
258 }
259
260 fn prepare_table_rename_statement(
261 &self,
262 rename: &TableRenameStatement,
263 sql: &mut impl sea_query::SqlWriter,
264 ) {
265 PostgresQueryBuilder.prepare_table_rename_statement(rename, sql);
266 }
267}
268
269impl SchemaBuilder for HyperQueryBuilder {}
270
271impl GenericBuilder for HyperQueryBuilder {}
272
273#[cfg(test)]
274mod tests {
275 use super::*;
276 use sea_query::{ExprTrait, Iden, Query};
277
278 #[derive(Iden)]
279 enum Users {
280 Table,
281 Id,
282 Name,
283 Age,
284 }
285
286 #[test]
287 fn select_generates_valid_sql() {
288 let query = Query::select()
289 .column(Users::Name)
290 .from(Users::Table)
291 .and_where(Expr::col(Users::Age).gt(18))
292 .to_owned();
293
294 let sql = query.to_string(HyperQueryBuilder);
295 assert_eq!(
296 sql,
297 query.to_string(PostgresQueryBuilder),
298 "HyperQueryBuilder should produce identical SQL to PostgresQueryBuilder"
299 );
300 }
301
302 #[test]
303 fn select_build_produces_placeholders() {
304 let query = Query::select()
305 .column(Users::Name)
306 .from(Users::Table)
307 .and_where(Expr::col(Users::Age).gt(18))
308 .to_owned();
309
310 let (sql, values) = query.build(HyperQueryBuilder);
311 let (pg_sql, pg_values) = query.build(PostgresQueryBuilder);
312 assert_eq!(sql, pg_sql);
313 assert_eq!(format!("{values:?}"), format!("{pg_values:?}"));
314 }
315
316 #[test]
317 fn insert_generates_valid_sql() {
318 let query = Query::insert()
319 .into_table(Users::Table)
320 .columns([Users::Name, Users::Age])
321 .values_panic(["Alice".into(), 30i32.into()])
322 .to_owned();
323
324 let sql = query.to_string(HyperQueryBuilder);
325 assert_eq!(sql, query.to_string(PostgresQueryBuilder));
326 }
327
328 #[test]
329 fn update_generates_valid_sql() {
330 let query = Query::update()
331 .table(Users::Table)
332 .value(Users::Name, "Bob")
333 .and_where(Expr::col(Users::Id).eq(1))
334 .to_owned();
335
336 let sql = query.to_string(HyperQueryBuilder);
337 assert_eq!(sql, query.to_string(PostgresQueryBuilder));
338 }
339
340 #[test]
341 fn delete_generates_valid_sql() {
342 let query = Query::delete()
343 .from_table(Users::Table)
344 .and_where(Expr::col(Users::Id).eq(1))
345 .to_owned();
346
347 let sql = query.to_string(HyperQueryBuilder);
348 assert_eq!(sql, query.to_string(PostgresQueryBuilder));
349 }
350
351 #[test]
352 fn create_table_generates_valid_sql() {
353 use sea_query::{ColumnDef, Table};
354
355 let stmt = Table::create()
356 .table(Users::Table)
357 .if_not_exists()
358 .col(ColumnDef::new(Users::Id).integer().not_null().primary_key())
359 .col(ColumnDef::new(Users::Name).string().not_null())
360 .col(ColumnDef::new(Users::Age).integer())
361 .to_owned();
362
363 let sql = stmt.to_string(HyperQueryBuilder);
364 assert_eq!(sql, stmt.to_string(PostgresQueryBuilder));
365 }
366
367 #[test]
368 fn default_trait() {
369 let builder = HyperQueryBuilder;
370 let _ = builder;
372 }
373}