/ backend / src / db / mod.rs
mod.rs
 1  use crate::util::accounts_error::{AccountsError, AccountsResult};
 2  use sqlx::{Pool, Postgres, Transaction};
 3  
 4  pub mod account_repository;
 5  pub mod activation_code_repository;
 6  pub mod client_scope_repository;
 7  pub mod login_details_repository;
 8  pub mod login_provider_repository;
 9  pub mod oauth_client_repository;
10  pub mod reset_password_repository;
11  pub mod third_party_login_repository;
12  pub mod user_client_consent_repository;
13  pub mod user_client_consented_scope_repository;
14  pub mod whitelist_repository;
15  
16  use crate::models::login_provider::LOCAL_LOGIN_PROVIDER;
17  
18  pub type DB = Postgres;
19  // The query would violate the UNIQUE sql constraint
20  pub const DB_ERR_VIOLATE_UNIQUE: &str = "23505";
21  
22  // Initial setup of the database
23  pub async fn init(pool: &Pool<DB>) -> AccountsResult<()> {
24      match sqlx::query_as!(
25          LoginProvider,
26          "
27  INSERT INTO login_provider(name)
28  VALUES                    ($1)
29      ",
30          LOCAL_LOGIN_PROVIDER
31      )
32      .execute(pool)
33      .await
34      {
35          Ok(_) => Ok(()),
36          Err(sqlx::Error::Database(err)) => {
37              if let Some(code) = err.code() {
38                  if code == DB_ERR_VIOLATE_UNIQUE {
39                      // The 'local' login provider already exists
40                      return Ok(());
41                  }
42              }
43              Err(AccountsError::SqlxError(sqlx::Error::Database(err)))
44          }
45          Err(err) => Err(AccountsError::SqlxError(err)),
46      }
47  }
48  
49  pub async fn new_transaction(db_pool: &Pool<DB>) -> AccountsResult<Transaction<'_, DB>> {
50      match db_pool.begin().await {
51          Ok(transaction) => Ok(transaction),
52          Err(err) => {
53              error!("Failed to create transaction: {:?}", err);
54              Err(AccountsError::SqlxError(err))
55          }
56      }
57  }