databeam/
sql.rs

1//! Shared SQL types
2use serde::{Serialize, Deserialize};
3
4#[derive(Serialize, Deserialize, Debug, Clone)]
5pub struct DatabaseOpts {
6    /// The type of the database
7    pub r#type: Option<String>,
8    /// The host to connect to (`None` for SQLite)
9    pub host: Option<String>,
10    /// The database user's name
11    pub user: String,
12    /// The database user's password
13    pub pass: String,
14    /// The name of the database
15    #[serde(default = "default_database_name")]
16    pub name: String,
17}
18
19fn default_database_name() -> String {
20    "main".to_string()
21}
22
23impl Default for DatabaseOpts {
24    fn default() -> Self {
25        Self {
26            r#type: Some("sqlite".to_string()),
27            host: None,
28            user: String::new(),
29            pass: String::new(),
30            name: default_database_name(),
31        }
32    }
33}
34
35// ...
36#[derive(Clone)]
37pub struct Database<T> {
38    pub client: T,
39    pub r#type: String,
40}
41
42// ...
43#[cfg(feature = "mysql")]
44/// Create a new "mysql" database
45pub async fn create_db(options: DatabaseOpts) -> Database<sqlx::MySqlPool> {
46    // mysql
47    let opts = sqlx::mysql::MySqlPoolOptions::new()
48        .max_connections(25)
49        .acquire_timeout(std::time::Duration::from_millis(2000))
50        .idle_timeout(Some(std::time::Duration::from_secs(60 * 5)));
51
52    let client = opts
53        .connect(&format!(
54            "mysql://{}:{}@{}/{}",
55            options.user,
56            options.pass,
57            if options.host.is_some() {
58                options.host.unwrap()
59            } else {
60                "localhost".to_string()
61            },
62            options.name
63        ))
64        .await;
65
66    if client.is_err() {
67        panic!("failed to connect to database: {}", client.err().unwrap());
68    }
69
70    return Database {
71        client: client.unwrap(),
72        r#type: String::from("mysql"),
73    };
74}
75
76#[cfg(feature = "postgres")]
77/// Create a new "postgres" database
78pub async fn create_db(options: DatabaseOpts) -> Database<sqlx::PgPool> {
79    // postgres
80    let opts = sqlx::postgres::PgPoolOptions::new()
81        .max_connections(25)
82        .acquire_timeout(std::time::Duration::from_millis(2000))
83        .idle_timeout(Some(std::time::Duration::from_secs(60 * 5)));
84
85    let client = opts
86        .connect(&format!(
87            "postgres://{}:{}@{}/{}",
88            options.user,
89            options.pass,
90            if options.host.is_some() {
91                options.host.unwrap()
92            } else {
93                "localhost".to_string()
94            },
95            options.name
96        ))
97        .await;
98
99    if client.is_err() {
100        panic!("failed to connect to database: {}", client.err().unwrap());
101    }
102
103    return Database {
104        client: client.unwrap(),
105        r#type: String::from("postgres"),
106    };
107}
108
109#[cfg(feature = "sqlite")]
110/// Create a new "sqlite" database (named "main.db")
111pub async fn create_db(options: DatabaseOpts) -> Database<sqlx::SqlitePool> {
112    // sqlite
113    let client = sqlx::SqlitePool::connect(&format!("sqlite://{}.db", options.name)).await;
114
115    if client.is_err() {
116        panic!("Failed to connect to database!");
117    }
118
119    Database {
120        client: client.unwrap(),
121        r#type: String::from("sqlite"),
122    }
123}