Lines
100 %
Functions
80 %
Branches
use crate::config::{ConfigError, ConfigOption, config_on, set_config_on};
use crate::db::DBError;
use cfg_if::cfg_if;
use sqlx::types::Uuid;
// `userpool` is the production per-user routing path. Its DB-facing half is
// excluded from server's own `cfg(test)` runs (see the module docs), where
// `get_connection` below short-circuits to the injected test pool; the
// bookkeeping half compiles always so it can be tested.
mod connection;
mod userpool;
pub use connection::TenantConnection;
pub struct User {
pub id: Uuid,
}
impl User {
cfg_if! {
if #[cfg(test)] {
pub async fn get_connection(&self) -> Result<TenantConnection, DBError> {
crate::db::get_connection().await.map(TenantConnection::global)
} else if #[cfg(feature = "test-utils")] {
if crate::db::test_pool_is_set() {
} else {
userpool::get_connection(self.id).await
/// Reads a config field from THIS user's database. Per-user config is
/// isolated to the user's own DB (distinct from server-wide
/// [`crate::config::system_config`]).
///
/// # Errors
/// [`ConfigError::DB`] on a connection or query error.
pub async fn config(&self, field: &str) -> Result<Option<ConfigOption>, ConfigError> {
let mut conn = self.get_connection().await.map_err(|_| ConfigError::DB)?;
config_on(&mut conn, field).await
/// Writes a config field to THIS user's database.
pub async fn set_config(&self, field: &str, contents: ConfigOption) -> Result<(), ConfigError> {
set_config_on(&mut conn, field, contents).await
#[cfg(test)]
/// `verified = TRUE`: the fixture is a usable account.
pub async fn commit(&self) -> Result<(), sqlx::Error> {
let mut conn = self.get_connection().await.unwrap();
sqlx::query!(
"INSERT INTO users (
id, user_name, email, photo, verified, user_password, user_role, database_name, created_at
) VALUES (
$1, 'Test User', 'test@example.com', 'default.png',
TRUE, 'password123', 'user', 'database', NOW()
)",
self.id,
)
.execute(&mut *conn)
.await?;
Ok(())