1#[derive(Debug)]
4pub struct SelectUsersParams<
5 T1: crate::StringSql,
6 T2: crate::ArraySql<Item = i32>,
7 T3: crate::ArraySql<Item = i32>,
8> {
9 pub organization_id: Option<i32>,
10 pub id: Option<i32>,
11 pub email: Option<T1>,
12 pub roles: Option<T2>,
13 pub groups: Option<T3>,
14}
15#[derive(Clone, Copy, Debug)]
16pub struct GetOrgUserIdParams {
17 pub organization_id: i32,
18 pub user_id: i32,
19}
20#[derive(Clone, Copy, Debug)]
21pub struct GetRoleIdsParams {
22 pub user_id: i32,
23 pub organization_id: i32,
24}
25#[derive(Debug)]
26pub struct InsertUserParams<
27 T1: crate::StringSql,
28 T2: crate::StringSql,
29 T3: crate::StringSql,
30 T4: crate::StringSql,
31> {
32 pub name: T1,
33 pub email: T2,
34 pub password_hash: Option<T3>,
35 pub profile_image: Option<T4>,
36}
37#[derive(Debug)]
38pub struct UpdateUserParams<
39 T1: crate::StringSql,
40 T2: crate::StringSql,
41 T3: crate::StringSql,
42 T4: crate::StringSql,
43> {
44 pub name: Option<T1>,
45 pub email: Option<T2>,
46 pub password_hash: Option<T3>,
47 pub profile_image: Option<T4>,
48 pub id: i32,
49}
50#[derive(Debug)]
51pub struct UpsertUserOrganizationParams<T1: crate::ArraySql<Item = i32>> {
52 pub user_id: i32,
53 pub organization_id: i32,
54 pub role_ids: Option<T1>,
55}
56#[derive(Debug)]
57pub struct ReplaceUserGroupsParams<T1: crate::ArraySql<Item = i32>> {
58 pub user_id: i32,
59 pub group_ids: T1,
60}
61#[derive(Debug, Clone, PartialEq)]
62pub struct UserRow {
63 pub id: i32,
64 pub name: String,
65 pub email: String,
66 pub password_hash: Option<String>,
67 pub created_at: chrono::DateTime<chrono::FixedOffset>,
68 pub updated_at: chrono::DateTime<chrono::FixedOffset>,
69 pub profile_image: Option<String>,
70 pub last_sign_in: Option<chrono::DateTime<chrono::FixedOffset>>,
71 pub organizations: serde_json::Value,
72 pub groups: serde_json::Value,
73}
74pub struct UserRowBorrowed<'a> {
75 pub id: i32,
76 pub name: &'a str,
77 pub email: &'a str,
78 pub password_hash: Option<&'a str>,
79 pub created_at: chrono::DateTime<chrono::FixedOffset>,
80 pub updated_at: chrono::DateTime<chrono::FixedOffset>,
81 pub profile_image: Option<&'a str>,
82 pub last_sign_in: Option<chrono::DateTime<chrono::FixedOffset>>,
83 pub organizations: postgres_types::Json<&'a serde_json::value::RawValue>,
84 pub groups: postgres_types::Json<&'a serde_json::value::RawValue>,
85}
86impl<'a> From<UserRowBorrowed<'a>> for UserRow {
87 fn from(
88 UserRowBorrowed {
89 id,
90 name,
91 email,
92 password_hash,
93 created_at,
94 updated_at,
95 profile_image,
96 last_sign_in,
97 organizations,
98 groups,
99 }: UserRowBorrowed<'a>,
100 ) -> Self {
101 Self {
102 id,
103 name: name.into(),
104 email: email.into(),
105 password_hash: password_hash.map(|v| v.into()),
106 created_at,
107 updated_at,
108 profile_image: profile_image.map(|v| v.into()),
109 last_sign_in,
110 organizations: serde_json::from_str(organizations.0.get()).unwrap(),
111 groups: serde_json::from_str(groups.0.get()).unwrap(),
112 }
113 }
114}
115use crate::client::async_::GenericClient;
116use futures::{self, StreamExt, TryStreamExt};
117pub struct UserRowQuery<'a, C: GenericClient, T, const N: usize> {
118 client: &'a C,
119 params: [&'a (dyn postgres_types::ToSql + Sync); N],
120 stmt: &'a mut crate::client::async_::Stmt,
121 extractor: fn(&tokio_postgres::Row) -> UserRowBorrowed,
122 mapper: fn(UserRowBorrowed) -> T,
123}
124impl<'a, C, T: 'a, const N: usize> UserRowQuery<'a, C, T, N>
125where
126 C: GenericClient,
127{
128 pub fn map<R>(self, mapper: fn(UserRowBorrowed) -> R) -> UserRowQuery<'a, C, R, N> {
129 UserRowQuery {
130 client: self.client,
131 params: self.params,
132 stmt: self.stmt,
133 extractor: self.extractor,
134 mapper,
135 }
136 }
137 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
138 let stmt = self.stmt.prepare(self.client).await?;
139 let row = self.client.query_one(stmt, &self.params).await?;
140 Ok((self.mapper)((self.extractor)(&row)))
141 }
142 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
143 self.iter().await?.try_collect().await
144 }
145 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
146 let stmt = self.stmt.prepare(self.client).await?;
147 Ok(self
148 .client
149 .query_opt(stmt, &self.params)
150 .await?
151 .map(|row| (self.mapper)((self.extractor)(&row))))
152 }
153 pub async fn iter(
154 self,
155 ) -> Result<
156 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
157 tokio_postgres::Error,
158 > {
159 let stmt = self.stmt.prepare(self.client).await?;
160 let it = self
161 .client
162 .query_raw(stmt, crate::slice_iter(&self.params))
163 .await?
164 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
165 .into_stream();
166 Ok(it)
167 }
168}
169pub struct I32Query<'a, C: GenericClient, T, const N: usize> {
170 client: &'a C,
171 params: [&'a (dyn postgres_types::ToSql + Sync); N],
172 stmt: &'a mut crate::client::async_::Stmt,
173 extractor: fn(&tokio_postgres::Row) -> i32,
174 mapper: fn(i32) -> T,
175}
176impl<'a, C, T: 'a, const N: usize> I32Query<'a, C, T, N>
177where
178 C: GenericClient,
179{
180 pub fn map<R>(self, mapper: fn(i32) -> R) -> I32Query<'a, C, R, N> {
181 I32Query {
182 client: self.client,
183 params: self.params,
184 stmt: self.stmt,
185 extractor: self.extractor,
186 mapper,
187 }
188 }
189 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
190 let stmt = self.stmt.prepare(self.client).await?;
191 let row = self.client.query_one(stmt, &self.params).await?;
192 Ok((self.mapper)((self.extractor)(&row)))
193 }
194 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
195 self.iter().await?.try_collect().await
196 }
197 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
198 let stmt = self.stmt.prepare(self.client).await?;
199 Ok(self
200 .client
201 .query_opt(stmt, &self.params)
202 .await?
203 .map(|row| (self.mapper)((self.extractor)(&row))))
204 }
205 pub async fn iter(
206 self,
207 ) -> Result<
208 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
209 tokio_postgres::Error,
210 > {
211 let stmt = self.stmt.prepare(self.client).await?;
212 let it = self
213 .client
214 .query_raw(stmt, crate::slice_iter(&self.params))
215 .await?
216 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
217 .into_stream();
218 Ok(it)
219 }
220}
221pub struct Veci32Query<'a, C: GenericClient, T, const N: usize> {
222 client: &'a C,
223 params: [&'a (dyn postgres_types::ToSql + Sync); N],
224 stmt: &'a mut crate::client::async_::Stmt,
225 extractor: fn(&tokio_postgres::Row) -> crate::ArrayIterator<'_, i32>,
226 mapper: fn(crate::ArrayIterator<'_, i32>) -> T,
227}
228impl<'a, C, T: 'a, const N: usize> Veci32Query<'a, C, T, N>
229where
230 C: GenericClient,
231{
232 pub fn map<R>(
233 self,
234 mapper: fn(crate::ArrayIterator<'_, i32>) -> R,
235 ) -> Veci32Query<'a, C, R, N> {
236 Veci32Query {
237 client: self.client,
238 params: self.params,
239 stmt: self.stmt,
240 extractor: self.extractor,
241 mapper,
242 }
243 }
244 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
245 let stmt = self.stmt.prepare(self.client).await?;
246 let row = self.client.query_one(stmt, &self.params).await?;
247 Ok((self.mapper)((self.extractor)(&row)))
248 }
249 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
250 self.iter().await?.try_collect().await
251 }
252 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
253 let stmt = self.stmt.prepare(self.client).await?;
254 Ok(self
255 .client
256 .query_opt(stmt, &self.params)
257 .await?
258 .map(|row| (self.mapper)((self.extractor)(&row))))
259 }
260 pub async fn iter(
261 self,
262 ) -> Result<
263 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
264 tokio_postgres::Error,
265 > {
266 let stmt = self.stmt.prepare(self.client).await?;
267 let it = self
268 .client
269 .query_raw(stmt, crate::slice_iter(&self.params))
270 .await?
271 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
272 .into_stream();
273 Ok(it)
274 }
275}
276pub struct StringQuery<'a, C: GenericClient, T, const N: usize> {
277 client: &'a C,
278 params: [&'a (dyn postgres_types::ToSql + Sync); N],
279 stmt: &'a mut crate::client::async_::Stmt,
280 extractor: fn(&tokio_postgres::Row) -> &str,
281 mapper: fn(&str) -> T,
282}
283impl<'a, C, T: 'a, const N: usize> StringQuery<'a, C, T, N>
284where
285 C: GenericClient,
286{
287 pub fn map<R>(self, mapper: fn(&str) -> R) -> StringQuery<'a, C, R, N> {
288 StringQuery {
289 client: self.client,
290 params: self.params,
291 stmt: self.stmt,
292 extractor: self.extractor,
293 mapper,
294 }
295 }
296 pub async fn one(self) -> Result<T, tokio_postgres::Error> {
297 let stmt = self.stmt.prepare(self.client).await?;
298 let row = self.client.query_one(stmt, &self.params).await?;
299 Ok((self.mapper)((self.extractor)(&row)))
300 }
301 pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
302 self.iter().await?.try_collect().await
303 }
304 pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
305 let stmt = self.stmt.prepare(self.client).await?;
306 Ok(self
307 .client
308 .query_opt(stmt, &self.params)
309 .await?
310 .map(|row| (self.mapper)((self.extractor)(&row))))
311 }
312 pub async fn iter(
313 self,
314 ) -> Result<
315 impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
316 tokio_postgres::Error,
317 > {
318 let stmt = self.stmt.prepare(self.client).await?;
319 let it = self
320 .client
321 .query_raw(stmt, crate::slice_iter(&self.params))
322 .await?
323 .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
324 .into_stream();
325 Ok(it)
326 }
327}
328pub fn select_users() -> SelectUsersStmt {
329 SelectUsersStmt(crate::client::async_::Stmt::new(
330 "WITH group_summaries AS (
331 SELECT
332 \"group\".id,
333 \"group\".slug,
334 \"group\".external_id,
335 \"group\".name,
336 \"group\".description,
337 coalesce(user_counts.n, 0) AS num_users,
338 coalesce(collection_counts.n, 0) AS num_collections,
339 coalesce(pricelist_counts.n, 0) AS num_price_lists
340 FROM \"group\"
341 LEFT JOIN LATERAL (
342 SELECT
343 group_user.group_id,
344 count(*) AS n
345 FROM group_user
346 WHERE group_user.group_id = \"group\".id
347 GROUP BY group_user.group_id
348 ) AS user_counts ON user_counts.group_id = \"group\".id
349 LEFT JOIN LATERAL (
350 SELECT
351 group_collection.group_id,
352 count(*) AS n
353 FROM
354 group_collection
355 WHERE group_collection.group_id = \"group\".id GROUP BY group_collection.group_id
356 ) AS collection_counts ON collection_counts.group_id = \"group\".id
357 LEFT JOIN LATERAL (
358 SELECT
359 group_pricelist.group_id,
360 count(*) AS n
361 FROM
362 group_pricelist
363 WHERE group_pricelist.group_id = \"group\".id GROUP BY group_pricelist.group_id
364 ) AS pricelist_counts ON pricelist_counts.group_id = \"group\".id
365 WHERE
366 ($1::int IS NULL OR \"group\".organization_id = $1)
367)
368
369SELECT
370 \"user\".*,
371 coalesce(organizations.json_data, '[]'::jsonb) AS organizations,
372 coalesce(\"groups\".json_data, '[]'::jsonb) AS \"groups\"
373FROM
374 \"user\"
375LEFT JOIN (
376 SELECT
377 user_organization.user_id,
378 array_agg(organization.id) AS ids,
379 jsonb_agg(
380 jsonb_build_object(
381 'organization',
382 jsonb_build_object(
383 'id',
384 organization.id,
385 'name',
386 organization.name,
387 'logo_url',
388 organization.logo_url
389 ),
390 'role_ids',
391 user_organization.role_ids
392 )
393 ) AS json_data
394 FROM user_organization
395 INNER JOIN
396 organization ON organization.id = user_organization.organization_id
397 GROUP BY user_organization.user_id
398) AS organizations ON organizations.user_id = \"user\".id
399LEFT JOIN (
400 SELECT
401 group_user.user_id,
402 array_agg(group_user.group_id) AS group_ids,
403 jsonb_agg(group_summaries.*) AS json_data
404 FROM group_user
405 INNER JOIN group_summaries
406 ON group_summaries.id = group_user.group_id
407 GROUP BY group_user.user_id
408) AS \"groups\" ON \"groups\".user_id = \"user\".id
409WHERE
410 ($1::int IS NULL OR $1 = any(organizations.ids))
411 AND ($2::int IS NULL OR \"user\".id = $2)
412 AND ($3::text IS NULL OR lower(\"user\".email) = lower($3))
413 AND (
414 $4::int[] IS NULL
415 OR jsonb_path_query_first(
416 organizations.json_data,
417 '$[*] ? (@.organization.id == $organization_id).role_ids',
418 jsonb_build_object('organization_id', $1)
419 ) @> to_jsonb($4)
420 )
421 AND ($5::int[] IS NULL OR \"groups\".group_ids @> $5)",
422 ))
423}
424pub struct SelectUsersStmt(crate::client::async_::Stmt);
425impl SelectUsersStmt {
426 pub fn bind<
427 'a,
428 C: GenericClient,
429 T1: crate::StringSql,
430 T2: crate::ArraySql<Item = i32>,
431 T3: crate::ArraySql<Item = i32>,
432 >(
433 &'a mut self,
434 client: &'a C,
435 organization_id: &'a Option<i32>,
436 id: &'a Option<i32>,
437 email: &'a Option<T1>,
438 roles: &'a Option<T2>,
439 groups: &'a Option<T3>,
440 ) -> UserRowQuery<'a, C, UserRow, 5> {
441 UserRowQuery {
442 client,
443 params: [organization_id, id, email, roles, groups],
444 stmt: &mut self.0,
445 extractor: |row| UserRowBorrowed {
446 id: row.get(0),
447 name: row.get(1),
448 email: row.get(2),
449 password_hash: row.get(3),
450 created_at: row.get(4),
451 updated_at: row.get(5),
452 profile_image: row.get(6),
453 last_sign_in: row.get(7),
454 organizations: row.get(8),
455 groups: row.get(9),
456 },
457 mapper: |it| <UserRow>::from(it),
458 }
459 }
460}
461impl<
462 'a,
463 C: GenericClient,
464 T1: crate::StringSql,
465 T2: crate::ArraySql<Item = i32>,
466 T3: crate::ArraySql<Item = i32>,
467 >
468 crate::client::async_::Params<
469 'a,
470 SelectUsersParams<T1, T2, T3>,
471 UserRowQuery<'a, C, UserRow, 5>,
472 C,
473 > for SelectUsersStmt
474{
475 fn params(
476 &'a mut self,
477 client: &'a C,
478 params: &'a SelectUsersParams<T1, T2, T3>,
479 ) -> UserRowQuery<'a, C, UserRow, 5> {
480 self.bind(
481 client,
482 ¶ms.organization_id,
483 ¶ms.id,
484 ¶ms.email,
485 ¶ms.roles,
486 ¶ms.groups,
487 )
488 }
489}
490pub fn get_org_user_id() -> GetOrgUserIdStmt {
491 GetOrgUserIdStmt(crate::client::async_::Stmt::new(
492 "SELECT \"user\".id
493FROM
494 \"user\"
495INNER JOIN user_organization
496 ON user_organization.user_id = \"user\".id
497WHERE
498 user_organization.organization_id = $1
499 AND \"user\".id = $2",
500 ))
501}
502pub struct GetOrgUserIdStmt(crate::client::async_::Stmt);
503impl GetOrgUserIdStmt {
504 pub fn bind<'a, C: GenericClient>(
505 &'a mut self,
506 client: &'a C,
507 organization_id: &'a i32,
508 user_id: &'a i32,
509 ) -> I32Query<'a, C, i32, 2> {
510 I32Query {
511 client,
512 params: [organization_id, user_id],
513 stmt: &mut self.0,
514 extractor: |row| row.get(0),
515 mapper: |it| it,
516 }
517 }
518}
519impl<'a, C: GenericClient>
520 crate::client::async_::Params<'a, GetOrgUserIdParams, I32Query<'a, C, i32, 2>, C>
521 for GetOrgUserIdStmt
522{
523 fn params(
524 &'a mut self,
525 client: &'a C,
526 params: &'a GetOrgUserIdParams,
527 ) -> I32Query<'a, C, i32, 2> {
528 self.bind(client, ¶ms.organization_id, ¶ms.user_id)
529 }
530}
531pub fn get_role_ids() -> GetRoleIdsStmt {
532 GetRoleIdsStmt(crate::client::async_::Stmt::new(
533 "SELECT user_organization.role_ids
534FROM
535 user_organization
536WHERE
537 user_organization.user_id = $1
538 AND user_organization.organization_id = $2",
539 ))
540}
541pub struct GetRoleIdsStmt(crate::client::async_::Stmt);
542impl GetRoleIdsStmt {
543 pub fn bind<'a, C: GenericClient>(
544 &'a mut self,
545 client: &'a C,
546 user_id: &'a i32,
547 organization_id: &'a i32,
548 ) -> Veci32Query<'a, C, Vec<i32>, 2> {
549 Veci32Query {
550 client,
551 params: [user_id, organization_id],
552 stmt: &mut self.0,
553 extractor: |row| row.get(0),
554 mapper: |it| it.map(|v| v).collect(),
555 }
556 }
557}
558impl<'a, C: GenericClient>
559 crate::client::async_::Params<'a, GetRoleIdsParams, Veci32Query<'a, C, Vec<i32>, 2>, C>
560 for GetRoleIdsStmt
561{
562 fn params(
563 &'a mut self,
564 client: &'a C,
565 params: &'a GetRoleIdsParams,
566 ) -> Veci32Query<'a, C, Vec<i32>, 2> {
567 self.bind(client, ¶ms.user_id, ¶ms.organization_id)
568 }
569}
570pub fn insert_user() -> InsertUserStmt {
571 InsertUserStmt(crate::client::async_::Stmt::new(
572 "INSERT INTO \"user\" (
573 name,
574 email,
575 password_hash,
576 profile_image)
577VALUES (
578 $1,
579 $2,
580 $3,
581 $4)
582RETURNING
583id",
584 ))
585}
586pub struct InsertUserStmt(crate::client::async_::Stmt);
587impl InsertUserStmt {
588 pub fn bind<
589 'a,
590 C: GenericClient,
591 T1: crate::StringSql,
592 T2: crate::StringSql,
593 T3: crate::StringSql,
594 T4: crate::StringSql,
595 >(
596 &'a mut self,
597 client: &'a C,
598 name: &'a T1,
599 email: &'a T2,
600 password_hash: &'a Option<T3>,
601 profile_image: &'a Option<T4>,
602 ) -> I32Query<'a, C, i32, 4> {
603 I32Query {
604 client,
605 params: [name, email, password_hash, profile_image],
606 stmt: &mut self.0,
607 extractor: |row| row.get(0),
608 mapper: |it| it,
609 }
610 }
611}
612impl<
613 'a,
614 C: GenericClient,
615 T1: crate::StringSql,
616 T2: crate::StringSql,
617 T3: crate::StringSql,
618 T4: crate::StringSql,
619 >
620 crate::client::async_::Params<'a, InsertUserParams<T1, T2, T3, T4>, I32Query<'a, C, i32, 4>, C>
621 for InsertUserStmt
622{
623 fn params(
624 &'a mut self,
625 client: &'a C,
626 params: &'a InsertUserParams<T1, T2, T3, T4>,
627 ) -> I32Query<'a, C, i32, 4> {
628 self.bind(
629 client,
630 ¶ms.name,
631 ¶ms.email,
632 ¶ms.password_hash,
633 ¶ms.profile_image,
634 )
635 }
636}
637pub fn update_user() -> UpdateUserStmt {
638 UpdateUserStmt(crate::client::async_::Stmt::new(
639 "UPDATE
640\"user\"
641SET
642 name = coalesce($1, name),
643 email = coalesce($2, email),
644 password_hash = coalesce($3, password_hash),
645 profile_image = coalesce($4, profile_image)
646WHERE
647 id = $5",
648 ))
649}
650pub struct UpdateUserStmt(crate::client::async_::Stmt);
651impl UpdateUserStmt {
652 pub async fn bind<
653 'a,
654 C: GenericClient,
655 T1: crate::StringSql,
656 T2: crate::StringSql,
657 T3: crate::StringSql,
658 T4: crate::StringSql,
659 >(
660 &'a mut self,
661 client: &'a C,
662 name: &'a Option<T1>,
663 email: &'a Option<T2>,
664 password_hash: &'a Option<T3>,
665 profile_image: &'a Option<T4>,
666 id: &'a i32,
667 ) -> Result<u64, tokio_postgres::Error> {
668 let stmt = self.0.prepare(client).await?;
669 client
670 .execute(stmt, &[name, email, password_hash, profile_image, id])
671 .await
672 }
673}
674impl<
675 'a,
676 C: GenericClient + Send + Sync,
677 T1: crate::StringSql,
678 T2: crate::StringSql,
679 T3: crate::StringSql,
680 T4: crate::StringSql,
681 >
682 crate::client::async_::Params<
683 'a,
684 UpdateUserParams<T1, T2, T3, T4>,
685 std::pin::Pin<
686 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
687 >,
688 C,
689 > for UpdateUserStmt
690{
691 fn params(
692 &'a mut self,
693 client: &'a C,
694 params: &'a UpdateUserParams<T1, T2, T3, T4>,
695 ) -> std::pin::Pin<
696 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
697 > {
698 Box::pin(self.bind(
699 client,
700 ¶ms.name,
701 ¶ms.email,
702 ¶ms.password_hash,
703 ¶ms.profile_image,
704 ¶ms.id,
705 ))
706 }
707}
708pub fn delete_user() -> DeleteUserStmt {
709 DeleteUserStmt(crate::client::async_::Stmt::new(
710 "DELETE FROM \"user\"
711WHERE id = $1",
712 ))
713}
714pub struct DeleteUserStmt(crate::client::async_::Stmt);
715impl DeleteUserStmt {
716 pub async fn bind<'a, C: GenericClient>(
717 &'a mut self,
718 client: &'a C,
719 id: &'a i32,
720 ) -> Result<u64, tokio_postgres::Error> {
721 let stmt = self.0.prepare(client).await?;
722 client.execute(stmt, &[id]).await
723 }
724}
725pub fn upsert_user_organization() -> UpsertUserOrganizationStmt {
726 UpsertUserOrganizationStmt(crate::client::async_::Stmt::new(
727 "INSERT INTO user_organization (
728 user_id,
729 organization_id,
730 role_ids
731)
732VALUES (
733 $1,
734 $2,
735 $3
736)
737ON CONFLICT ON CONSTRAINT user_organization_uq
738DO UPDATE SET role_ids = coalesce(excluded.role_ids, user_organization.role_ids)",
739 ))
740}
741pub struct UpsertUserOrganizationStmt(crate::client::async_::Stmt);
742impl UpsertUserOrganizationStmt {
743 pub async fn bind<'a, C: GenericClient, T1: crate::ArraySql<Item = i32>>(
744 &'a mut self,
745 client: &'a C,
746 user_id: &'a i32,
747 organization_id: &'a i32,
748 role_ids: &'a Option<T1>,
749 ) -> Result<u64, tokio_postgres::Error> {
750 let stmt = self.0.prepare(client).await?;
751 client
752 .execute(stmt, &[user_id, organization_id, role_ids])
753 .await
754 }
755}
756impl<'a, C: GenericClient + Send + Sync, T1: crate::ArraySql<Item = i32>>
757 crate::client::async_::Params<
758 'a,
759 UpsertUserOrganizationParams<T1>,
760 std::pin::Pin<
761 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
762 >,
763 C,
764 > for UpsertUserOrganizationStmt
765{
766 fn params(
767 &'a mut self,
768 client: &'a C,
769 params: &'a UpsertUserOrganizationParams<T1>,
770 ) -> std::pin::Pin<
771 Box<dyn futures::Future<Output = Result<u64, tokio_postgres::Error>> + Send + 'a>,
772 > {
773 Box::pin(self.bind(
774 client,
775 ¶ms.user_id,
776 ¶ms.organization_id,
777 ¶ms.role_ids,
778 ))
779 }
780}
781pub fn get_user_password_hash() -> GetUserPasswordHashStmt {
782 GetUserPasswordHashStmt(crate::client::async_::Stmt::new(
783 "SELECT \"user\".password_hash
784FROM
785 \"user\"
786WHERE
787 \"user\".id = $1",
788 ))
789}
790pub struct GetUserPasswordHashStmt(crate::client::async_::Stmt);
791impl GetUserPasswordHashStmt {
792 pub fn bind<'a, C: GenericClient>(
793 &'a mut self,
794 client: &'a C,
795 user_id: &'a i32,
796 ) -> StringQuery<'a, C, String, 1> {
797 StringQuery {
798 client,
799 params: [user_id],
800 stmt: &mut self.0,
801 extractor: |row| row.get(0),
802 mapper: |it| it.into(),
803 }
804 }
805}
806pub fn update_last_sign_in() -> UpdateLastSignInStmt {
807 UpdateLastSignInStmt(crate::client::async_::Stmt::new(
808 "UPDATE \"user\" SET last_sign_in = now() WHERE id = $1",
809 ))
810}
811pub struct UpdateLastSignInStmt(crate::client::async_::Stmt);
812impl UpdateLastSignInStmt {
813 pub async fn bind<'a, C: GenericClient>(
814 &'a mut self,
815 client: &'a C,
816 id: &'a i32,
817 ) -> Result<u64, tokio_postgres::Error> {
818 let stmt = self.0.prepare(client).await?;
819 client.execute(stmt, &[id]).await
820 }
821}
822pub fn replace_user_groups() -> ReplaceUserGroupsStmt {
823 ReplaceUserGroupsStmt(crate::client::async_::Stmt::new(
824 "SELECT *
825FROM
826 replace_user_groups($1, $2)",
827 ))
828}
829pub struct ReplaceUserGroupsStmt(crate::client::async_::Stmt);
830impl ReplaceUserGroupsStmt {
831 pub fn bind<'a, C: GenericClient, T1: crate::ArraySql<Item = i32>>(
832 &'a mut self,
833 client: &'a C,
834 user_id: &'a i32,
835 group_ids: &'a T1,
836 ) -> I32Query<'a, C, i32, 2> {
837 I32Query {
838 client,
839 params: [user_id, group_ids],
840 stmt: &mut self.0,
841 extractor: |row| row.get(0),
842 mapper: |it| it,
843 }
844 }
845}
846impl<'a, C: GenericClient, T1: crate::ArraySql<Item = i32>>
847 crate::client::async_::Params<'a, ReplaceUserGroupsParams<T1>, I32Query<'a, C, i32, 2>, C>
848 for ReplaceUserGroupsStmt
849{
850 fn params(
851 &'a mut self,
852 client: &'a C,
853 params: &'a ReplaceUserGroupsParams<T1>,
854 ) -> I32Query<'a, C, i32, 2> {
855 self.bind(client, ¶ms.user_id, ¶ms.group_ids)
856 }
857}