keelson_sqlite/statement/
insert.rs1use keelson_core::clause::{
2 ConflictClause, HasReturning, HasTableRef, HasValues, HasWith, Returning, TableRef, Values,
3 With,
4};
5use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
6use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
7
8use crate::Sqlite;
9use crate::extras::{HasOr, HasUpserts, Or, write_spaced};
10
11#[derive(Debug, Clone, Default)]
36pub struct InsertQuery {
37 pub with: With,
39 pub or: Option<Or>,
41 pub table: TableRef,
43 pub values: Values,
46 pub upserts: Vec<ConflictClause>,
49 pub returning: Returning,
51}
52
53impl InsertQuery {
54 pub fn new() -> InsertQuery {
56 InsertQuery::default()
57 }
58
59 pub fn apply(&mut self, mods: impl Mod<InsertQuery>) {
61 mods.apply(self);
62 }
63}
64
65impl Expression for InsertQuery {
66 fn write_sql(&self, w: &mut SqlWriter<'_>) {
67 w.write_if(!self.with.is_empty(), "", &self.with, " ");
68
69 if self.table.is_empty() {
70 w.record_error(Error::Incomplete("the target table of an INSERT"));
73 return;
74 }
75
76 w.push_str("INSERT");
77 if let Some(or) = self.or {
78 w.push_str(" OR ");
79 w.push_str(or.as_str());
80 }
81 w.push_str(" INTO ");
82 w.write_expr(&self.table);
83
84 if self.values.is_empty() {
85 if self.upserts.iter().any(|c| !c.is_empty()) {
90 w.record_error(Error::other(
91 "a DEFAULT VALUES insert cannot carry an ON CONFLICT clause",
92 ));
93 return;
94 }
95 w.push_str(" DEFAULT VALUES");
96 } else {
97 w.push_str(" ");
98 w.write_expr(&self.values);
99 }
100
101 if self.upserts.iter().any(|c| !c.is_empty()) {
105 w.push_str(" ");
106 write_spaced(w, self.upserts.iter().filter(|c| !c.is_empty()));
107 }
108
109 w.write_if(!self.returning.is_empty(), " ", &self.returning, "");
110 }
111}
112
113impl Query for InsertQuery {
114 fn query_type(&self) -> QueryType {
115 QueryType::Insert
116 }
117
118 fn dialect(&self) -> &dyn Dialect {
119 &Sqlite
120 }
121}
122
123impl<H, L, M> QueryExtensions<H, L, M> for InsertQuery {}
124
125impl IntoExpr for InsertQuery {
126 fn into_expr(self) -> Expr {
127 crate::query(self)
128 }
129}
130
131impl IntoExprList for InsertQuery {
132 fn into_expr_list(self) -> Vec<Expr> {
133 vec![self.into_expr()]
134 }
135}
136
137impl HasWith for InsertQuery {
138 fn with_mut(&mut self) -> &mut With {
139 &mut self.with
140 }
141}
142
143impl HasTableRef for InsertQuery {
144 fn table_ref_mut(&mut self) -> &mut TableRef {
145 &mut self.table
146 }
147}
148
149impl HasValues for InsertQuery {
150 fn values_mut(&mut self) -> &mut Values {
151 &mut self.values
152 }
153}
154
155impl HasOr for InsertQuery {
156 fn or_mut(&mut self) -> &mut Option<Or> {
157 &mut self.or
158 }
159}
160
161impl HasUpserts for InsertQuery {
162 fn upserts_mut(&mut self) -> &mut Vec<ConflictClause> {
163 &mut self.upserts
164 }
165}
166
167impl HasReturning for InsertQuery {
168 fn returning_mut(&mut self) -> &mut Returning {
169 &mut self.returning
170 }
171}