sea_query/query/insert.rs
1use inherent::inherent;
2
3use crate::{
4 DynIden, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, QueryBuilder, QueryStatement,
5 QueryStatementBuilder, QueryStatementWriter, ReturningClause, SelectStatement, SqlWriter,
6 SubQueryStatement, TableRef, Values, WithClause, WithQuery,
7 error::{Error, Result},
8};
9
10/// Represents a value source that can be used in an insert query.
11///
12/// [`InsertValueSource`] is a node in the expression tree and can represent a raw value set
13/// ('VALUES') or a select query.
14#[derive(Debug, Clone, PartialEq)]
15pub(crate) enum InsertValueSource {
16 Values(Vec<Vec<Expr>>),
17 Select(Box<SelectStatement>),
18}
19
20/// Insert any new rows into an existing table
21///
22/// # Examples
23///
24/// ```
25/// use sea_query::{audit::*, tests_cfg::*, *};
26///
27/// let query = Query::insert()
28/// .into_table(Glyph::Table)
29/// .columns([Glyph::Aspect, Glyph::Image])
30/// .values_panic([5.15.into(), "12A".into()])
31/// .values_panic([4.21.into(), "123".into()])
32/// .take();
33///
34/// assert_eq!(
35/// query.to_string(MysqlQueryBuilder),
36/// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (5.15, '12A'), (4.21, '123')"#
37/// );
38/// assert_eq!(
39/// query.to_string(PostgresQueryBuilder),
40/// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (5.15, '12A'), (4.21, '123')"#
41/// );
42/// assert_eq!(
43/// query.to_string(SqliteQueryBuilder),
44/// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (5.15, '12A'), (4.21, '123')"#
45/// );
46/// assert_eq!(
47/// query.audit().unwrap().inserted_tables(),
48/// [Glyph::Table.into_iden()]
49/// );
50/// ```
51#[derive(Debug, Default, Clone, PartialEq)]
52pub struct InsertStatement {
53 pub(crate) replace: bool,
54 pub(crate) table: Option<Box<TableRef>>,
55 pub(crate) columns: Vec<DynIden>,
56 pub(crate) source: Option<InsertValueSource>,
57 pub(crate) on_conflict: Option<OnConflict>,
58 pub(crate) returning: Option<ReturningClause>,
59 pub(crate) default_values: Option<u32>,
60 pub(crate) with: Option<WithClause>,
61}
62
63impl InsertStatement {
64 /// Construct a new [`InsertStatement`]
65 pub fn new() -> Self {
66 Self::default()
67 }
68
69 /// Take the ownership of data in the current [`SelectStatement`]
70 pub fn take(&mut self) -> Self {
71 Self {
72 replace: self.replace,
73 table: self.table.take(),
74 columns: std::mem::take(&mut self.columns),
75 source: self.source.take(),
76 on_conflict: self.on_conflict.take(),
77 returning: self.returning.take(),
78 default_values: self.default_values.take(),
79 with: self.with.take(),
80 }
81 }
82
83 /// Use REPLACE instead of INSERT
84 ///
85 /// # Examples
86 ///
87 /// ```
88 /// use sea_query::{tests_cfg::*, *};
89 ///
90 /// let query = Query::insert()
91 /// .replace()
92 /// .into_table(Glyph::Table)
93 /// .columns([Glyph::Aspect, Glyph::Image])
94 /// .values_panic([5.15.into(), "12A".into()])
95 /// .take();
96 ///
97 /// assert_eq!(
98 /// query.to_string(MysqlQueryBuilder),
99 /// r#"REPLACE INTO `glyph` (`aspect`, `image`) VALUES (5.15, '12A')"#
100 /// );
101 /// assert_eq!(
102 /// query.to_string(SqliteQueryBuilder),
103 /// r#"REPLACE INTO "glyph" ("aspect", "image") VALUES (5.15, '12A')"#
104 /// );
105 /// ```
106 #[cfg(any(feature = "backend-sqlite", feature = "backend-mysql"))]
107 pub fn replace(&mut self) -> &mut Self {
108 self.replace = true;
109 self
110 }
111
112 /// Specify which table to insert into.
113 ///
114 /// # Examples
115 ///
116 /// See [`InsertStatement::values`]
117 pub fn into_table<T>(&mut self, tbl_ref: T) -> &mut Self
118 where
119 T: IntoTableRef,
120 {
121 self.table = Some(Box::new(tbl_ref.into_table_ref()));
122 self
123 }
124
125 /// Specify what columns to insert.
126 ///
127 /// # Examples
128 ///
129 /// See [`InsertStatement::values`]
130 pub fn columns<C, I>(&mut self, columns: I) -> &mut Self
131 where
132 C: IntoIden,
133 I: IntoIterator<Item = C>,
134 {
135 self.columns = columns.into_iter().map(|c| c.into_iden()).collect();
136 self
137 }
138
139 /// Specify a select query whose values to be inserted.
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// use sea_query::{audit::*, tests_cfg::*, *};
145 ///
146 /// let query = Query::insert()
147 /// .into_table(Glyph::Table)
148 /// .columns([Glyph::Aspect, Glyph::Image])
149 /// .select_from(Query::select()
150 /// .column(Glyph::Aspect)
151 /// .column(Glyph::Image)
152 /// .from(Glyph::Table)
153 /// .and_where(Expr::col(Glyph::Image).like("0%"))
154 /// .take()
155 /// )
156 /// .unwrap()
157 /// .take();
158 ///
159 /// assert_eq!(
160 /// query.to_string(MysqlQueryBuilder),
161 /// r#"INSERT INTO `glyph` (`aspect`, `image`) SELECT `aspect`, `image` FROM `glyph` WHERE `image` LIKE '0%'"#
162 /// );
163 /// assert_eq!(
164 /// query.to_string(PostgresQueryBuilder),
165 /// r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
166 /// );
167 /// assert_eq!(
168 /// query.to_string(SqliteQueryBuilder),
169 /// r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
170 /// );
171 /// assert_eq!(
172 /// query.audit().unwrap().selected_tables(),
173 /// [Glyph::Table.into_iden()]
174 /// );
175 /// assert_eq!(
176 /// query.audit().unwrap().inserted_tables(),
177 /// [Glyph::Table.into_iden()]
178 /// );
179 /// ```
180 ///
181 /// ```
182 /// use sea_query::{tests_cfg::*, *};
183 /// let query = Query::insert()
184 /// .into_table(Glyph::Table)
185 /// .columns([Glyph::Image])
186 /// .select_from(
187 /// Query::select()
188 /// .expr(Expr::val("hello"))
189 /// .cond_where(Cond::all().not().add(Expr::exists(
190 /// Query::select().expr(Expr::val("world")).take(),
191 /// )))
192 /// .take(),
193 /// )
194 /// .unwrap()
195 /// .take();
196 ///
197 /// assert_eq!(
198 /// query.to_string(SqliteQueryBuilder),
199 /// r#"INSERT INTO "glyph" ("image") SELECT 'hello' WHERE NOT EXISTS(SELECT 'world')"#
200 /// );
201 /// ```
202 ///
203 /// ```
204 /// use sea_query::{audit::*, tests_cfg::*, *};
205 /// let query = Query::insert()
206 /// .into_table(Glyph::Table)
207 /// .columns([Glyph::Image])
208 /// .select_from(
209 /// Query::select()
210 /// .expr(Expr::col(Font::Name))
211 /// .from(Font::Table)
212 /// .take(),
213 /// )
214 /// .unwrap()
215 /// .take();
216 ///
217 /// assert_eq!(
218 /// query.to_string(SqliteQueryBuilder),
219 /// r#"INSERT INTO "glyph" ("image") SELECT "name" FROM "font""#
220 /// );
221 /// assert_eq!(
222 /// query.audit().unwrap().selected_tables(),
223 /// [Font::Table.into_iden()]
224 /// );
225 /// assert_eq!(
226 /// query.audit().unwrap().inserted_tables(),
227 /// [Glyph::Table.into_iden()]
228 /// );
229 /// ```
230 pub fn select_from<S>(&mut self, select: S) -> Result<&mut Self>
231 where
232 S: Into<SelectStatement>,
233 {
234 let statement = select.into();
235
236 if self.columns.len() != statement.selects.len() {
237 return Err(Error::ColValNumMismatch {
238 col_len: self.columns.len(),
239 val_len: statement.selects.len(),
240 });
241 }
242
243 self.source = Some(InsertValueSource::Select(Box::new(statement)));
244 Ok(self)
245 }
246
247 /// Specify a row of values to be inserted.
248 ///
249 /// Return error when number of values not matching number of columns.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// use sea_query::{tests_cfg::*, *};
255 ///
256 /// let query = Query::insert()
257 /// .into_table(Glyph::Table)
258 /// .columns([Glyph::Aspect, Glyph::Image])
259 /// .values([
260 /// 2.into(),
261 /// Func::cast_as("2020-02-02 00:00:00", "DATE").into(),
262 /// ])
263 /// .unwrap()
264 /// .take();
265 ///
266 /// assert_eq!(
267 /// query.to_string(MysqlQueryBuilder),
268 /// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
269 /// );
270 /// assert_eq!(
271 /// query.to_string(PostgresQueryBuilder),
272 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
273 /// );
274 /// assert_eq!(
275 /// query.to_string(SqliteQueryBuilder),
276 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
277 /// );
278 ///
279 /// assert!(
280 /// Query::insert()
281 /// .into_table(Glyph::Table)
282 /// .columns([Glyph::Aspect, Glyph::Image])
283 /// .values([1.into()])
284 /// .is_err()
285 /// );
286 /// ```
287 pub fn values<I>(&mut self, values: I) -> Result<&mut Self>
288 where
289 I: IntoIterator<Item = Expr>,
290 {
291 let values = values.into_iter().collect::<Vec<Expr>>();
292 if self.columns.len() != values.len() {
293 return Err(Error::ColValNumMismatch {
294 col_len: self.columns.len(),
295 val_len: values.len(),
296 });
297 }
298 if !values.is_empty() {
299 let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
300 values
301 } else {
302 self.source = Some(InsertValueSource::Values(Default::default()));
303 if let Some(InsertValueSource::Values(values)) = &mut self.source {
304 values
305 } else {
306 unreachable!();
307 }
308 };
309 values_source.push(values);
310 }
311 Ok(self)
312 }
313
314 /// Specify a row of values to be inserted, variation of [`InsertStatement::values`].
315 ///
316 /// # Panics
317 ///
318 /// Panics when number of values not matching number of columns.
319 /// The equivalent `insert_many` method in SeaORM does not panic, it can construct the column list from active models.
320 ///
321 /// # Examples
322 ///
323 /// ```
324 /// use sea_query::{tests_cfg::*, *};
325 ///
326 /// let query = Query::insert()
327 /// .into_table(Glyph::Table)
328 /// .columns([Glyph::Aspect, Glyph::Image])
329 /// .values_panic([2.1345.into(), "24B".into()])
330 /// .values_panic([5.15.into(), "12A".into()])
331 /// .take();
332 ///
333 /// assert_eq!(
334 /// query.to_string(MysqlQueryBuilder),
335 /// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
336 /// );
337 /// assert_eq!(
338 /// query.to_string(PostgresQueryBuilder),
339 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
340 /// );
341 /// assert_eq!(
342 /// query.to_string(SqliteQueryBuilder),
343 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
344 /// );
345 /// ```
346 ///
347 /// ```should_panic
348 /// # use sea_query::{tests_cfg::*, *};
349 /// let query = Query::insert()
350 /// .into_table(Glyph::Table)
351 /// .columns([Glyph::Aspect])
352 /// .values_panic([2.1345.into(), "24B".into()])
353 /// .take();
354 /// ```
355 ///
356 /// The same query can be constructed using the `raw_query!` macro.
357 ///
358 /// ```
359 /// use sea_query::Values;
360 ///
361 /// let values = vec![(2.1345, "24B"), (5.15, "12A")];
362 /// let query = sea_query::raw_query!(
363 /// PostgresQueryBuilder,
364 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.0:1),}"#
365 /// );
366 ///
367 /// assert_eq!(
368 /// query.sql,
369 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ($1, $2), ($3, $4)"#
370 /// );
371 /// assert_eq!(
372 /// query.values,
373 /// Values(vec![2.1345.into(), "24B".into(), 5.15.into(), "12A".into()])
374 /// );
375 ///
376 /// // same as above but with named fields:
377 ///
378 /// struct Item<'a> {
379 /// aspect: f64,
380 /// image: &'a str,
381 /// };
382 ///
383 /// let values = vec![
384 /// Item {
385 /// aspect: 2.1345,
386 /// image: "24B",
387 /// },
388 /// Item {
389 /// aspect: 5.15,
390 /// image: "12A",
391 /// },
392 /// ];
393 ///
394 /// let new_query = sea_query::raw_query!(
395 /// PostgresQueryBuilder,
396 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.aspect, values.image),}"#
397 /// );
398 ///
399 /// assert_eq!(query.sql, new_query.sql);
400 /// assert_eq!(query.values, new_query.values);
401 /// ```
402 pub fn values_panic<I>(&mut self, values: I) -> &mut Self
403 where
404 I: IntoIterator<Item = Expr>,
405 {
406 self.values(values).unwrap()
407 }
408
409 /// Add rows to be inserted from an iterator, variation of [`InsertStatement::values_panic`].
410 ///
411 /// # Examples
412 ///
413 /// ```
414 /// use sea_query::{audit::*, tests_cfg::*, *};
415 ///
416 /// let rows = vec![[2.1345.into(), "24B".into()], [5.15.into(), "12A".into()]];
417 ///
418 /// let query = Query::insert()
419 /// .into_table(Glyph::Table)
420 /// .columns([Glyph::Aspect, Glyph::Image])
421 /// .values_from_panic(rows)
422 /// .take();
423 ///
424 /// assert_eq!(
425 /// query.to_string(MysqlQueryBuilder),
426 /// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
427 /// );
428 /// assert_eq!(
429 /// query.to_string(PostgresQueryBuilder),
430 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
431 /// );
432 /// assert_eq!(
433 /// query.to_string(SqliteQueryBuilder),
434 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
435 /// );
436 /// assert_eq!(
437 /// query.audit().unwrap().inserted_tables(),
438 /// [Glyph::Table.into_iden()]
439 /// );
440 /// ```
441 pub fn values_from_panic<I, J>(&mut self, values_iter: J) -> &mut Self
442 where
443 I: IntoIterator<Item = Expr>,
444 J: IntoIterator<Item = I>,
445 {
446 values_iter.into_iter().for_each(|values| {
447 self.values_panic(values);
448 });
449 self
450 }
451
452 /// ON CONFLICT expression
453 ///
454 /// # Examples
455 ///
456 /// - [`OnConflict::update_columns`]: Update column value of existing row with inserting value
457 pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
458 self.on_conflict = Some(on_conflict);
459 self
460 }
461
462 /// RETURNING expressions.
463 ///
464 /// # Examples
465 ///
466 /// ```
467 /// use sea_query::{tests_cfg::*, *};
468 ///
469 /// let query = Query::insert()
470 /// .into_table(Glyph::Table)
471 /// .columns([Glyph::Image])
472 /// .values_panic(["12A".into()])
473 /// .returning(Query::returning().columns([Glyph::Id]))
474 /// .take();
475 ///
476 /// assert_eq!(
477 /// query.to_string(MysqlQueryBuilder),
478 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
479 /// );
480 /// assert_eq!(
481 /// query.to_string(PostgresQueryBuilder),
482 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
483 /// );
484 /// assert_eq!(
485 /// query.to_string(SqliteQueryBuilder),
486 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
487 /// );
488 /// ```
489 pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
490 self.returning = Some(returning);
491 self
492 }
493
494 /// RETURNING expressions for a column.
495 ///
496 /// # Examples
497 ///
498 /// ```
499 /// use sea_query::{tests_cfg::*, *};
500 ///
501 /// let query = Query::insert()
502 /// .into_table(Glyph::Table)
503 /// .columns([Glyph::Image])
504 /// .values_panic(["12A".into()])
505 /// .returning_col(Glyph::Id)
506 /// .take();
507 ///
508 /// assert_eq!(
509 /// query.to_string(MysqlQueryBuilder),
510 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
511 /// );
512 /// assert_eq!(
513 /// query.to_string(PostgresQueryBuilder),
514 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
515 /// );
516 /// assert_eq!(
517 /// query.to_string(SqliteQueryBuilder),
518 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
519 /// );
520 /// ```
521 pub fn returning_col<C>(&mut self, col: C) -> &mut Self
522 where
523 C: IntoColumnRef,
524 {
525 self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
526 }
527
528 /// RETURNING expressions all columns.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// use sea_query::{tests_cfg::*, *};
534 ///
535 /// let query = Query::insert()
536 /// .into_table(Glyph::Table)
537 /// .columns([Glyph::Image])
538 /// .values_panic(["12A".into()])
539 /// .returning_all()
540 /// .take();
541 ///
542 /// assert_eq!(
543 /// query.to_string(MysqlQueryBuilder),
544 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
545 /// );
546 /// assert_eq!(
547 /// query.to_string(PostgresQueryBuilder),
548 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
549 /// );
550 /// assert_eq!(
551 /// query.to_string(SqliteQueryBuilder),
552 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
553 /// );
554 /// ```
555 pub fn returning_all(&mut self) -> &mut Self {
556 self.returning(ReturningClause::All)
557 }
558
559 /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
560 ///
561 /// # Examples
562 ///
563 /// ```
564 /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
565 ///
566 /// let select = SelectStatement::new()
567 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
568 /// .from(Glyph::Table)
569 /// .take();
570 /// let cte = CommonTableExpression::new()
571 /// .query(select)
572 /// .column(Glyph::Id)
573 /// .column(Glyph::Image)
574 /// .column(Glyph::Aspect)
575 /// .table_name("cte")
576 /// .to_owned();
577 /// let with_clause = WithClause::new().cte(cte).to_owned();
578 /// let select = SelectStatement::new()
579 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
580 /// .from("cte")
581 /// .take();
582 /// let mut insert = Query::insert();
583 /// insert
584 /// .into_table(Glyph::Table)
585 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
586 /// .select_from(select)
587 /// .unwrap();
588 /// let query = insert.with(with_clause);
589 ///
590 /// assert_eq!(
591 /// query.to_string(MysqlQueryBuilder),
592 /// r#"WITH `cte` (`id`, `image`, `aspect`) AS (SELECT `id`, `image`, `aspect` FROM `glyph`) INSERT INTO `glyph` (`id`, `image`, `aspect`) SELECT `id`, `image`, `aspect` FROM `cte`"#
593 /// );
594 /// assert_eq!(
595 /// query.to_string(PostgresQueryBuilder),
596 /// r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
597 /// );
598 /// assert_eq!(
599 /// query.to_string(SqliteQueryBuilder),
600 /// r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
601 /// );
602 /// ```
603 pub fn with(self, clause: WithClause) -> WithQuery {
604 clause.query(self)
605 }
606
607 /// Create a Common Table Expression by specifying a [CommonTableExpression][crate::CommonTableExpression]
608 /// or [WithClause] to execute this query with.
609 ///
610 /// # Examples
611 ///
612 /// ```
613 /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
614 ///
615 /// let select = SelectStatement::new()
616 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
617 /// .from(Glyph::Table)
618 /// .take();
619 /// let cte = CommonTableExpression::new()
620 /// .query(select)
621 /// .column(Glyph::Id)
622 /// .column(Glyph::Image)
623 /// .column(Glyph::Aspect)
624 /// .table_name("cte")
625 /// .to_owned();
626 /// let with_clause = WithClause::new().cte(cte).to_owned();
627 /// let select = SelectStatement::new()
628 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
629 /// .from("cte")
630 /// .take();
631 /// let mut query = Query::insert();
632 /// query
633 /// .with_cte(with_clause)
634 /// .into_table(Glyph::Table)
635 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
636 /// .select_from(select)
637 /// .unwrap();
638 ///
639 /// assert_eq!(
640 /// query.to_string(MysqlQueryBuilder),
641 /// r#"WITH `cte` (`id`, `image`, `aspect`) AS (SELECT `id`, `image`, `aspect` FROM `glyph`) INSERT INTO `glyph` (`id`, `image`, `aspect`) SELECT `id`, `image`, `aspect` FROM `cte`"#
642 /// );
643 /// assert_eq!(
644 /// query.to_string(PostgresQueryBuilder),
645 /// r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
646 /// );
647 /// assert_eq!(
648 /// query.to_string(SqliteQueryBuilder),
649 /// r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
650 /// );
651 /// ```
652 pub fn with_cte<C: Into<WithClause>>(&mut self, clause: C) -> &mut Self {
653 self.with = Some(clause.into());
654 self
655 }
656
657 /// Insert with default values if columns and values are not supplied.
658 ///
659 /// # Examples
660 ///
661 /// ```
662 /// use sea_query::{tests_cfg::*, *};
663 ///
664 /// // Insert default
665 /// let query = Query::insert()
666 /// .into_table(Glyph::Table)
667 /// .or_default_values()
668 /// .take();
669 ///
670 /// assert_eq!(
671 /// query.to_string(MysqlQueryBuilder),
672 /// r#"INSERT INTO `glyph` VALUES ()"#
673 /// );
674 /// assert_eq!(
675 /// query.to_string(PostgresQueryBuilder),
676 /// r#"INSERT INTO "glyph" VALUES (DEFAULT)"#
677 /// );
678 /// assert_eq!(
679 /// query.to_string(SqliteQueryBuilder),
680 /// r#"INSERT INTO "glyph" DEFAULT VALUES"#
681 /// );
682 ///
683 /// // Ordinary insert as columns and values are supplied
684 /// let query = Query::insert()
685 /// .into_table(Glyph::Table)
686 /// .or_default_values()
687 /// .columns([Glyph::Image])
688 /// .values_panic(["ABC".into()])
689 /// .take();
690 ///
691 /// assert_eq!(
692 /// query.to_string(MysqlQueryBuilder),
693 /// r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
694 /// );
695 /// assert_eq!(
696 /// query.to_string(PostgresQueryBuilder),
697 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
698 /// );
699 /// assert_eq!(
700 /// query.to_string(SqliteQueryBuilder),
701 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
702 /// );
703 /// ```
704 pub fn or_default_values(&mut self) -> &mut Self {
705 self.default_values = Some(1);
706 self
707 }
708
709 /// Insert multiple rows with default values if columns and values are not supplied.
710 ///
711 /// # Examples
712 ///
713 /// ```
714 /// use sea_query::{tests_cfg::*, *};
715 ///
716 /// // Insert default
717 /// let query = Query::insert()
718 /// .into_table(Glyph::Table)
719 /// .or_default_values_many(3)
720 /// .take();
721 ///
722 /// assert_eq!(
723 /// query.to_string(MysqlQueryBuilder),
724 /// r#"INSERT INTO `glyph` VALUES (), (), ()"#
725 /// );
726 /// assert_eq!(
727 /// query.to_string(PostgresQueryBuilder),
728 /// r#"INSERT INTO "glyph" VALUES (DEFAULT), (DEFAULT), (DEFAULT)"#
729 /// );
730 /// assert_eq!(
731 /// query.to_string(SqliteQueryBuilder),
732 /// r#"INSERT INTO "glyph" DEFAULT VALUES"#
733 /// );
734 ///
735 /// // Ordinary insert as columns and values are supplied
736 /// let query = Query::insert()
737 /// .into_table(Glyph::Table)
738 /// .or_default_values_many(3)
739 /// .columns([Glyph::Image])
740 /// .values_panic(["ABC".into()])
741 /// .take();
742 ///
743 /// assert_eq!(
744 /// query.to_string(MysqlQueryBuilder),
745 /// r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
746 /// );
747 /// assert_eq!(
748 /// query.to_string(PostgresQueryBuilder),
749 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
750 /// );
751 /// assert_eq!(
752 /// query.to_string(SqliteQueryBuilder),
753 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
754 /// );
755 /// ```
756 pub fn or_default_values_many(&mut self, num_rows: u32) -> &mut Self {
757 self.default_values = Some(num_rows);
758 self
759 }
760}
761
762#[inherent]
763impl QueryStatementBuilder for InsertStatement {
764 pub fn build_collect_any_into(
765 &self,
766 query_builder: &impl QueryBuilder,
767 sql: &mut impl SqlWriter,
768 ) {
769 query_builder.prepare_insert_statement(self, sql);
770 }
771
772 pub fn build_any(&self, query_builder: &impl QueryBuilder) -> (String, Values);
773 pub fn build_collect_any(
774 &self,
775 query_builder: &impl QueryBuilder,
776 sql: &mut impl SqlWriter,
777 ) -> String;
778}
779
780impl From<InsertStatement> for QueryStatement {
781 fn from(s: InsertStatement) -> Self {
782 Self::Insert(s)
783 }
784}
785
786impl From<InsertStatement> for SubQueryStatement {
787 fn from(s: InsertStatement) -> Self {
788 Self::InsertStatement(s)
789 }
790}
791
792#[inherent]
793impl QueryStatementWriter for InsertStatement {
794 pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
795 query_builder.prepare_insert_statement(self, sql);
796 }
797
798 pub fn build_collect<T: QueryBuilder>(
799 &self,
800 query_builder: T,
801 sql: &mut impl SqlWriter,
802 ) -> String;
803 pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values);
804 pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String;
805}