luna_orm/database/
postgres.rs

1use crate::database::lib::Database;
2use crate::database::lib::DatabaseType;
3use crate::database::DB;
4use crate::{error::LunaOrmError, LunaOrmResult};
5
6use sqlx::any::AnyConnectOptions;
7use sqlx::AnyPool;
8
9use crate::command_executor::CommandExecutor;
10use crate::sql_executor::SqlExecutor;
11use crate::sql_generator::PostgresGenerator;
12use crate::sql_generator::SqlGenerator;
13use luna_orm_trait::Entity;
14use luna_orm_trait::LastRowId;
15use std::str::FromStr;
16use tracing::debug;
17
18#[derive(Debug)]
19pub struct PostgresDatabase {
20    database_type: DatabaseType,
21    pool: AnyPool,
22    sql_generator: PostgresGenerator,
23}
24
25impl SqlExecutor for PostgresDatabase {
26    fn get_pool(&self) -> LunaOrmResult<&AnyPool> {
27        Ok(&self.pool)
28    }
29}
30
31impl CommandExecutor for PostgresDatabase {
32    type G = PostgresGenerator;
33
34    fn get_generator(&self) -> &Self::G {
35        &self.sql_generator
36    }
37
38    async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult<bool> {
39        debug!(target: "luna_orm", command = "create",  entity = ?entity);
40        let sql = self.get_generator().get_create_sql(entity);
41        debug!(target: "luna_orm", command = "create", sql = sql);
42        let args = entity.any_arguments_of_insert();
43        if entity.get_auto_increment_field().is_some() {
44            let last_row_id: LastRowId = self.fetch_one(&sql, args).await?;
45            entity.set_auto_increment_field(Some(last_row_id.id));
46        } else {
47            self.execute(&sql, args).await?;
48        }
49        debug!(target: "luna_orm", command = "create", result = ?entity);
50        return Ok(true);
51    }
52}
53
54impl Database for PostgresDatabase {
55    fn get_type(&self) -> &DatabaseType {
56        &self.database_type
57    }
58}
59
60impl From<PostgresDatabase> for DB<PostgresDatabase> {
61    fn from(value: PostgresDatabase) -> Self {
62        Self(value)
63    }
64}
65
66impl PostgresDatabase {
67    pub async fn build(url: &str, user: &str, password: &str) -> LunaOrmResult<Self> {
68        let url = format!("postgres://{}:{}@{}", user, password, url);
69
70        let any_options = AnyConnectOptions::from_str(&url).unwrap();
71        let pool = AnyPool::connect_with(any_options)
72            .await
73            .map_err(|_e| LunaOrmError::DatabaseInitFail("init pool fail".to_string()))?;
74
75        let generator = PostgresGenerator::new();
76        let database = PostgresDatabase {
77            database_type: DatabaseType::MySql,
78            pool,
79            sql_generator: generator,
80        };
81        Ok(database)
82    }
83}