quaint_forked/ast/insert.rs
1use crate::ast::*;
2use std::borrow::Cow;
3
4/// A builder for an `INSERT` statement.
5#[derive(Clone, Debug, PartialEq)]
6pub struct Insert<'a> {
7 pub(crate) table: Option<Table<'a>>,
8 pub(crate) columns: Vec<Column<'a>>,
9 pub(crate) values: Expression<'a>,
10 pub(crate) on_conflict: Option<OnConflict<'a>>,
11 pub(crate) returning: Option<Vec<Column<'a>>>,
12 pub(crate) comment: Option<Cow<'a, str>>,
13}
14
15/// A builder for an `INSERT` statement for a single row.
16#[derive(Clone, Debug, PartialEq)]
17pub struct SingleRowInsert<'a> {
18 pub(crate) table: Option<Table<'a>>,
19 pub(crate) columns: Vec<Column<'a>>,
20 pub(crate) values: Row<'a>,
21}
22
23/// A builder for an `INSERT` statement for multiple rows.
24#[derive(Clone, Debug, PartialEq)]
25pub struct MultiRowInsert<'a> {
26 pub(crate) table: Option<Table<'a>>,
27 pub(crate) columns: Vec<Column<'a>>,
28 pub(crate) values: Vec<Row<'a>>,
29}
30
31/// `INSERT` conflict resolution strategies.
32#[allow(clippy::large_enum_variant)]
33#[derive(Clone, Debug, PartialEq)]
34pub enum OnConflict<'a> {
35 /// When a row already exists, do nothing. Works with PostgreSQL, MySQL or
36 /// SQLite without schema information.
37 ///
38 /// ```rust
39 /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
40 /// # fn main() -> Result<(), quaint::error::Error> {
41 /// let query: Insert = Insert::single_into("users").into();
42 /// let (sql, _) = Sqlite::build(query.on_conflict(OnConflict::DoNothing))?;
43 /// assert_eq!("INSERT OR IGNORE INTO `users` DEFAULT VALUES", sql);
44 /// # Ok(())
45 /// # }
46 /// ```
47 ///
48 /// With Microsoft SQL server not supporting `IGNORE` in the `INSERT`
49 /// statement, the `INSERT` is converted to a `MERGE` statement. For it to work
50 /// in a correct way, the table should know all unique indices of the actual table.
51 ///
52 /// In this example our `users` table holds one unique index for the `id` column.
53 ///
54 /// ```rust
55 /// # use quaint::{ast::*, visitor::{Visitor, Mssql}};
56 /// # use indoc::indoc;
57 /// # fn main() -> Result<(), quaint::error::Error> {
58 /// let id = Column::from("id").table("users");
59 /// let table = Table::from("users").add_unique_index(id.clone());
60 /// let query: Insert = Insert::single_into(table).value(id, 1).into();
61 /// let (sql, _) = Mssql::build(query.on_conflict(OnConflict::DoNothing))?;
62 ///
63 /// let expected_sql = indoc!(
64 /// "
65 /// MERGE INTO [users]
66 /// USING (SELECT @P1 AS [id]) AS [dual] ([id])
67 /// ON [dual].[id] = [users].[id]
68 /// WHEN NOT MATCHED THEN
69 /// INSERT ([id]) VALUES ([dual].[id]);
70 /// "
71 /// );
72 ///
73 /// assert_eq!(expected_sql.replace('\n', " ").trim(), sql);
74 /// # Ok(())
75 /// # }
76 /// ```
77 ///
78 /// If the `INSERT` statement misses a value for a unique column that does
79 /// not have default value set, the visitor will raise a panic. For compound
80 /// unique indices, the `add_unique_index` takes a vector as a parameter.
81 ///
82 /// If the [column has a default value], it should be added to the `Column`
83 /// definition to allow inserting missing unique values with the `Insert`
84 /// statement. If default is set to [`DefaultValue::Generated`], the value
85 /// is considered to be always unique and not added to the join.
86 ///
87 /// [`DefaultValue::Generated`]: enum.DefaultValue.html#variant.Generated
88 /// [column has a default value]: struct.Column.html#method.default
89 DoNothing,
90 /// ON CONFLICT UPDATE is supported for Sqlite and Postgres
91 Update(Update<'a>, Vec<Column<'a>>),
92}
93
94impl<'a> From<Insert<'a>> for Query<'a> {
95 fn from(insert: Insert<'a>) -> Self {
96 Query::Insert(Box::new(insert))
97 }
98}
99
100impl<'a> From<SingleRowInsert<'a>> for Insert<'a> {
101 fn from(insert: SingleRowInsert<'a>) -> Self {
102 let values = if insert.values.is_empty() {
103 Expression::from(Row::new())
104 } else {
105 Expression::from(insert.values)
106 };
107
108 Insert {
109 table: insert.table,
110 columns: insert.columns,
111 values,
112 on_conflict: None,
113 returning: None,
114 comment: None,
115 }
116 }
117}
118
119impl<'a> From<MultiRowInsert<'a>> for Insert<'a> {
120 fn from(insert: MultiRowInsert<'a>) -> Self {
121 let values = Expression::from(Values::new(insert.values));
122
123 Insert {
124 table: insert.table,
125 columns: insert.columns,
126 values,
127 on_conflict: None,
128 returning: None,
129 comment: None,
130 }
131 }
132}
133
134impl<'a> From<SingleRowInsert<'a>> for Query<'a> {
135 fn from(insert: SingleRowInsert<'a>) -> Query<'a> {
136 Query::from(Insert::from(insert))
137 }
138}
139
140impl<'a> From<MultiRowInsert<'a>> for Query<'a> {
141 fn from(insert: MultiRowInsert<'a>) -> Query<'a> {
142 Query::from(Insert::from(insert))
143 }
144}
145
146impl<'a> Insert<'a> {
147 /// Creates a new single row `INSERT` statement for the given table.
148 ///
149 /// ```rust
150 /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
151 /// # fn main() -> Result<(), quaint::error::Error> {
152 /// let query = Insert::single_into("users");
153 /// let (sql, _) = Sqlite::build(query)?;
154 ///
155 /// assert_eq!("INSERT INTO `users` DEFAULT VALUES", sql);
156 /// # Ok(())
157 /// # }
158 /// ```
159 pub fn single_into<T>(table: T) -> SingleRowInsert<'a>
160 where
161 T: Into<Table<'a>>,
162 {
163 SingleRowInsert {
164 table: Some(table.into()),
165 columns: Vec::new(),
166 values: Row::new(),
167 }
168 }
169
170 pub fn single() -> SingleRowInsert<'a> {
171 SingleRowInsert {
172 table: None,
173 columns: Vec::new(),
174 values: Row::new(),
175 }
176 }
177
178 /// Creates a new multi row `INSERT` statement for the given table.
179 pub fn multi_into<T, K, I>(table: T, columns: I) -> MultiRowInsert<'a>
180 where
181 T: Into<Table<'a>>,
182 K: Into<Column<'a>>,
183 I: IntoIterator<Item = K>,
184 {
185 MultiRowInsert {
186 table: Some(table.into()),
187 columns: columns.into_iter().map(|c| c.into()).collect(),
188 values: Vec::new(),
189 }
190 }
191
192 pub fn multi<K, I>(columns: I) -> MultiRowInsert<'a>
193 where
194 K: Into<Column<'a>>,
195 I: IntoIterator<Item = K>,
196 {
197 MultiRowInsert {
198 table: None,
199 columns: columns.into_iter().map(|c| c.into()).collect(),
200 values: Vec::new(),
201 }
202 }
203
204 pub fn expression_into<T, I, K, E>(table: T, columns: I, expression: E) -> Self
205 where
206 T: Into<Table<'a>>,
207 I: IntoIterator<Item = K>,
208 K: Into<Column<'a>>,
209 E: Into<Expression<'a>>,
210 {
211 Insert {
212 table: Some(table.into()),
213 columns: columns.into_iter().map(|c| c.into()).collect(),
214 values: expression.into(),
215 on_conflict: None,
216 returning: None,
217 comment: None,
218 }
219 }
220
221 /// Sets the conflict resolution strategy.
222 pub fn on_conflict(mut self, on_conflict: OnConflict<'a>) -> Self {
223 self.on_conflict = Some(on_conflict);
224 self
225 }
226
227 /// Adds a comment to the insert.
228 ///
229 /// ```rust
230 /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
231 /// # fn main() -> Result<(), quaint::error::Error> {
232 /// let query = Insert::single_into("users");
233 /// let insert = Insert::from(query).comment("trace_id='5bd66ef5095369c7b0d1f8f4bd33716a', parent_id='c532cb4098ac3dd2'");
234 /// let (sql, _) = Sqlite::build(insert)?;
235 ///
236 /// assert_eq!("INSERT INTO `users` DEFAULT VALUES; /* trace_id='5bd66ef5095369c7b0d1f8f4bd33716a', parent_id='c532cb4098ac3dd2' */", sql);
237 /// # Ok(())
238 /// # }
239 /// ```
240 pub fn comment<C: Into<Cow<'a, str>>>(mut self, comment: C) -> Self {
241 self.comment = Some(comment.into());
242 self
243 }
244
245 /// Sets the returned columns.
246 ///
247 /// ```rust
248 /// # use quaint::{ast::*, visitor::{Visitor, Postgres}};
249 /// # fn main() -> Result<(), quaint::error::Error> {
250 /// let query = Insert::single_into("users");
251 /// let insert = Insert::from(query).returning(vec!["id"]);
252 /// let (sql, _) = Postgres::build(insert)?;
253 ///
254 /// assert_eq!("INSERT INTO \"users\" DEFAULT VALUES RETURNING \"id\"", sql);
255 /// # Ok(())
256 /// # }
257 /// ```
258 #[cfg(any(feature = "postgresql", feature = "mssql", feature = "sqlite"))]
259 pub fn returning<K, I>(mut self, columns: I) -> Self
260 where
261 K: Into<Column<'a>>,
262 I: IntoIterator<Item = K>,
263 {
264 self.returning = Some(columns.into_iter().map(|k| k.into()).collect());
265 self
266 }
267}
268
269impl<'a> SingleRowInsert<'a> {
270 /// Adds a new value to the `INSERT` statement
271 ///
272 /// ```rust
273 /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
274 /// # fn main() -> Result<(), quaint::error::Error> {
275 /// let query = Insert::single_into("users").value("foo", 10);
276 /// let (sql, params) = Sqlite::build(query)?;
277 ///
278 /// assert_eq!("INSERT INTO `users` (`foo`) VALUES (?)", sql);
279 /// assert_eq!(vec![Value::from(10)], params);
280 /// # Ok(())
281 /// # }
282 /// ```
283 pub fn value<K, V>(mut self, key: K, val: V) -> SingleRowInsert<'a>
284 where
285 K: Into<Column<'a>>,
286 V: Into<Expression<'a>>,
287 {
288 self.columns.push(key.into());
289 self.values.push(val.into());
290
291 self
292 }
293
294 /// Convert into a common `Insert` statement.
295 pub fn build(self) -> Insert<'a> {
296 Insert::from(self)
297 }
298}
299
300impl<'a> MultiRowInsert<'a> {
301 /// Adds a new row to be inserted.
302 ///
303 /// ```rust
304 /// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
305 /// # fn main() -> Result<(), quaint::error::Error> {
306 /// let query = Insert::multi_into("users", vec!["foo"])
307 /// .values(vec![1])
308 /// .values(vec![2]);
309 ///
310 /// let (sql, params) = Sqlite::build(query)?;
311 ///
312 /// assert_eq!("INSERT INTO `users` (`foo`) VALUES (?), (?)", sql);
313 ///
314 /// assert_eq!(
315 /// vec![
316 /// Value::from(1),
317 /// Value::from(2),
318 /// ], params);
319 /// # Ok(())
320 /// # }
321 /// ```
322 pub fn values<V>(mut self, values: V) -> Self
323 where
324 V: Into<Row<'a>>,
325 {
326 self.values.push(values.into());
327 self
328 }
329
330 /// Convert into a common `Insert` statement.
331 pub fn build(self) -> Insert<'a> {
332 Insert::from(self)
333 }
334}