Skip to main content

shared/domain/permission/
repository.rs

1use std::sync::Arc;
2
3use crate::error::{CoreError, InternalError, ResourceKind, Result};
4
5use super::model::Permission;
6use super::ports::database::DatabaseAdapter;
7use super::ports::query::QueryBuilder;
8
9#[derive(Clone)]
10pub struct PermissionRepository {
11    adapter: Arc<dyn DatabaseAdapter<Permission>>,
12}
13
14impl PermissionRepository {
15    pub fn new(adapter: Arc<dyn DatabaseAdapter<Permission>>) -> Self {
16        Self { adapter }
17    }
18}
19
20impl PermissionRepository {
21    #[tracing::instrument(name = "db.permission.insert", skip(self, permission))]
22    pub async fn insert(&self, permission: Permission) -> Result<String> {
23        match self.adapter.upsert(permission).await {
24            Ok(id) => Ok(id),
25            Err(err) => {
26                tracing::error!("Failed to insert permission to database - {err}");
27                Err(CoreError::Internal(InternalError::Database(
28                    err.to_string(),
29                )))
30            }
31        }
32    }
33    #[tracing::instrument(name = "db.permission.insert", skip(self, permissions))]
34    pub async fn upsert_many(&self, permissions: Vec<Permission>) -> Result<Vec<String>> {
35        match self.adapter.upsert_many(permissions).await {
36            Ok(ids) => Ok(ids),
37            Err(err) => {
38                tracing::error!("Failed to insert permission to database - {err}");
39                Err(CoreError::Internal(InternalError::Database(
40                    err.to_string(),
41                )))
42            }
43        }
44    }
45
46    #[tracing::instrument(name = "db.permission.find", skip(self, name))]
47    pub async fn find(&self, name: &str) -> Result<Permission> {
48        let filter = QueryBuilder::default().eq("name", name);
49
50        match self.adapter.find_one(filter).await {
51            Ok(Some(permission)) => Ok(permission),
52            // FIXME use Permission not Role
53            Ok(None) => Err(CoreError::NotFound(ResourceKind::Role {
54                id: Some(name.into()),
55            })),
56            Err(err) => {
57                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
58                Err(err)
59            }
60        }
61    }
62
63    #[tracing::instrument(name = "db.permission.find", skip(self))]
64    pub async fn find_all(&self) -> Result<Vec<Permission>> {
65        let filter = QueryBuilder::default();
66
67        match self.adapter.find_all(filter).await {
68            Ok(permissions) => Ok(permissions),
69            Err(err) => {
70                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
71                Err(err)
72            }
73        }
74    }
75
76    #[tracing::instrument(name = "db.permission.find_by_id", skip(self, ids))]
77    pub async fn find_by_ids(&self, ids: Vec<String>) -> Result<Vec<Permission>> {
78        let filter = QueryBuilder::default().in_("id", ids);
79
80        match self.adapter.find_all(filter).await {
81            Ok(permissions) => Ok(permissions),
82            Err(err) => {
83                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
84                Err(err)
85            }
86        }
87    }
88
89    #[tracing::instrument(name = "db.permission.find", skip(self, id))]
90    pub async fn delete(&self, id: &str) -> Result<()> {
91        let filter = QueryBuilder::default().eq("id", id);
92
93        match self.adapter.delete_one(filter).await {
94            Ok(_) => Ok(()),
95            Err(err) => {
96                tracing::error!(error_code = "InternalError::Database", error = %err, "Database query failed");
97                Err(err)
98            }
99        }
100    }
101}