Compare commits

...

2 Commits

7 changed files with 28 additions and 18 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "manifold" name = "manifold"
version = "4.0.0" version = "5.0.0"
authors = ["Lucy Bladen <admin@lbladen.uk>"] authors = ["Lucy Bladen <admin@lbladen.uk>"]
edition = "2021" edition = "2021"
@ -16,7 +16,7 @@ chrono-tz = "0.8.3"
clap = "4.3.4" clap = "4.3.4"
config = { version = "0.13.1", features = [ "yaml" ] } config = { version = "0.13.1", features = [ "yaml" ] }
d20 = "0.1.0" 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" diesel_migrations = "2.1.0"
dirs = "5.0.1" dirs = "5.0.1"
env_logger = "0.10.0" env_logger = "0.10.0"

View File

@ -38,7 +38,7 @@ async fn save_world(ctx: ManifoldContext<'_>) -> ManifoldResult<()> {
Ok(_) => debug!("User {:?} inserted successfully", user.0), Ok(_) => debug!("User {:?} inserted successfully", user.0),
Err(e) => { Err(e) => {
debug!("User {:?} was not inserted: {:?}, attempting to save instead", user.1, 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), Ok(_) => debug!("User {:?} saved successfully, user is saved in database.", user.0),
Err(e) => debug!("User {:?} could not be saved: {:?}", user.1, e), Err(e) => debug!("User {:?} could not be saved: {:?}", user.1, e),
}; };

View File

@ -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()) { if let Some(existing_user) = userinfo.get_mut(&ctx.author().id.as_u64()) {
existing_user.weather_location = Some(location.clone()); existing_user.weather_location = Some(location.clone());
existing_user.save(db)?; existing_user.insert(db)?;
} else { } else {
let new_user = UserInfo { let new_user = UserInfo {
user_id: ctx.author().id.as_u64().clone() as i64, user_id: ctx.author().id.as_u64().clone() as i64,

View File

@ -10,12 +10,22 @@ pub struct Channels {
pub log: ChannelId, 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)] #[derive(Debug, Deserialize, Serialize)]
pub struct ManifoldConfig { pub struct ManifoldConfig {
pub prefix: String, pub prefix: String,
pub channels: Channels, pub channels: Channels,
pub nickname: String, pub nickname: String,
pub services: HashMap<String, FuelTank>, pub services: HashMap<String, FuelTank>,
pub database: DatabaseConfig,
pub responses_file_path: PathBuf, pub responses_file_path: PathBuf,
} }

View File

@ -208,9 +208,11 @@ impl Handler {
async fn message(_ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message) -> ManifoldResult<()> { async fn message(_ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message) -> ManifoldResult<()> {
let userinfo = &mut fctx.user_data().await.user_info.lock().await; 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()) { if let Some(u) = userinfo.get_mut(&msg.author.id.as_u64()) {
u.last_seen = Some(chrono::Utc::now().timestamp()); u.last_seen = Some(chrono::Utc::now().timestamp());
u.insert(db)?;
} else { } else {
let new_user = UserInfo { let new_user = UserInfo {
user_id: msg.author.id.as_u64().clone() as i64, user_id: msg.author.id.as_u64().clone() as i64,
@ -221,6 +223,7 @@ impl Handler {
last_seen: Some(chrono::Utc::now().timestamp()), last_seen: Some(chrono::Utc::now().timestamp()),
}; };
new_user.insert(db)?;
userinfo.insert(msg.author.id.as_u64().clone(), new_user); userinfo.insert(msg.author.id.as_u64().clone(), new_user);
} }

View File

@ -7,16 +7,16 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use clap::ArgMatches; use clap::ArgMatches;
use diesel::pg::Pg;
use diesel::r2d2::ConnectionManager; use diesel::r2d2::ConnectionManager;
use diesel::sqlite::Sqlite; use diesel::PgConnection;
use diesel::SqliteConnection;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use poise::framework::FrameworkBuilder; use poise::framework::FrameworkBuilder;
use poise::serenity_prelude::*; use poise::serenity_prelude::*;
use crate::config::ManifoldConfig; use crate::config::ManifoldConfig;
use crate::error::{ManifoldError, ManifoldResult}; use crate::error::{ManifoldError, ManifoldResult};
use crate::events::EventHandler; use crate::events::{EventHandler, Handler};
use crate::models::user::{ManifoldUserInfo, UserInfo}; use crate::models::user::{ManifoldUserInfo, UserInfo};
use crate::responses::Responses; use crate::responses::Responses;
@ -36,7 +36,7 @@ pub mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs")); include!(concat!(env!("OUT_DIR"), "/built.rs"));
} }
pub type ManifoldDatabasePool = r2d2::Pool<ConnectionManager<SqliteConnection>>; pub type ManifoldDatabasePool = r2d2::Pool<ConnectionManager<PgConnection>>;
pub struct Db { pub struct Db {
pub pool: ManifoldDatabasePool, pub pool: ManifoldDatabasePool,
@ -79,7 +79,7 @@ pub async fn prepare_client<T: EventHandler>(arguments: ArgMatches, intents: Gat
debug!("Configuration file path: {}", &config_file); 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 bot_config = ManifoldConfig::new(&config_file, bot_environment).expect(&*format!("Could not read configuration file {}", &config_file));
let manager = ConnectionManager::<SqliteConnection>::new("manifold.db"); let manager = ConnectionManager::<PgConnection>::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() let pool = r2d2::Pool::builder()
.max_size(1) .max_size(1)
.build(manager) .build(manager)
@ -95,6 +95,7 @@ pub async fn prepare_client<T: EventHandler>(arguments: ArgMatches, intents: Gat
let framework = poise::Framework::builder() let framework = poise::Framework::builder()
.options(poise::FrameworkOptions { .options(poise::FrameworkOptions {
event_handler: |ctx, e, fctx, _| Box::pin(async move { event_handler: |ctx, e, fctx, _| Box::pin(async move {
_ = Handler::listen(ctx, fctx, e).await;
T::listen(ctx, fctx, e).await T::listen(ctx, fctx, e).await
}), }),
pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move { pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move {
@ -133,7 +134,7 @@ pub async fn prepare_client<T: EventHandler>(arguments: ArgMatches, intents: Gat
Ok(framework) Ok(framework)
} }
fn apply_migrations(conn: &mut impl MigrationHarness<Sqlite>, caller_migrations: EmbeddedMigrations) { fn apply_migrations(conn: &mut impl MigrationHarness<Pg>, caller_migrations: EmbeddedMigrations) {
conn.run_pending_migrations(MIGRATIONS) conn.run_pending_migrations(MIGRATIONS)
.expect("An error occurred applying migrations."); .expect("An error occurred applying migrations.");

View File

@ -1,6 +1,6 @@
use diesel::prelude::*; use diesel::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use diesel::{insert_into, update}; use diesel::insert_into;
use crate::schema::*; use crate::schema::*;
use crate::schema::userinfo::dsl as userinfo_dsl; use crate::schema::userinfo::dsl as userinfo_dsl;
@ -48,15 +48,11 @@ impl UserInfo {
pub fn insert(&self, conn: &Db) -> ManifoldResult<usize> { pub fn insert(&self, conn: &Db) -> ManifoldResult<usize> {
insert_into(userinfo_dsl::userinfo) insert_into(userinfo_dsl::userinfo)
.values(self) .values(self)
.execute(&mut conn.get()?) .on_conflict(userinfo_dsl::user_id)
.map_err(|e| ManifoldError::from(e)) .do_update()
}
pub fn save(&self, conn: &Db) -> ManifoldResult<usize> {
update(userinfo_dsl::userinfo)
.filter(userinfo::user_id.eq(self.user_id))
.set(self) .set(self)
.execute(&mut conn.get()?) .execute(&mut conn.get()?)
.map_err(|e| ManifoldError::from(e)) .map_err(|e| ManifoldError::from(e))
} }
} }