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