use crate::domain::{
official::Official,
term::{Branch, GovernmentLevel, Term},
};
use crate::error::DbError;
use sqlx::PgPool;
use uuid::Uuid;
pub fn build_pgsql_url(host: &str, port: i32, user: &str, password: &str, db: &str) -> String {
format!("postgres://{user}:{password}@{host}:{port}/{db}")
}
pub async fn insert_official(url: &str, person: Official) -> Result<(), DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
sqlx::query(
"INSERT INTO officials (birth, birth_sources, first_name, first_name_sources, id, is_in_office, last_name, last_name_sources, middle_name, middle_name_sources) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"
)
.bind(person.birth)
.bind(person.birth_sources)
.bind(person.first_name)
.bind(person.first_name_sources)
.bind(person.id)
.bind(person.is_in_office)
.bind(person.last_name)
.bind(person.last_name_sources)
.bind(person.middle_name)
.bind(person.middle_name_sources)
.execute(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::InsertError(e.to_string()))?;
Ok(())
}
pub async fn select_officials(url: &str) -> Result<Vec<Official>, DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
let officials: Vec<Official> = sqlx::query_as!(Official, "SELECT * FROM officials")
.fetch_all(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::SelectError(e.to_string()))?;
Ok(officials)
}
pub async fn insert_term(url: &str, term: Term) -> Result<(), DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
sqlx::query(
"INSERT INTO terms (branch, branch_sources, end_date, end_date_sources, level, level_sources, location, location_sources, office_title, office_title_sources, parent_id, political_party, political_party_sources, session_number, session_number_sources, start_date, start_date_sources) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"
)
.bind(term.branch)
.bind(term.branch_sources)
.bind(term.end_date)
.bind(term.end_date_sources)
.bind(term.level)
.bind(term.level_sources)
.bind(term.location)
.bind(term.location_sources)
.bind(term.office_title)
.bind(term.office_title_sources)
.bind(term.parent_id)
.bind(term.political_party)
.bind(term.political_party_sources)
.bind(term.session_number)
.bind(term.session_number_sources)
.bind(term.start_date)
.bind(term.start_date_sources)
.execute(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::InsertError(e.to_string()))?;
Ok(())
}
pub async fn select_all_terms(url: &str) -> Result<Vec<Term>, DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
let terms: Vec<Term> = sqlx::query_as!(
Term,
r#"
SELECT
branch AS "branch!: Branch",
branch_sources,
end_date,
end_date_sources,
id,
level AS "level!: GovernmentLevel",
level_sources,
location,
location_sources,
office_title,
office_title_sources,
parent_id,
political_party,
political_party_sources,
session_number,
session_number_sources,
start_date,
start_date_sources
FROM terms
"#
)
.fetch_all(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::SelectError(e.to_string()))?;
Ok(terms)
}
pub async fn select_terms_by_official_id(
url: &str,
official_id: Uuid,
) -> Result<Vec<Term>, DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
let terms: Vec<Term> = sqlx::query_as!(
Term,
r#"
SELECT
branch AS "branch!: Branch",
branch_sources,
end_date,
end_date_sources,
id,
level AS "level!: GovernmentLevel",
level_sources,
location,
location_sources,
office_title,
office_title_sources,
parent_id,
political_party,
political_party_sources,
session_number,
session_number_sources,
start_date,
start_date_sources
FROM terms
WHERE parent_id = $1
"#,
official_id
)
.fetch_all(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::SelectError(e.to_string()))?;
Ok(terms)
}
pub async fn select_official_most_recent_term(
url: &str,
official_id: Uuid,
) -> Result<Term, DbError> {
let connection_pool = PgPool::connect(url)
.await
.map_err(|e: sqlx::Error| DbError::ConnectError(e.to_string()))?;
let term: Term = sqlx::query_as!(
Term,
r#"
SELECT
branch AS "branch!: Branch",
branch_sources,
end_date,
end_date_sources,
id,
level AS "level!: GovernmentLevel",
level_sources,
location,
location_sources,
office_title,
office_title_sources,
parent_id,
political_party,
political_party_sources,
session_number,
session_number_sources,
start_date,
start_date_sources
FROM terms
WHERE parent_id = $1
ORDER BY start_date DESC
LIMIT 1
"#,
official_id
)
.fetch_one(&connection_pool)
.await
.map_err(|e: sqlx::Error| DbError::SelectError(e.to_string()))?;
Ok(term)
}