echoes/backend/src/database/relational/postgresql/mod.rs

90 lines
2.4 KiB
Rust
Raw Normal View History

// src/database/relational/postgresql/mod.rs
/*
* PostgreSQL数据库的交互功能
*
*/
use super::{DatabaseTrait, QueryBuilder};
use crate::config;
use async_trait::async_trait;
use sqlx::{Column, PgPool, Row};
2024-11-11 01:38:58 +08:00
use std::{collections::HashMap, error::Error};
2024-11-11 01:38:58 +08:00
#[derive(Clone)]
/// PostgreSQL数据库连接池结构体
pub struct Postgresql {
/// 数据库连接池
2024-11-11 01:38:58 +08:00
pool: PgPool,
}
#[async_trait]
impl DatabaseTrait for Postgresql {
/**
* PostgreSQL数据库并返回Postgresql实例
*
* #
* - `db_config`:
*
* #
* - `Result<Self, Box<dyn Error>>`:
*/
async fn connect(db_config: config::SqlConfig) -> Result<Self, Box<dyn Error>> {
2024-11-11 01:38:58 +08:00
let connection_str = format!(
"postgres://{}:{}@{}:{}/{}",
db_config.user, db_config.password, db_config.address, db_config.prot, db_config.db_name
2024-11-11 01:38:58 +08:00
);
// 连接到数据库池
2024-11-11 01:38:58 +08:00
let pool = PgPool::connect(&connection_str)
.await
.map_err(|e| Box::new(e) as Box<dyn Error>)?;
// 返回Postgresql实例
2024-11-11 01:38:58 +08:00
Ok(Postgresql { pool })
}
/**
*
*
* #
* - `builder`:
*
* #
* - `Result<Vec<HashMap<String, String>>, Box<dyn Error + 'a>>`:
*/
async fn execute_query<'a>(
&'a self,
builder: &QueryBuilder,
) -> Result<Vec<HashMap<String, String>>, Box<dyn Error + 'a>> {
let (query, values) = builder.build();
// 构建查询
let mut sqlx_query = sqlx::query(&query);
// 绑定参数
for value in values {
sqlx_query = sqlx_query.bind(value);
}
// 执行查询
let rows = sqlx_query
2024-11-11 01:38:58 +08:00
.fetch_all(&self.pool)
.await
.map_err(|e| Box::new(e) as Box<dyn Error>)?;
// 处理结果
2024-11-11 01:38:58 +08:00
let mut results = Vec::new();
for row in rows {
let mut map = HashMap::new();
for column in row.columns() {
let value: String = row.try_get(column.name()).unwrap_or_default();
map.insert(column.name().to_string(), value);
}
results.push(map);
}
2024-11-11 01:38:58 +08:00
Ok(results)
}
}