subgraph/data_sources/sql/services/update_many/
mod.rs1use log::{debug, error, trace};
2use sqlx::Row;
3
4use crate::{
5 configuration::subgraph::entities::ServiceEntityConfig,
6 data_sources::sql::{PoolEnum, SqlQuery},
7 sql_value::SqlValue,
8 utils::clean_string::{clean_string, CleanOptions},
9};
10
11use super::{ResponseRow, Services};
12
13impl Services {
14 pub async fn update_many(
15 entity: &ServiceEntityConfig,
16 pool_enum: &PoolEnum,
17 sql_query: &SqlQuery,
18 ) -> Result<Vec<Option<ResponseRow>>, async_graphql::Error> {
19 debug!("Update Many SQL Data Source");
20
21 let clean_options = CleanOptions {
22 newline: Some(false),
23 quotes: Some(true),
24 };
25 match pool_enum {
26 PoolEnum::MySql(pool) => {
27 let identifier_query = match &sql_query.identifier_query {
28 Some(query) => query,
29 None => {
30 error!(
31 "Identifier query not found for update_many on {}",
32 entity.name
33 );
34 return Err(async_graphql::Error::new(format!(
35 "Identifier query not found for update_many on {}",
36 entity.name
37 )));
38 }
39 };
40
41 let mut identifier_query = sqlx::query(&identifier_query);
42
43 let mut update_query = sqlx::query(&sql_query.query);
44 for value in &sql_query.values {
45 match value {
46 SqlValue::String(v) | SqlValue::ObjectID(v) => {
47 let v = clean_string(v, Some(clean_options.clone()));
48 update_query = update_query.bind(v.clone());
49 }
50 SqlValue::Int(v) => {
51 update_query = update_query.bind(v);
52 }
53 SqlValue::Bool(v) => {
54 update_query = update_query.bind(v);
55 }
56 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
57 for v in values {
58 let v = clean_string(v, Some(clean_options.clone()));
59 update_query = update_query.bind(v.clone());
60 }
61 }
62 SqlValue::IntList(values) => {
63 for int in values {
64 update_query = update_query.bind(int);
65 }
66 }
67 SqlValue::BoolList(values) => {
68 for bool in values {
69 update_query = update_query.bind(bool);
70 }
71 }
72 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
73 SqlValue::UUIDList(uuids) => {
74 for uuid in uuids {
75 update_query = update_query.bind(uuid);
76 }
77 }
78 SqlValue::DateTime(date_time) => {
79 update_query = update_query.bind(date_time);
80 }
81 SqlValue::DateTimeList(date_times) => {
82 for date_time in date_times {
83 update_query = update_query.bind(date_time);
84 }
85 }
86 }
87 }
88 for value in &sql_query.where_values {
89 match value {
90 SqlValue::String(v) | SqlValue::ObjectID(v) => {
91 let v = clean_string(v, Some(clean_options.clone()));
92 update_query = update_query.bind(v.clone());
93 identifier_query = identifier_query.bind(v);
94 }
95 SqlValue::Int(v) => {
96 update_query = update_query.bind(v);
97 identifier_query = identifier_query.bind(v);
98 }
99 SqlValue::Bool(v) => {
100 update_query = update_query.bind(v);
101 identifier_query = identifier_query.bind(v);
102 }
103 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
104 for v in values {
105 let v = clean_string(v, Some(clean_options.clone()));
106 update_query = update_query.bind(v.clone());
107 identifier_query = identifier_query.bind(v);
108 }
109 }
110 SqlValue::IntList(values) => {
111 for int in values {
112 update_query = update_query.bind(int);
113 identifier_query = identifier_query.bind(int);
114 }
115 }
116 SqlValue::BoolList(values) => {
117 for bool in values {
118 update_query = update_query.bind(bool);
119 identifier_query = identifier_query.bind(bool);
120 }
121 }
122 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
123 SqlValue::UUIDList(uuids) => {
124 for uuid in uuids {
125 update_query = update_query.bind(uuid);
126 identifier_query = identifier_query.bind(uuid);
127 }
128 }
129 SqlValue::DateTime(date_time) => {
130 update_query = update_query.bind(date_time);
131 identifier_query = identifier_query.bind(date_time);
132 }
133 SqlValue::DateTimeList(date_times) => {
134 for date_time in date_times {
135 update_query = update_query.bind(date_time);
136 identifier_query = identifier_query.bind(date_time);
137 }
138 }
139 }
140 }
141
142 let identifier_results = identifier_query.fetch_all(pool).await.map_err(|e| {
143 error!("Error executing identifier query: {}", e);
144 e
145 })?;
146
147 update_query.execute(pool).await.map_err(|e| {
148 error!("Error executing update many query: {}", e);
149 e
150 })?;
151
152 let mut ids = Vec::new();
153 for row in identifier_results {
154 trace!("Row: {:?}", row);
155 let identifier: i64 = row.try_get("id").map_err(|e| {
156 error!("Error getting primary key from row: {}", e);
157 e
158 })?;
159 ids.push(identifier);
160 }
161
162 trace!("Identifiers: {:?}", ids);
163
164 if ids.is_empty() {
165 return Ok(Vec::new());
166 }
167
168 let query = format!(
169 "SELECT * FROM {} WHERE id IN ({});",
170 sql_query.table,
171 ids.iter()
172 .map(|id| id.to_string())
173 .collect::<Vec<String>>()
174 .join(",")
175 );
176 trace!("Query: {}", query);
177
178 let response_query = sqlx::query(&query);
179
180 let rows = response_query.fetch_all(pool).await.map_err(|e| {
181 error!("Error finding data: {}", e);
182 e
183 })?;
184
185 let mut response_rows = Vec::new();
186
187 for row in rows {
188 response_rows.push(Some(ResponseRow::MySql(row)));
189 }
190
191 Ok(response_rows)
192 }
193 PoolEnum::Postgres(pool) => {
194 let mut update_query = sqlx::query(&sql_query.query);
195 debug!("PG VALUES: {:?}", sql_query);
196 for value in &sql_query.values {
197 match value {
198 SqlValue::String(v) | SqlValue::ObjectID(v) => {
199 let v = clean_string(v, Some(clean_options.clone()));
200 update_query = update_query.bind(v);
201 }
202 SqlValue::Int(v) => {
203 update_query = update_query.bind(v);
204 }
205 SqlValue::Bool(v) => {
206 update_query = update_query.bind(v);
207 }
208 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
209 for v in values {
210 let v = clean_string(v, Some(clean_options.clone()));
211 update_query = update_query.bind(v)
212 }
213 }
214 SqlValue::IntList(values) => {
215 for int in values {
216 update_query = update_query.bind(int)
217 }
218 }
219 SqlValue::BoolList(values) => {
220 for bool in values {
221 update_query = update_query.bind(bool)
222 }
223 }
224 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
225 SqlValue::UUIDList(uuids) => {
226 for uuid in uuids {
227 update_query = update_query.bind(uuid)
228 }
229 }
230 SqlValue::DateTime(date_time) => {
231 update_query = update_query.bind(date_time)
232 }
233 SqlValue::DateTimeList(date_times) => {
234 for date_time in date_times {
235 update_query = update_query.bind(date_time)
236 }
237 }
238 }
239 }
240 for value in &sql_query.where_values {
241 match value {
242 SqlValue::String(v) | SqlValue::ObjectID(v) => {
243 let v = clean_string(v, Some(clean_options.clone()));
244 update_query = update_query.bind(v);
245 }
246 SqlValue::Int(v) => {
247 update_query = update_query.bind(v);
248 }
249 SqlValue::Bool(v) => {
250 update_query = update_query.bind(v);
251 }
252 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
253 for v in values {
254 let v = clean_string(v, Some(clean_options.clone()));
255 update_query = update_query.bind(v)
256 }
257 }
258 SqlValue::IntList(values) => {
259 for int in values {
260 update_query = update_query.bind(int)
261 }
262 }
263 SqlValue::BoolList(values) => {
264 for bool in values {
265 update_query = update_query.bind(bool)
266 }
267 }
268 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
269 SqlValue::UUIDList(uuids) => {
270 for uuid in uuids {
271 update_query = update_query.bind(uuid)
272 }
273 }
274 SqlValue::DateTime(date_time) => {
275 update_query = update_query.bind(date_time)
276 }
277 SqlValue::DateTimeList(date_times) => {
278 for date_time in date_times {
279 update_query = update_query.bind(date_time)
280 }
281 }
282 }
283 }
284
285 let rows = update_query.fetch_all(pool).await.map_err(|e| {
286 error!("Error: {:?}", e);
287 e
288 })?;
289
290 let mut response_rows = Vec::new();
291 for row in rows {
292 response_rows.push(Some(ResponseRow::Postgres(row)));
293 }
294 Ok(response_rows)
295 }
296 PoolEnum::SqLite(pool) => {
297 let identifier_query = match &sql_query.identifier_query {
298 Some(identifier_query) => identifier_query,
299 None => {
300 return Err(async_graphql::Error::new(
301 "No identifier query provided for SQLite",
302 ))
303 }
304 };
305 let mut identifier_query = sqlx::query(identifier_query);
306 let mut update_query = sqlx::query(&sql_query.query);
307
308 for value in &sql_query.values {
310 match value {
311 SqlValue::String(v) | SqlValue::ObjectID(v) => {
312 let v = clean_string(v, Some(clean_options.clone()));
313 update_query = update_query.bind(v.clone());
314 }
315 SqlValue::Int(v) => {
316 update_query = update_query.bind(v.clone());
317 }
318 SqlValue::Bool(v) => {
319 update_query = update_query.bind(v);
320 }
321 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
322 for v in values {
323 let v = clean_string(v, Some(clean_options.clone()));
324 update_query = update_query.bind(v.clone());
325 }
326 }
327 SqlValue::IntList(values) => {
328 for int in values {
329 update_query = update_query.bind(int);
330 }
331 }
332 SqlValue::BoolList(values) => {
333 for bool in values {
334 update_query = update_query.bind(bool);
335 }
336 }
337 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
338 SqlValue::UUIDList(uuids) => {
339 for uuid in uuids {
340 update_query = update_query.bind(uuid);
341 }
342 }
343 SqlValue::DateTime(date_time) => {
344 update_query = update_query.bind(date_time);
345 }
346 SqlValue::DateTimeList(date_times) => {
347 for date_time in date_times {
348 update_query = update_query.bind(date_time);
349 }
350 }
351 }
352 }
353
354 for value in &sql_query.where_values {
356 match value {
357 SqlValue::String(v) | SqlValue::ObjectID(v) => {
358 let v = clean_string(v, Some(clean_options.clone()));
359 update_query = update_query.bind(v.clone());
360 identifier_query = identifier_query.bind(v);
361 }
362 SqlValue::Int(v) => {
363 update_query = update_query.bind(v);
364 identifier_query = identifier_query.bind(v);
365 }
366 SqlValue::Bool(v) => {
367 update_query = update_query.bind(v);
368 identifier_query = identifier_query.bind(v);
369 }
370 SqlValue::StringList(values) | SqlValue::ObjectIDList(values) => {
371 for v in values {
372 update_query = update_query.bind(v);
373 identifier_query = identifier_query.bind(v);
374 }
375 }
376 SqlValue::IntList(values) => {
377 for int in values {
378 update_query = update_query.bind(int);
379 identifier_query = identifier_query.bind(int);
380 }
381 }
382 SqlValue::BoolList(values) => {
383 for bool in values {
384 update_query = update_query.bind(bool);
385 identifier_query = identifier_query.bind(bool);
386 }
387 }
388 SqlValue::UUID(uuid) => update_query = update_query.bind(uuid),
389 SqlValue::UUIDList(uuids) => {
390 for uuid in uuids {
391 update_query = update_query.bind(uuid);
392 identifier_query = identifier_query.bind(uuid);
393 }
394 }
395 SqlValue::DateTime(date_time) => {
396 update_query = update_query.bind(date_time);
397 identifier_query = identifier_query.bind(date_time);
398 }
399 SqlValue::DateTimeList(date_times) => {
400 for date_time in date_times {
401 update_query = update_query.bind(date_time);
402 identifier_query = identifier_query.bind(date_time);
403 }
404 }
405 }
406 }
407
408 let identifer_results = identifier_query.fetch_all(pool).await.map_err(|e| {
410 error!("Error: {:?}", e);
411 e
412 })?;
413
414 update_query.execute(pool).await.map_err(|e| {
415 error!("Error: {:?}", e);
416 e
417 })?;
418
419 let mut ids = vec![];
420 for row in identifer_results {
421 let id: i64 = row.try_get("id")?;
422 ids.push(id);
423 }
424
425 if ids.is_empty() {
426 return Ok(vec![]);
427 }
428
429 let query = format!(
430 "SELECT * FROM {} WHERE id IN ({})",
431 sql_query.table,
432 ids.iter()
433 .map(|id| id.to_string())
434 .collect::<Vec<String>>()
435 .join(",")
436 );
437
438 let response_query = sqlx::query(&query);
439
440 let rows = response_query.fetch_all(pool).await.map_err(|e| {
441 error!("Error finding data: {}", e);
442 e
443 })?;
444
445 let mut response_rows = Vec::new();
446
447 for row in rows {
448 response_rows.push(Some(ResponseRow::SqLite(row)));
449 }
450
451 Ok(response_rows)
452 }
453 }
454 }
455}