bindizr_db/repository/postgres/
api_token_repository_impl.rs1use async_trait::async_trait;
2use sqlx::{Pool, Postgres, Row};
3
4use crate::{error::DatabaseError, model::api_token::ApiToken, repository::ApiTokenRepository};
5
6pub struct PostgresApiTokenRepository {
7 pool: Pool<Postgres>,
8}
9
10impl PostgresApiTokenRepository {
11 pub fn new(pool: Pool<Postgres>) -> Self {
12 Self { pool }
13 }
14}
15
16#[async_trait]
17impl ApiTokenRepository for PostgresApiTokenRepository {
18 async fn create(&self, mut token: ApiToken) -> Result<ApiToken, DatabaseError> {
19 let mut conn = self.pool.acquire().await?;
20
21 let result = sqlx::query(
22 r#"
23 INSERT INTO api_tokens (token, description, expires_at)
24 VALUES ($1, $2, $3)
25 RETURNING id
26 "#,
27 )
28 .bind(&token.token)
29 .bind(&token.description)
30 .bind(token.expires_at)
31 .fetch_one(&mut *conn)
32 .await?;
33
34 token.id = result.get::<i32, _>(0);
35
36 Ok(token)
37 }
38
39 async fn get_by_id(&self, id: i32) -> Result<Option<ApiToken>, DatabaseError> {
40 let mut conn = self.pool.acquire().await?;
41
42 let row = sqlx::query_as::<_, ApiToken>(
43 "SELECT id, token, description, expires_at, created_at, last_used_at FROM api_tokens WHERE id = $1"
44 )
45 .bind(id)
46 .fetch_optional(&mut *conn)
47 .await
48 ?;
49
50 Ok(row)
51 }
52
53 async fn get_by_token(&self, token: &str) -> Result<Option<ApiToken>, DatabaseError> {
54 let mut conn = self.pool.acquire().await?;
55
56 let row = sqlx::query_as::<_, ApiToken>(
57 "SELECT id, token, description, expires_at, created_at, last_used_at FROM api_tokens WHERE token = $1"
58 )
59 .bind(token)
60 .fetch_optional(&mut *conn)
61 .await
62 ?;
63
64 Ok(row)
65 }
66
67 async fn get_all(&self) -> Result<Vec<ApiToken>, DatabaseError> {
68 let mut conn = self.pool.acquire().await?;
69
70 let rows = sqlx::query_as::<_, ApiToken>(
71 "SELECT id, token, description, expires_at, created_at, last_used_at FROM api_tokens ORDER BY created_at DESC"
72 )
73 .fetch_all(&mut *conn)
74 .await
75 ?;
76
77 Ok(rows)
78 }
79
80 async fn update(&self, token: ApiToken) -> Result<ApiToken, DatabaseError> {
81 let mut conn = self.pool.acquire().await?;
82
83 sqlx::query(
84 r#"
85 UPDATE api_tokens
86 SET description = $1, expires_at = $2, last_used_at = $3
87 WHERE id = $4
88 "#,
89 )
90 .bind(&token.description)
91 .bind(token.expires_at)
92 .bind(token.last_used_at)
93 .bind(token.id)
94 .execute(&mut *conn)
95 .await?;
96
97 Ok(token)
98 }
99
100 async fn delete(&self, id: i32) -> Result<(), DatabaseError> {
101 let mut conn = self.pool.acquire().await?;
102
103 sqlx::query("DELETE FROM api_tokens WHERE id = $1")
104 .bind(id)
105 .execute(&mut *conn)
106 .await?;
107
108 Ok(())
109 }
110}