diff --git a/Cargo.toml b/Cargo.toml index 1cec6f9..4c6a570 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "manifold" -version = "4.0.0" +version = "5.0.0" authors = ["Lucy Bladen "] edition = "2021" @@ -16,7 +16,7 @@ chrono-tz = "0.8.3" clap = "4.3.4" config = { version = "0.13.1", features = [ "yaml" ] } d20 = "0.1.0" -diesel = { version = "2.1.0", features = ["sqlite", "r2d2", "chrono"] } +diesel = { version = "2.1.0", features = ["postgres", "r2d2", "chrono"] } diesel_migrations = "2.1.0" dirs = "5.0.1" env_logger = "0.10.0" diff --git a/src/commands/admin.rs b/src/commands/admin.rs index eb26025..19dcdb9 100644 --- a/src/commands/admin.rs +++ b/src/commands/admin.rs @@ -38,7 +38,7 @@ async fn save_world(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { Ok(_) => debug!("User {:?} inserted successfully", user.0), Err(e) => { debug!("User {:?} was not inserted: {:?}, attempting to save instead", user.1, e); - match user.1.save(db) { + match user.1.insert(db) { Ok(_) => debug!("User {:?} saved successfully, user is saved in database.", user.0), Err(e) => debug!("User {:?} could not be saved: {:?}", user.1, e), }; diff --git a/src/commands/weather.rs b/src/commands/weather.rs index 7b47f17..dc994e9 100644 --- a/src/commands/weather.rs +++ b/src/commands/weather.rs @@ -62,7 +62,7 @@ pub async fn save_weather_location(ctx: ManifoldContext<'_>, #[rest] #[descripti if let Some(existing_user) = userinfo.get_mut(&ctx.author().id.as_u64()) { existing_user.weather_location = Some(location.clone()); - existing_user.save(db)?; + existing_user.insert(db)?; } else { let new_user = UserInfo { user_id: ctx.author().id.as_u64().clone() as i64, diff --git a/src/config.rs b/src/config.rs index c36255e..d182a4c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,12 +10,22 @@ pub struct Channels { pub log: ChannelId, } +#[derive(Debug, Deserialize, Serialize)] +pub struct DatabaseConfig { + pub host: String, + pub user: String, + pub pass: String, + pub database_name: String, + pub port: i32, +} + #[derive(Debug, Deserialize, Serialize)] pub struct ManifoldConfig { pub prefix: String, pub channels: Channels, pub nickname: String, pub services: HashMap, + pub database: DatabaseConfig, pub responses_file_path: PathBuf, } diff --git a/src/events.rs b/src/events.rs index 42d9e21..c174fc3 100644 --- a/src/events.rs +++ b/src/events.rs @@ -208,9 +208,11 @@ impl Handler { async fn message(_ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message) -> ManifoldResult<()> { let userinfo = &mut fctx.user_data().await.user_info.lock().await; + let db = &fctx.user_data().await.database; if let Some(u) = userinfo.get_mut(&msg.author.id.as_u64()) { u.last_seen = Some(chrono::Utc::now().timestamp()); + u.insert(db)?; } else { let new_user = UserInfo { user_id: msg.author.id.as_u64().clone() as i64, @@ -221,6 +223,7 @@ impl Handler { last_seen: Some(chrono::Utc::now().timestamp()), }; + new_user.insert(db)?; userinfo.insert(msg.author.id.as_u64().clone(), new_user); } diff --git a/src/lib.rs b/src/lib.rs index 2c545a9..9225eba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,16 +7,16 @@ use std::path::PathBuf; use std::sync::Arc; use clap::ArgMatches; +use diesel::pg::Pg; use diesel::r2d2::ConnectionManager; -use diesel::sqlite::Sqlite; -use diesel::SqliteConnection; +use diesel::PgConnection; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use poise::framework::FrameworkBuilder; use poise::serenity_prelude::*; use crate::config::ManifoldConfig; use crate::error::{ManifoldError, ManifoldResult}; -use crate::events::EventHandler; +use crate::events::{EventHandler, Handler}; use crate::models::user::{ManifoldUserInfo, UserInfo}; use crate::responses::Responses; @@ -36,7 +36,7 @@ pub mod built_info { include!(concat!(env!("OUT_DIR"), "/built.rs")); } -pub type ManifoldDatabasePool = r2d2::Pool>; +pub type ManifoldDatabasePool = r2d2::Pool>; pub struct Db { pub pool: ManifoldDatabasePool, @@ -79,7 +79,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: Gat debug!("Configuration file path: {}", &config_file); let bot_config = ManifoldConfig::new(&config_file, bot_environment).expect(&*format!("Could not read configuration file {}", &config_file)); - let manager = ConnectionManager::::new("manifold.db"); + let manager = ConnectionManager::::new(format!("postgresql://{user}:{pass}@{host}:{port}/{database}", user=&bot_config.database.user, pass=&bot_config.database.pass, host=&bot_config.database.host, port=&bot_config.database.port, database=&bot_config.database.database_name)); let pool = r2d2::Pool::builder() .max_size(1) .build(manager) @@ -95,6 +95,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: Gat let framework = poise::Framework::builder() .options(poise::FrameworkOptions { event_handler: |ctx, e, fctx, _| Box::pin(async move { + _ = Handler::listen(ctx, fctx, e).await; T::listen(ctx, fctx, e).await }), pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move { @@ -133,7 +134,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: Gat Ok(framework) } -fn apply_migrations(conn: &mut impl MigrationHarness, caller_migrations: EmbeddedMigrations) { +fn apply_migrations(conn: &mut impl MigrationHarness, caller_migrations: EmbeddedMigrations) { conn.run_pending_migrations(MIGRATIONS) .expect("An error occurred applying migrations."); diff --git a/src/models/user.rs b/src/models/user.rs index eb6e84d..35b4a83 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -1,6 +1,6 @@ use diesel::prelude::*; use std::collections::HashMap; -use diesel::{insert_into, update}; +use diesel::insert_into; use crate::schema::*; use crate::schema::userinfo::dsl as userinfo_dsl; @@ -48,15 +48,11 @@ impl UserInfo { pub fn insert(&self, conn: &Db) -> ManifoldResult { insert_into(userinfo_dsl::userinfo) .values(self) - .execute(&mut conn.get()?) - .map_err(|e| ManifoldError::from(e)) - } - - pub fn save(&self, conn: &Db) -> ManifoldResult { - update(userinfo_dsl::userinfo) - .filter(userinfo::user_id.eq(self.user_id)) + .on_conflict(userinfo_dsl::user_id) + .do_update() .set(self) .execute(&mut conn.get()?) .map_err(|e| ManifoldError::from(e)) } + }