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 /// - [`OnConflict::update_values`]: Update column value of existing row with value
458 /// - [`OnConflict::update_exprs`]: Update column value of existing row with expression
459 pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
460 self.on_conflict = Some(on_conflict);
461 self
462 }
463
464 /// RETURNING expressions.
465 ///
466 /// # Examples
467 ///
468 /// ```
469 /// use sea_query::{tests_cfg::*, *};
470 ///
471 /// let query = Query::insert()
472 /// .into_table(Glyph::Table)
473 /// .columns([Glyph::Image])
474 /// .values_panic(["12A".into()])
475 /// .returning(Query::returning().columns([Glyph::Id]))
476 /// .take();
477 ///
478 /// assert_eq!(
479 /// query.to_string(MysqlQueryBuilder),
480 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
481 /// );
482 /// assert_eq!(
483 /// query.to_string(PostgresQueryBuilder),
484 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
485 /// );
486 /// assert_eq!(
487 /// query.to_string(SqliteQueryBuilder),
488 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
489 /// );
490 /// ```
491 pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
492 self.returning = Some(returning);
493 self
494 }
495
496 /// RETURNING expressions for a column.
497 ///
498 /// # Examples
499 ///
500 /// ```
501 /// use sea_query::{tests_cfg::*, *};
502 ///
503 /// let query = Query::insert()
504 /// .into_table(Glyph::Table)
505 /// .columns([Glyph::Image])
506 /// .values_panic(["12A".into()])
507 /// .returning_col(Glyph::Id)
508 /// .take();
509 ///
510 /// assert_eq!(
511 /// query.to_string(MysqlQueryBuilder),
512 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
513 /// );
514 /// assert_eq!(
515 /// query.to_string(PostgresQueryBuilder),
516 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
517 /// );
518 /// assert_eq!(
519 /// query.to_string(SqliteQueryBuilder),
520 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
521 /// );
522 /// ```
523 pub fn returning_col<C>(&mut self, col: C) -> &mut Self
524 where
525 C: IntoColumnRef,
526 {
527 self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
528 }
529
530 /// RETURNING expressions all columns.
531 ///
532 /// # Examples
533 ///
534 /// ```
535 /// use sea_query::{tests_cfg::*, *};
536 ///
537 /// let query = Query::insert()
538 /// .into_table(Glyph::Table)
539 /// .columns([Glyph::Image])
540 /// .values_panic(["12A".into()])
541 /// .returning_all()
542 /// .take();
543 ///
544 /// assert_eq!(
545 /// query.to_string(MysqlQueryBuilder),
546 /// "INSERT INTO `glyph` (`image`) VALUES ('12A')"
547 /// );
548 /// assert_eq!(
549 /// query.to_string(PostgresQueryBuilder),
550 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
551 /// );
552 /// assert_eq!(
553 /// query.to_string(SqliteQueryBuilder),
554 /// r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
555 /// );
556 /// ```
557 pub fn returning_all(&mut self) -> &mut Self {
558 self.returning(ReturningClause::All)
559 }
560
561 /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
562 ///
563 /// # Examples
564 ///
565 /// ```
566 /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
567 ///
568 /// let select = SelectStatement::new()
569 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
570 /// .from(Glyph::Table)
571 /// .take();
572 /// let cte = CommonTableExpression::new()
573 /// .query(select)
574 /// .column(Glyph::Id)
575 /// .column(Glyph::Image)
576 /// .column(Glyph::Aspect)
577 /// .table_name("cte")
578 /// .to_owned();
579 /// let with_clause = WithClause::new().cte(cte).to_owned();
580 /// let select = SelectStatement::new()
581 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
582 /// .from("cte")
583 /// .take();
584 /// let mut insert = Query::insert();
585 /// insert
586 /// .into_table(Glyph::Table)
587 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
588 /// .select_from(select)
589 /// .unwrap();
590 /// let query = insert.with(with_clause);
591 ///
592 /// assert_eq!(
593 /// query.to_string(MysqlQueryBuilder),
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(PostgresQueryBuilder),
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 /// assert_eq!(
601 /// query.to_string(SqliteQueryBuilder),
602 /// 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""#
603 /// );
604 /// ```
605 pub fn with(self, clause: WithClause) -> WithQuery {
606 clause.query(self)
607 }
608
609 /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with.
610 ///
611 /// # Examples
612 ///
613 /// ```
614 /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
615 ///
616 /// let select = SelectStatement::new()
617 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
618 /// .from(Glyph::Table)
619 /// .take();
620 /// let cte = CommonTableExpression::new()
621 /// .query(select)
622 /// .column(Glyph::Id)
623 /// .column(Glyph::Image)
624 /// .column(Glyph::Aspect)
625 /// .table_name("cte")
626 /// .to_owned();
627 /// let with_clause = WithClause::new().cte(cte).to_owned();
628 /// let select = SelectStatement::new()
629 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
630 /// .from("cte")
631 /// .take();
632 /// let mut query = Query::insert();
633 /// query
634 /// .with_cte(with_clause)
635 /// .into_table(Glyph::Table)
636 /// .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
637 /// .select_from(select)
638 /// .unwrap();
639 ///
640 /// assert_eq!(
641 /// query.to_string(MysqlQueryBuilder),
642 /// 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`"#
643 /// );
644 /// assert_eq!(
645 /// query.to_string(PostgresQueryBuilder),
646 /// 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""#
647 /// );
648 /// assert_eq!(
649 /// query.to_string(SqliteQueryBuilder),
650 /// 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""#
651 /// );
652 /// ```
653 pub fn with_cte<C: Into<WithClause>>(&mut self, clause: C) -> &mut Self {
654 self.with = Some(clause.into());
655 self
656 }
657
658 /// Insert with default values if columns and values are not supplied.
659 ///
660 /// # Examples
661 ///
662 /// ```
663 /// use sea_query::{tests_cfg::*, *};
664 ///
665 /// // Insert default
666 /// let query = Query::insert()
667 /// .into_table(Glyph::Table)
668 /// .or_default_values()
669 /// .take();
670 ///
671 /// assert_eq!(
672 /// query.to_string(MysqlQueryBuilder),
673 /// r#"INSERT INTO `glyph` VALUES ()"#
674 /// );
675 /// assert_eq!(
676 /// query.to_string(PostgresQueryBuilder),
677 /// r#"INSERT INTO "glyph" VALUES (DEFAULT)"#
678 /// );
679 /// assert_eq!(
680 /// query.to_string(SqliteQueryBuilder),
681 /// r#"INSERT INTO "glyph" DEFAULT VALUES"#
682 /// );
683 ///
684 /// // Ordinary insert as columns and values are supplied
685 /// let query = Query::insert()
686 /// .into_table(Glyph::Table)
687 /// .or_default_values()
688 /// .columns([Glyph::Image])
689 /// .values_panic(["ABC".into()])
690 /// .take();
691 ///
692 /// assert_eq!(
693 /// query.to_string(MysqlQueryBuilder),
694 /// r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
695 /// );
696 /// assert_eq!(
697 /// query.to_string(PostgresQueryBuilder),
698 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
699 /// );
700 /// assert_eq!(
701 /// query.to_string(SqliteQueryBuilder),
702 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
703 /// );
704 /// ```
705 pub fn or_default_values(&mut self) -> &mut Self {
706 self.default_values = Some(1);
707 self
708 }
709
710 /// Insert multiple rows with default values if columns and values are not supplied.
711 ///
712 /// # Examples
713 ///
714 /// ```
715 /// use sea_query::{tests_cfg::*, *};
716 ///
717 /// // Insert default
718 /// let query = Query::insert()
719 /// .into_table(Glyph::Table)
720 /// .or_default_values_many(3)
721 /// .take();
722 ///
723 /// assert_eq!(
724 /// query.to_string(MysqlQueryBuilder),
725 /// r#"INSERT INTO `glyph` VALUES (), (), ()"#
726 /// );
727 /// assert_eq!(
728 /// query.to_string(PostgresQueryBuilder),
729 /// r#"INSERT INTO "glyph" VALUES (DEFAULT), (DEFAULT), (DEFAULT)"#
730 /// );
731 /// assert_eq!(
732 /// query.to_string(SqliteQueryBuilder),
733 /// r#"INSERT INTO "glyph" DEFAULT VALUES"#
734 /// );
735 ///
736 /// // Ordinary insert as columns and values are supplied
737 /// let query = Query::insert()
738 /// .into_table(Glyph::Table)
739 /// .or_default_values_many(3)
740 /// .columns([Glyph::Image])
741 /// .values_panic(["ABC".into()])
742 /// .take();
743 ///
744 /// assert_eq!(
745 /// query.to_string(MysqlQueryBuilder),
746 /// r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
747 /// );
748 /// assert_eq!(
749 /// query.to_string(PostgresQueryBuilder),
750 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
751 /// );
752 /// assert_eq!(
753 /// query.to_string(SqliteQueryBuilder),
754 /// r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
755 /// );
756 /// ```
757 pub fn or_default_values_many(&mut self, num_rows: u32) -> &mut Self {
758 self.default_values = Some(num_rows);
759 self
760 }
761}
762
763#[inherent]
764impl QueryStatementBuilder for InsertStatement {
765 pub fn build_collect_any_into(
766 &self,
767 query_builder: &impl QueryBuilder,
768 sql: &mut impl SqlWriter,
769 ) {
770 query_builder.prepare_insert_statement(self, sql);
771 }
772
773 pub fn build_any(&self, query_builder: &impl QueryBuilder) -> (String, Values);
774 pub fn build_collect_any(
775 &self,
776 query_builder: &impl QueryBuilder,
777 sql: &mut impl SqlWriter,
778 ) -> String;
779}
780
781impl From<InsertStatement> for QueryStatement {
782 fn from(s: InsertStatement) -> Self {
783 Self::Insert(s)
784 }
785}
786
787impl From<InsertStatement> for SubQueryStatement {
788 fn from(s: InsertStatement) -> Self {
789 Self::InsertStatement(s)
790 }
791}
792
793#[inherent]
794impl QueryStatementWriter for InsertStatement {
795 pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
796 query_builder.prepare_insert_statement(self, sql);
797 }
798
799 pub fn build_collect<T: QueryBuilder>(
800 &self,
801 query_builder: T,
802 sql: &mut impl SqlWriter,
803 ) -> String;
804 pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values);
805 pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String;
806}