sea_query/query/insert.rs
1use crate::{
2 DynIden, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, QueryBuilder, QueryStatement,
3 QueryStatementBuilder, QueryStatementWriter, ReturningClause, SelectStatement, SqlWriter,
4 SubQueryStatement, TableRef, Values, WithClause, WithQuery,
5 error::{Error, Result},
6};
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 /// The equivalent `insert_many` method in SeaORM does not panic, it can construct the column list from active models.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// use sea_query::{tests_cfg::*, *};
323 ///
324 /// let query = Query::insert()
325 /// .into_table(Glyph::Table)
326 /// .columns([Glyph::Aspect, Glyph::Image])
327 /// .values_panic([2.1345.into(), "24B".into()])
328 /// .values_panic([5.15.into(), "12A".into()])
329 /// .take();
330 ///
331 /// assert_eq!(
332 /// query.to_string(MysqlQueryBuilder),
333 /// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
334 /// );
335 /// assert_eq!(
336 /// query.to_string(PostgresQueryBuilder),
337 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
338 /// );
339 /// assert_eq!(
340 /// query.to_string(SqliteQueryBuilder),
341 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
342 /// );
343 /// ```
344 ///
345 /// ```should_panic
346 /// # use sea_query::{tests_cfg::*, *};
347 /// let query = Query::insert()
348 /// .into_table(Glyph::Table)
349 /// .columns([Glyph::Aspect])
350 /// .values_panic([2.1345.into(), "24B".into()])
351 /// .take();
352 /// ```
353 ///
354 /// The same query can be constructed using the `raw_query!` macro.
355 ///
356 /// ```
357 /// use sea_query::Values;
358 ///
359 /// let values = vec![(2.1345, "24B"), (5.15, "12A")];
360 /// let query = sea_query::raw_query!(
361 /// PostgresQueryBuilder,
362 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.0:1),}"#
363 /// );
364 ///
365 /// assert_eq!(
366 /// query.sql,
367 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES ($1, $2), ($3, $4)"#
368 /// );
369 /// assert_eq!(
370 /// query.values,
371 /// Values(vec![2.1345.into(), "24B".into(), 5.15.into(), "12A".into()])
372 /// );
373 ///
374 /// // same as above but with named fields:
375 ///
376 /// struct Item<'a> {
377 /// aspect: f64,
378 /// image: &'a str,
379 /// };
380 ///
381 /// let values = vec![
382 /// Item {
383 /// aspect: 2.1345,
384 /// image: "24B",
385 /// },
386 /// Item {
387 /// aspect: 5.15,
388 /// image: "12A",
389 /// },
390 /// ];
391 ///
392 /// let new_query = sea_query::raw_query!(
393 /// PostgresQueryBuilder,
394 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.aspect, values.image),}"#
395 /// );
396 ///
397 /// assert_eq!(query.sql, new_query.sql);
398 /// assert_eq!(query.values, new_query.values);
399 /// ```
400 pub fn values_panic<I>(&mut self, values: I) -> &mut Self
401 where
402 I: IntoIterator<Item = Expr>,
403 {
404 self.values(values).unwrap()
405 }
406
407 /// Add rows to be inserted from an iterator, variation of [`InsertStatement::values_panic`].
408 ///
409 /// # Examples
410 ///
411 /// ```
412 /// use sea_query::{audit::*, tests_cfg::*, *};
413 ///
414 /// let rows = vec![[2.1345.into(), "24B".into()], [5.15.into(), "12A".into()]];
415 ///
416 /// let query = Query::insert()
417 /// .into_table(Glyph::Table)
418 /// .columns([Glyph::Aspect, Glyph::Image])
419 /// .values_from_panic(rows)
420 /// .take();
421 ///
422 /// assert_eq!(
423 /// query.to_string(MysqlQueryBuilder),
424 /// r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
425 /// );
426 /// assert_eq!(
427 /// query.to_string(PostgresQueryBuilder),
428 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
429 /// );
430 /// assert_eq!(
431 /// query.to_string(SqliteQueryBuilder),
432 /// r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
433 /// );
434 /// assert_eq!(
435 /// query.audit().unwrap().inserted_tables(),
436 /// [Glyph::Table.into_iden()]
437 /// );
438 /// ```
439 pub fn values_from_panic<I, J>(&mut self, values_iter: J) -> &mut Self
440 where
441 I: IntoIterator<Item = Expr>,
442 J: IntoIterator<Item = I>,
443 {
444 values_iter.into_iter().for_each(|values| {
445 self.values_panic(values);
446 });
447 self
448 }
449
450 /// ON CONFLICT expression
451 ///
452 /// # Examples
453 ///
454 /// - [`OnConflict::update_columns`]: Update column value of existing row with inserting value
455 pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
456 self.on_conflict = Some(on_conflict);
457 self
458 }
459
460 /// RETURNING expressions.
461 ///
462 /// # Examples
463 ///
464 /// ```
465 /// use sea_query::{tests_cfg::*, *};
466 ///
467 /// let query = Query::insert()
468 /// .into_table(Glyph::Table)
469 /// .columns([Glyph::Image])
470 /// .values_panic(["12A".into()])
471 /// .returning(Query::returning().columns([Glyph::Id]))
472 /// .take();
473 ///
474 /// assert_eq!(
475 /// query.to_string(MysqlQueryBuilder),
476 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
477 /// );
478 /// assert_eq!(
479 /// query.to_string(PostgresQueryBuilder),
480 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
481 /// );
482 /// assert_eq!(
483 /// query.to_string(SqliteQueryBuilder),
484 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
485 /// );
486 /// ```
487 pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
488 self.returning = Some(returning);
489 self
490 }
491
492 /// RETURNING expressions for a column.
493 ///
494 /// # Examples
495 ///
496 /// ```
497 /// use sea_query::{tests_cfg::*, *};
498 ///
499 /// let query = Query::insert()
500 /// .into_table(Glyph::Table)
501 /// .columns([Glyph::Image])
502 /// .values_panic(["12A".into()])
503 /// .returning_col(Glyph::Id)
504 /// .take();
505 ///
506 /// assert_eq!(
507 /// query.to_string(MysqlQueryBuilder),
508 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
509 /// );
510 /// assert_eq!(
511 /// query.to_string(PostgresQueryBuilder),
512 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
513 /// );
514 /// assert_eq!(
515 /// query.to_string(SqliteQueryBuilder),
516 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
517 /// );
518 /// ```
519 pub fn returning_col<C>(&mut self, col: C) -> &mut Self
520 where
521 C: IntoColumnRef,
522 {
523 self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
524 }
525
526 /// RETURNING expressions all columns.
527 ///
528 /// # Examples
529 ///
530 /// ```
531 /// use sea_query::{tests_cfg::*, *};
532 ///
533 /// let query = Query::insert()
534 /// .into_table(Glyph::Table)
535 /// .columns([Glyph::Image])
536 /// .values_panic(["12A".into()])
537 /// .returning_all()
538 /// .take();
539 ///
540 /// assert_eq!(
541 /// query.to_string(MysqlQueryBuilder),
542 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
543 /// );
544 /// assert_eq!(
545 /// query.to_string(PostgresQueryBuilder),
546 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
547 /// );
548 /// assert_eq!(
549 /// query.to_string(SqliteQueryBuilder),
550 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
551 /// );
552 /// ```
553 pub fn returning_all(&mut self) -> &mut Self {
554 self.returning(ReturningClause::All)
555 }
556
557 /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
558 ///
559 /// # Examples
560 ///
561 /// ```
562 /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
563 ///
564 /// let select = SelectStatement::new()
565 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
566 /// .from(Glyph::Table)
567 /// .take();
568 /// let cte = CommonTableExpression::new()
569 /// .query(select)
570 /// .column(Glyph::Id)
571 /// .column(Glyph::Image)
572 /// .column(Glyph::Aspect)
573 /// .table_name("cte")
574 /// .to_owned();
575 /// let with_clause = WithClause::new().cte(cte).to_owned();
576 /// let select = SelectStatement::new()
577 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
578 /// .from("cte")
579 /// .take();
580 /// let mut insert = Query::insert();
581 /// insert
582 /// .into_table(Glyph::Table)
583 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
584 /// .select_from(select)
585 /// .unwrap();
586 /// let query = insert.with(with_clause);
587 ///
588 /// assert_eq!(
589 /// query.to_string(MysqlQueryBuilder),
590 /// 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`"#
591 /// );
592 /// assert_eq!(
593 /// query.to_string(PostgresQueryBuilder),
594 /// 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""#
595 /// );
596 /// assert_eq!(
597 /// query.to_string(SqliteQueryBuilder),
598 /// 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""#
599 /// );
600 /// ```
601 pub fn with(self, clause: WithClause) -> WithQuery {
602 clause.query(self)
603 }
604
605 /// Create a Common Table Expression by specifying a [CommonTableExpression][crate::CommonTableExpression]
606 /// 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
760impl QueryStatementBuilder for InsertStatement {
761 fn build_collect_any_into(&self, query_builder: &impl QueryBuilder, sql: &mut impl SqlWriter) {
762 query_builder.prepare_insert_statement(self, sql);
763 }
764}
765
766impl InsertStatement {
767 pub fn build_any(&self, query_builder: &impl QueryBuilder) -> (String, Values) {
768 <Self as QueryStatementBuilder>::build_any(self, query_builder)
769 }
770
771 pub fn build_collect_any(
772 &self,
773 query_builder: &impl QueryBuilder,
774 sql: &mut impl SqlWriter,
775 ) -> String {
776 <Self as QueryStatementBuilder>::build_collect_any(self, query_builder, sql)
777 }
778
779 pub fn build_collect_any_into(
780 &self,
781 query_builder: &impl QueryBuilder,
782 sql: &mut impl SqlWriter,
783 ) {
784 <Self as QueryStatementBuilder>::build_collect_any_into(self, query_builder, sql)
785 }
786}
787
788impl From<InsertStatement> for QueryStatement {
789 fn from(s: InsertStatement) -> Self {
790 Self::Insert(s)
791 }
792}
793
794impl From<InsertStatement> for SubQueryStatement {
795 fn from(s: InsertStatement) -> Self {
796 Self::InsertStatement(s)
797 }
798}
799
800impl QueryStatementWriter for InsertStatement {
801 fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
802 query_builder.prepare_insert_statement(self, sql);
803 }
804}
805
806impl InsertStatement {
807 pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
808 <Self as QueryStatementWriter>::to_string(self, query_builder)
809 }
810
811 pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values) {
812 <Self as QueryStatementWriter>::build(self, query_builder)
813 }
814
815 pub fn build_collect<T: QueryBuilder>(
816 &self,
817 query_builder: T,
818 sql: &mut impl SqlWriter,
819 ) -> String {
820 <Self as QueryStatementWriter>::build_collect(self, query_builder, sql)
821 }
822
823 pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
824 <Self as QueryStatementWriter>::build_collect_into(self, query_builder, sql);
825 }
826}