luna_orm/database/
postgres.rs1use 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}