90 lines
2.8 KiB
Rust
90 lines
2.8 KiB
Rust
|
|
use chrono::{DateTime, Utc};
|
||
|
|
use serde::{Deserialize, Serialize};
|
||
|
|
use sqlx::{FromRow, PgPool};
|
||
|
|
use uuid::Uuid;
|
||
|
|
|
||
|
|
#[derive(Debug, Serialize, Deserialize, FromRow)]
|
||
|
|
pub struct PhotographerProfile {
|
||
|
|
pub id: Uuid,
|
||
|
|
pub user_id: Uuid,
|
||
|
|
pub portfolio_url: Option<String>,
|
||
|
|
pub equipment_list: Option<String>,
|
||
|
|
pub years_of_experience: Option<i32>,
|
||
|
|
pub hourly_rate: Option<sqlx::types::BigDecimal>,
|
||
|
|
pub specialties: Option<Vec<String>>,
|
||
|
|
pub created_at: DateTime<Utc>,
|
||
|
|
pub updated_at: DateTime<Utc>,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
|
pub struct UpsertPhotographerProfilePayload {
|
||
|
|
pub portfolio_url: Option<String>,
|
||
|
|
pub equipment_list: Option<String>,
|
||
|
|
pub years_of_experience: Option<i32>,
|
||
|
|
pub hourly_rate: Option<f64>,
|
||
|
|
pub specialties: Option<Vec<String>>,
|
||
|
|
}
|
||
|
|
|
||
|
|
pub struct PhotographerRepository;
|
||
|
|
|
||
|
|
impl PhotographerRepository {
|
||
|
|
pub async fn get_by_user_id(
|
||
|
|
pool: &PgPool,
|
||
|
|
user_id: Uuid,
|
||
|
|
) -> Result<Option<PhotographerProfile>, sqlx::Error> {
|
||
|
|
let profile = sqlx::query_as!(
|
||
|
|
PhotographerProfile,
|
||
|
|
r#"
|
||
|
|
SELECT
|
||
|
|
id, user_id, portfolio_url, equipment_list, years_of_experience,
|
||
|
|
hourly_rate, specialties, created_at, updated_at
|
||
|
|
FROM photographer_profiles
|
||
|
|
WHERE user_id = $1
|
||
|
|
"#,
|
||
|
|
user_id
|
||
|
|
)
|
||
|
|
.fetch_optional(pool)
|
||
|
|
.await?;
|
||
|
|
|
||
|
|
Ok(profile)
|
||
|
|
}
|
||
|
|
|
||
|
|
pub async fn upsert(
|
||
|
|
pool: &PgPool,
|
||
|
|
user_id: Uuid,
|
||
|
|
payload: UpsertPhotographerProfilePayload,
|
||
|
|
) -> Result<PhotographerProfile, sqlx::Error> {
|
||
|
|
let hourly_rate_bd = payload.hourly_rate.map(|v| sqlx::types::BigDecimal::try_from(v).unwrap_or_default());
|
||
|
|
|
||
|
|
let profile = sqlx::query_as!(
|
||
|
|
PhotographerProfile,
|
||
|
|
r#"
|
||
|
|
INSERT INTO photographer_profiles (
|
||
|
|
user_id, portfolio_url, equipment_list, years_of_experience, hourly_rate, specialties
|
||
|
|
)
|
||
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||
|
|
ON CONFLICT (user_id) DO UPDATE SET
|
||
|
|
portfolio_url = EXCLUDED.portfolio_url,
|
||
|
|
equipment_list = EXCLUDED.equipment_list,
|
||
|
|
years_of_experience = EXCLUDED.years_of_experience,
|
||
|
|
hourly_rate = EXCLUDED.hourly_rate,
|
||
|
|
specialties = EXCLUDED.specialties,
|
||
|
|
updated_at = NOW()
|
||
|
|
RETURNING
|
||
|
|
id, user_id, portfolio_url, equipment_list, years_of_experience,
|
||
|
|
hourly_rate, specialties, created_at, updated_at
|
||
|
|
"#,
|
||
|
|
user_id,
|
||
|
|
payload.portfolio_url,
|
||
|
|
payload.equipment_list,
|
||
|
|
payload.years_of_experience,
|
||
|
|
hourly_rate_bd,
|
||
|
|
payload.specialties.as_deref()
|
||
|
|
)
|
||
|
|
.fetch_one(pool)
|
||
|
|
.await?;
|
||
|
|
|
||
|
|
Ok(profile)
|
||
|
|
}
|
||
|
|
}
|