1#[derive(Debug)]
4pub struct GetAttributeParams<T1: crate::StringSql, T2: crate::StringSql> {
5 pub organization_id: i32,
6 pub id: Option<i32>,
7 pub external_id: Option<T1>,
8 pub slug: Option<T2>,
9}
10#[derive(Debug)]
11pub struct GetAttributeIdParams<T1: crate::StringSql, T2: crate::StringSql> {
12 pub organization_id: i32,
13 pub id: Option<i32>,
14 pub external_id: Option<T1>,
15 pub slug: Option<T2>,
16}
17#[derive(Debug)]
18pub struct InsertAttributeParams<
19 T1: crate::JsonSql,
20 T2: crate::JsonSql,
21 T3: crate::StringSql,
22 T4: crate::StringSql,
23> {
24 pub title: T1,
25 pub description: T2,
26 pub type_id: i32,
27 pub slug: T3,
28 pub external_id: Option<T4>,
29 pub organization_id: i32,
30 pub created_by: i32,
31}
32#[derive(Debug)]
33pub struct UpdateAttributeParams<
34 T1: crate::JsonSql,
35 T2: crate::JsonSql,
36 T3: crate::StringSql,
37 T4: crate::StringSql,
38> {
39 pub type_id: Option<i32>,
40 pub title: Option<T1>,
41 pub description: Option<T2>,
42 pub slug: Option<T3>,
43 pub external_id: Option<T4>,
44 pub id: i32,
45}
46#[derive(Clone, Copy, Debug)]
47pub struct DeleteAttributeParams {
48 pub organization_id: i32,
49 pub id: i32,
50}
51#[derive(Debug)]
52pub struct AssociateStyleAttributesParams<T1: crate::ArraySql<Item = i32>> {
53 pub style_id: i32,
54 pub attribute_ids: T1,
55}
56#[derive(Debug, Clone, PartialEq)]
57pub struct AttributeRow {
58 pub id: i32,
59 pub organization_id: i32,
60 pub type_id: i32,
61 pub title: serde_json::Value,
62 pub description: serde_json::Value,
63 pub slug: String,
64 pub external_id: Option<String>,
65 pub created_by: Option<i32>,
66 pub created_at: chrono::DateTime<chrono::FixedOffset>,
67 pub updated_at: chrono::DateTime<chrono::FixedOffset>,
68 pub r#type: serde_json::Value,
69}
70pub struct AttributeRowBorrowed<'a> {
71 pub id: i32,
72 pub organization_id: i32,
73 pub type_id: i32,
74 pub title: postgres_types::Json<&'a serde_json::value::RawValue>,
75 pub description: postgres_types::Json<&'a serde_json::value::RawValue>,
76 pub slug: &'a str,
77 pub external_id: Option<&'a str>,
78 pub created_by: Option<i32>,
79 pub created_at: chrono::DateTime<chrono::FixedOffset>,
80 pub updated_at: chrono::DateTime<chrono::FixedOffset>,
81 pub r#type: postgres_types::Json<&'a serde_json::value::RawValue>,
82}
83impl<'a> From<AttributeRowBorrowed<'a>> for AttributeRow {
84 fn from(
85 AttributeRowBorrowed {
86 id,
87 organization_id,
88 type_id,
89 title,
90 description,
91 slug,
92 external_id,
93 created_by,
94 created_at,
95 updated_at,
96 r#type,
97 }: AttributeRowBorrowed<'a>,
98 ) -> Self {
99 Self {
100 id,
101 organization_id,
102 type_id,
103 title: serde_json::from_str(title.0.get()).unwrap(),
104 description: serde_json::from_str(description.0.get()).unwrap(),
105 slug: slug.into(),
106 external_id: external_id.map(|v| v.into()),
107 created_by,
108 created_at,
109 updated_at,
110 r#type: serde_json::from_str(r#type.0.get()).unwrap(),
111 }
112 }
113}
114use crate::client::async_::GenericClient;
115use futures::{self, StreamExt, TryStreamExt};
116pub struct AttributeRowQuery<'a, C: GenericClient, T, const N: usize> {
117 client: &'a C,
118 params: [&'a (dyn postgres_types::ToSql + Sync); N],
119 stmt: &'a mut crate::client::async_::Stmt,
120 extractor: fn(&tokio_postgres::Row) -> AttributeRowBorrowed,
121 mapper: fn(AttributeRowBorrowed) -> T,
122}
123impl<'a, C, T: 'a, const N: usize> AttributeRowQuery<'a, C, T, N>
124where
125 C: GenericClient,
126{
127 pub fn map<R>(self, mapper: fn(AttributeRowBorrowed) -> R) -> AttributeRowQuery<'a, C, R, N> {
128 AttributeRowQuery {
129 client: self.client,
130 params: self.params,
131 stmt: self.stmt,
132 extractor: self.extractor,
133 mapper,
134 }
135 }
136 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
137 let stmt = self.stmt.prepare(self.client).await?;
138 let row = self.client.query_one(stmt, &self.params).await?;
139 Ok((self.mapper)((self.extractor)(&row)))
140 }
141 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
142 self.iter().await?.try_collect().await
143 }
144 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
145 let stmt = self.stmt.prepare(self.client).await?;
146 Ok(self
147 .client
148 .query_opt(stmt, &self.params)
149 .await?
150 .map(|row| (self.mapper)((self.extractor)(&row))))
151 }
152 pub async fn iter(
153 self,
154 ) -> Result<
155 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
156 tokio_postgres::Error,
157 > {
158 let stmt = self.stmt.prepare(self.client).await?;
159 let it = self
160 .client
161 .query_raw(stmt, crate::slice_iter(&self.params))
162 .await?
163 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
164 .into_stream();
165 Ok(it)
166 }
167}
168pub struct I32Query<'a, C: GenericClient, T, const N: usize> {
169 client: &'a C,
170 params: [&'a (dyn postgres_types::ToSql + Sync); N],
171 stmt: &'a mut crate::client::async_::Stmt,
172 extractor: fn(&tokio_postgres::Row) -> i32,
173 mapper: fn(i32) -> T,
174}
175impl<'a, C, T: 'a, const N: usize> I32Query<'a, C, T, N>
176where
177 C: GenericClient,
178{
179 pub fn map<R>(self, mapper: fn(i32) -> R) -> I32Query<'a, C, R, N> {
180 I32Query {
181 client: self.client,
182 params: self.params,
183 stmt: self.stmt,
184 extractor: self.extractor,
185 mapper,
186 }
187 }
188 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
189 let stmt = self.stmt.prepare(self.client).await?;
190 let row = self.client.query_one(stmt, &self.params).await?;
191 Ok((self.mapper)((self.extractor)(&row)))
192 }
193 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
194 self.iter().await?.try_collect().await
195 }
196 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
197 let stmt = self.stmt.prepare(self.client).await?;
198 Ok(self
199 .client
200 .query_opt(stmt, &self.params)
201 .await?
202 .map(|row| (self.mapper)((self.extractor)(&row))))
203 }
204 pub async fn iter(
205 self,
206 ) -> Result<
207 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
208 tokio_postgres::Error,
209 > {
210 let stmt = self.stmt.prepare(self.client).await?;
211 let it = self
212 .client
213 .query_raw(stmt, crate::slice_iter(&self.params))
214 .await?
215 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
216 .into_stream();
217 Ok(it)
218 }
219}
220pub fn list_attributes() -> ListAttributesStmt {
221 ListAttributesStmt(crate::client::async_::Stmt::new(
222 "SELECT
223 attribute.*,
224 to_jsonb(attributetype.*) AS \"type\"
225FROM
226 attribute
227INNER JOIN attributetype
228 ON attributetype.id = attribute.type_id
229WHERE
230 attribute.organization_id = $1
231ORDER BY
232 attribute.updated_at DESC",
233 ))
234}
235pub struct ListAttributesStmt(crate::client::async_::Stmt);
236impl ListAttributesStmt {
237 pub fn bind<'a, C: GenericClient>(
238 &'a mut self,
239 client: &'a C,
240 organization_id: &'a i32,
241 ) -> AttributeRowQuery<'a, C, AttributeRow, 1> {
242 AttributeRowQuery {
243 client,
244 params: [organization_id],
245 stmt: &mut self.0,
246 extractor: |row| AttributeRowBorrowed {
247 id: row.get(0),
248 organization_id: row.get(1),
249 type_id: row.get(2),
250 title: row.get(3),
251 description: row.get(4),
252 slug: row.get(5),
253 external_id: row.get(6),
254 created_by: row.get(7),
255 created_at: row.get(8),
256 updated_at: row.get(9),
257 r#type: row.get(10),
258 },
259 mapper: |it| <AttributeRow>::from(it),
260 }
261 }
262}
263pub fn get_attribute() -> GetAttributeStmt {
264 GetAttributeStmt(crate::client::async_::Stmt::new(
265 "SELECT
266 attribute.*,
267 to_jsonb(attributetype.*) AS \"type\"
268FROM
269 attribute
270INNER JOIN attributetype
271 ON attributetype.id = attribute.type_id
272WHERE
273 attribute.organization_id = $1
274 AND ((attribute.id = coalesce($2, -1))
275 OR (
276 attribute.external_id = coalesce($3, '___NON_EXISTING___')
277 )
278 OR (attribute.slug = coalesce($4, '___NON_EXISTING___')))",
279 ))
280}
281pub struct GetAttributeStmt(crate::client::async_::Stmt);
282impl GetAttributeStmt {
283 pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>(
284 &'a mut self,
285 client: &'a C,
286 organization_id: &'a i32,
287 id: &'a Option<i32>,
288 external_id: &'a Option<T1>,
289 slug: &'a Option<T2>,
290 ) -> AttributeRowQuery<'a, C, AttributeRow, 4> {
291 AttributeRowQuery {
292 client,
293 params: [organization_id, id, external_id, slug],
294 stmt: &mut self.0,
295 extractor: |row| AttributeRowBorrowed {
296 id: row.get(0),
297 organization_id: row.get(1),
298 type_id: row.get(2),
299 title: row.get(3),
300 description: row.get(4),
301 slug: row.get(5),
302 external_id: row.get(6),
303 created_by: row.get(7),
304 created_at: row.get(8),
305 updated_at: row.get(9),
306 r#type: row.get(10),
307 },
308 mapper: |it| <AttributeRow>::from(it),
309 }
310 }
311}
312impl<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>
313 crate::client::async_::Params<
314 'a,
315 GetAttributeParams<T1, T2>,
316 AttributeRowQuery<'a, C, AttributeRow, 4>,
317 C,
318 > for GetAttributeStmt
319{
320 fn params(
321 &'a mut self,
322 client: &'a C,
323 params: &'a GetAttributeParams<T1, T2>,
324 ) -> AttributeRowQuery<'a, C, AttributeRow, 4> {
325 self.bind(
326 client,
327 ¶ms.organization_id,
328 ¶ms.id,
329 ¶ms.external_id,
330 ¶ms.slug,
331 )
332 }
333}
334pub fn get_attribute_id() -> GetAttributeIdStmt {
335 GetAttributeIdStmt(crate::client::async_::Stmt::new(
336 "SELECT attribute.id
337FROM
338 attribute
339WHERE
340 attribute.organization_id = $1
341 AND ((attribute.id = coalesce($2, -1))
342 OR (
343 attribute.external_id = coalesce($3, '___NON_EXISTING___')
344 )
345 OR (attribute.slug = coalesce($4, '___NON_EXISTING___')))",
346 ))
347}
348pub struct GetAttributeIdStmt(crate::client::async_::Stmt);
349impl GetAttributeIdStmt {
350 pub fn bind<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>(
351 &'a mut self,
352 client: &'a C,
353 organization_id: &'a i32,
354 id: &'a Option<i32>,
355 external_id: &'a Option<T1>,
356 slug: &'a Option<T2>,
357 ) -> I32Query<'a, C, i32, 4> {
358 I32Query {
359 client,
360 params: [organization_id, id, external_id, slug],
361 stmt: &mut self.0,
362 extractor: |row| row.get(0),
363 mapper: |it| it,
364 }
365 }
366}
367impl<'a, C: GenericClient, T1: crate::StringSql, T2: crate::StringSql>
368 crate::client::async_::Params<'a, GetAttributeIdParams<T1, T2>, I32Query<'a, C, i32, 4>, C>
369 for GetAttributeIdStmt
370{
371 fn params(
372 &'a mut self,
373 client: &'a C,
374 params: &'a GetAttributeIdParams<T1, T2>,
375 ) -> I32Query<'a, C, i32, 4> {
376 self.bind(
377 client,
378 ¶ms.organization_id,
379 ¶ms.id,
380 ¶ms.external_id,
381 ¶ms.slug,
382 )
383 }
384}
385pub fn insert_attribute() -> InsertAttributeStmt {
386 InsertAttributeStmt(crate::client::async_::Stmt::new(
387 "INSERT INTO attribute (
388 title,
389 description,
390 type_id,
391 slug,
392 external_id,
393 organization_id,
394 created_by)
395VALUES (
396 $1,
397 $2,
398 $3,
399 $4,
400 $5,
401 $6,
402 $7)
403RETURNING
404id",
405 ))
406}
407pub struct InsertAttributeStmt(crate::client::async_::Stmt);
408impl InsertAttributeStmt {
409 pub fn bind<
410 'a,
411 C: GenericClient,
412 T1: crate::JsonSql,
413 T2: crate::JsonSql,
414 T3: crate::StringSql,
415 T4: crate::StringSql,
416 >(
417 &'a mut self,
418 client: &'a C,
419 title: &'a T1,
420 description: &'a T2,
421 type_id: &'a i32,
422 slug: &'a T3,
423 external_id: &'a Option<T4>,
424 organization_id: &'a i32,
425 created_by: &'a i32,
426 ) -> I32Query<'a, C, i32, 7> {
427 I32Query {
428 client,
429 params: [
430 title,
431 description,
432 type_id,
433 slug,
434 external_id,
435 organization_id,
436 created_by,
437 ],
438 stmt: &mut self.0,
439 extractor: |row| row.get(0),
440 mapper: |it| it,
441 }
442 }
443}
444impl<
445 'a,
446 C: GenericClient,
447 T1: crate::JsonSql,
448 T2: crate::JsonSql,
449 T3: crate::StringSql,
450 T4: crate::StringSql,
451 >
452 crate::client::async_::Params<
453 'a,
454 InsertAttributeParams<T1, T2, T3, T4>,
455 I32Query<'a, C, i32, 7>,
456 C,
457 > for InsertAttributeStmt
458{
459 fn params(
460 &'a mut self,
461 client: &'a C,
462 params: &'a InsertAttributeParams<T1, T2, T3, T4>,
463 ) -> I32Query<'a, C, i32, 7> {
464 self.bind(
465 client,
466 ¶ms.title,
467 ¶ms.description,
468 ¶ms.type_id,
469 ¶ms.slug,
470 ¶ms.external_id,
471 ¶ms.organization_id,
472 ¶ms.created_by,
473 )
474 }
475}
476pub fn update_attribute() -> UpdateAttributeStmt {
477 UpdateAttributeStmt(crate::client::async_::Stmt::new(
478 "UPDATE
479attribute
480SET
481 type_id = coalesce($1, type_id),
482 title = coalesce($2, title),
483 description = coalesce($3, description),
484 slug = coalesce($4, slug),
485 external_id = coalesce($5, external_id)
486WHERE
487 id = $6",
488 ))
489}
490pub struct UpdateAttributeStmt(crate::client::async_::Stmt);
491impl UpdateAttributeStmt {
492 pub async fn bind<
493 'a,
494 C: GenericClient,
495 T1: crate::JsonSql,
496 T2: crate::JsonSql,
497 T3: crate::StringSql,
498 T4: crate::StringSql,
499 >(
500 &'a mut self,
501 client: &'a C,
502 type_id: &'a Option<i32>,
503 title: &'a Option<T1>,
504 description: &'a Option<T2>,
505 slug: &'a Option<T3>,
506 external_id: &'a Option<T4>,
507 id: &'a i32,
508 ) -> Result<u64, tokio_postgres::Error> {
509 let stmt = self.0.prepare(client).await?;
510 client
511 .execute(stmt, &[type_id, title, description, slug, external_id, id])
512 .await
513 }
514}
515impl<
516 'a,
517 C: GenericClient + Send + Sync,
518 T1: crate::JsonSql,
519 T2: crate::JsonSql,
520 T3: crate::StringSql,
521 T4: crate::StringSql,
522 >
523 crate::client::async_::Params<
524 'a,
525 UpdateAttributeParams<T1, T2, T3, T4>,
526 std::pin::Pin<
527 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
528 >,
529 C,
530 > for UpdateAttributeStmt
531{
532 fn params(
533 &'a mut self,
534 client: &'a C,
535 params: &'a UpdateAttributeParams<T1, T2, T3, T4>,
536 ) -> std::pin::Pin<
537 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
538 > {
539 Box::pin(self.bind(
540 client,
541 ¶ms.type_id,
542 ¶ms.title,
543 ¶ms.description,
544 ¶ms.slug,
545 ¶ms.external_id,
546 ¶ms.id,
547 ))
548 }
549}
550pub fn delete_attribute() -> DeleteAttributeStmt {
551 DeleteAttributeStmt(crate::client::async_::Stmt::new(
552 "DELETE FROM attribute
553WHERE organization_id = $1
554 AND id = $2",
555 ))
556}
557pub struct DeleteAttributeStmt(crate::client::async_::Stmt);
558impl DeleteAttributeStmt {
559 pub async fn bind<'a, C: GenericClient>(
560 &'a mut self,
561 client: &'a C,
562 organization_id: &'a i32,
563 id: &'a i32,
564 ) -> Result<u64, tokio_postgres::Error> {
565 let stmt = self.0.prepare(client).await?;
566 client.execute(stmt, &[organization_id, id]).await
567 }
568}
569impl<'a, C: GenericClient + Send + Sync>
570 crate::client::async_::Params<
571 'a,
572 DeleteAttributeParams,
573 std::pin::Pin<
574 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
575 >,
576 C,
577 > for DeleteAttributeStmt
578{
579 fn params(
580 &'a mut self,
581 client: &'a C,
582 params: &'a DeleteAttributeParams,
583 ) -> std::pin::Pin<
584 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
585 > {
586 Box::pin(self.bind(client, ¶ms.organization_id, ¶ms.id))
587 }
588}
589pub fn associate_style_attributes() -> AssociateStyleAttributesStmt {
590 AssociateStyleAttributesStmt(crate::client::async_::Stmt::new(
591 "SELECT *
592FROM
593 associate_style_attributes($1, $2)",
594 ))
595}
596pub struct AssociateStyleAttributesStmt(crate::client::async_::Stmt);
597impl AssociateStyleAttributesStmt {
598 pub fn bind<'a, C: GenericClient, T1: crate::ArraySql<Item = i32>>(
599 &'a mut self,
600 client: &'a C,
601 style_id: &'a i32,
602 attribute_ids: &'a T1,
603 ) -> I32Query<'a, C, i32, 2> {
604 I32Query {
605 client,
606 params: [style_id, attribute_ids],
607 stmt: &mut self.0,
608 extractor: |row| row.get(0),
609 mapper: |it| it,
610 }
611 }
612}
613impl<'a, C: GenericClient, T1: crate::ArraySql<Item = i32>>
614 crate::client::async_::Params<
615 'a,
616 AssociateStyleAttributesParams<T1>,
617 I32Query<'a, C, i32, 2>,
618 C,
619 > for AssociateStyleAttributesStmt
620{
621 fn params(
622 &'a mut self,
623 client: &'a C,
624 params: &'a AssociateStyleAttributesParams<T1>,
625 ) -> I32Query<'a, C, i32, 2> {
626 self.bind(client, ¶ms.style_id, ¶ms.attribute_ids)
627 }
628}