ouverture_core/
database.rs

1pub mod setup;
2
3use pg_embed::pg_enums::PgAuthMethod;
4use pg_embed::pg_errors::PgEmbedError;
5use pg_embed::pg_fetch::{PgFetchSettings, PG_V13};
6use pg_embed::postgres::{PgEmbed, PgSettings};
7use platform_dirs::AppDirs;
8use std::error::Error;
9use std::path::PathBuf;
10use std::time::Duration;
11use tokio::net::TcpListener;
12
13use crate::config::Config;
14use crate::music::song::*;
15use log::{debug, info};
16
17use color_eyre::eyre::eyre;
18use color_eyre::Result;
19use sea_orm::entity::prelude::*;
20use sea_orm::{entity::*, query::*};
21use sea_orm::{Database, DatabaseConnection};
22
23pub async fn setup_db(config: Config) -> Result<PgEmbed> {
24    std::fs::create_dir_all(config.database_dir.clone())?;
25    let pg_settings = PgSettings {
26        // Where to store the postgresql database
27        database_dir: PathBuf::from(config.database_dir),
28        port: config.database_port as i16,
29        user: "ouverture".to_string(),
30        password: "ouverture".to_string(),
31
32        // authentication method
33        auth_method: PgAuthMethod::Plain,
34        // If persistent is false clean up files and directories on drop, otherwise keep them
35        persistent: true,
36        // duration to wait before terminating process execution
37        // pg_ctl start/stop and initdb timeout
38        // if set to None the process will not be terminated
39        timeout: Some(Duration::from_secs(15)),
40        // If migration sql scripts need to be run, the directory containing those scripts can be
41        // specified here with `Some(PathBuf(path_to_dir)), otherwise `None` to run no migrations.
42        // To enable migrations view the **Usage** section for details
43        migration_dir: None,
44    };
45
46    let fetch_settings = PgFetchSettings {
47        version: PG_V13,
48        ..Default::default()
49    };
50
51    let mut pg = PgEmbed::new(pg_settings, fetch_settings)
52        .await
53        .map_err(|e| eyre!(e.to_string()))?;
54
55    // Download, unpack, create password file and database cluster
56    pg.setup().await.map_err(|e| eyre!(e.to_string()))?;
57
58    Ok(pg)
59}
60
61pub async fn start_db(pg: &mut PgEmbed, config: Config) -> Result<()> {
62    pg.start_db().await.map_err(|e| eyre!(e.to_string()))?;
63
64    // First time setup
65    if !pg
66        .database_exists("ouverture")
67        .await
68        .map_err(|e| eyre!(e.to_string()))?
69    {
70        pg.create_database("ouverture")
71            .await
72            .map_err(|e| eyre!(e.to_string()))?;
73        info!("empty database created");
74
75        let database_url = "postgres://ouverture:ouverture@localhost:".to_string()
76            + &config.database_port.to_string()
77            + "/ouverture";
78
79        let conn = Database::connect(&database_url).await?;
80        let _ = setup::create_post_table(&conn).await;
81    }
82
83    Ok(())
84}
85
86pub async fn add_db(config: &Config, song: Song) -> Result<()> {
87    let database_url = "postgres://ouverture:ouverture@localhost:".to_string()
88        + &config.database_port.to_string()
89        + "/ouverture";
90    let db = Database::connect(&database_url).await.unwrap();
91    debug!("Adding song {song:?}");
92    setup::ActiveModel::from(song).insert(&db).await?;
93    debug!("Song added to db successfully!");
94    Ok(())
95}
96
97pub async fn test_db(config: Config) {
98    let database_url = "postgres://ouverture:ouverture@localhost:".to_string()
99        + &config.database_port.to_string()
100        + "/ouverture";
101    let db = Database::connect(&database_url).await.unwrap();
102    debug!("test DB connection established");
103    let test_song = setup::ActiveModel {
104        title: Set(Some("test title".to_owned())),
105        ..Default::default()
106    };
107
108    let res = test_song.insert(&db).await.unwrap();
109    debug!("insert result : {:?}", res);
110
111    let song_found: Option<setup::Model> = setup::Entity::find_by_id(1).one(&db).await.unwrap();
112    debug!("song found: {:?}", song_found);
113}