Skip to main content

haste_repository/pg/
mod.rs

1use haste_fhir_model::r4::generated::resources::Resource;
2use haste_fhir_operation_error::derive::OperationOutcomeError;
3use haste_jwt::VersionId;
4use moka::future::Cache;
5use sqlx::Postgres;
6use std::sync::Arc;
7use tokio::sync::Mutex;
8
9use crate::Repository;
10
11pub use pending::PendingRows;
12
13mod async_job;
14mod failed_indexing;
15mod migrate;
16mod models;
17mod pending;
18mod rate_limit;
19mod sequence;
20mod transaction;
21
22#[derive(OperationOutcomeError, Debug)]
23pub enum StoreError {
24    #[error(code = "duplicate", diagnostic = "Resource already exists.")]
25    Duplicate,
26    #[error(code = "not-found", diagnostic = "Resource not found.")]
27    NotFound,
28    // A failure of the database, not of the request: answers 500.
29    #[error(code = "exception", diagnostic = "Database operation failed.")]
30    SQLXError(#[from] sqlx::Error),
31    #[error(code = "exception", diagnostic = "Failed to create transaction.")]
32    TransactionError,
33    #[error(code = "invalid", diagnostic = "Cannot commit non transaction.")]
34    NotTransaction,
35    #[error(code = "invalid", diagnostic = "Failed to commit the transaction.")]
36    FailedCommitTransaction,
37    #[error(code = "exception", diagnostic = "Failed to hash password.")]
38    PasswordHashError(argon2::password_hash::Error),
39    #[error(
40        code = "exception",
41        diagnostic = "Failed to deserialize resource: '{arg0}'"
42    )]
43    DeserializeError(String),
44}
45
46/// Connection types supported by the repository traits.
47#[derive(Debug, Clone)]
48pub enum PGConnection {
49    Pool(sqlx::Pool<Postgres>, Cache<VersionId, Resource>),
50    Transaction(
51        Arc<Mutex<sqlx::Transaction<'static, Postgres>>>,
52        Cache<VersionId, Resource>,
53        PendingRows,
54    ),
55}
56
57static TOTAL_CACHE_SIZE: u64 = 1000 * 10;
58
59impl PGConnection {
60    #[must_use]
61    pub fn pool(pool: sqlx::Pool<Postgres>) -> Self {
62        PGConnection::Pool(pool, Cache::new(TOTAL_CACHE_SIZE))
63    }
64
65    #[must_use]
66    pub fn cache(&self) -> &Cache<VersionId, Resource> {
67        match self {
68            PGConnection::Pool(_, cache) | PGConnection::Transaction(_, cache, _) => cache,
69        }
70    }
71}
72
73impl Repository for PGConnection {}