aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2023-04-06 17:14:22 -0400
committerCara Salter <cara@devcara.com>2023-04-06 17:14:22 -0400
commit555810bedc0cf9d9d954f56b5a2c8c92522ad27f (patch)
tree0dd37a701fb242fa953c23f2b0a94252fa60762b
parent3a3a1e5345ae8e133fa7800d9fcba2dbb779b8b9 (diff)
parent7629de5b888bd3d1cdb94dce3ba51cb1e1c2e625 (diff)
download142bot-555810bedc0cf9d9d954f56b5a2c8c92522ad27f.tar.gz
142bot-555810bedc0cf9d9d954f56b5a2c8c92522ad27f.zip
Merge branch 'database'
Change-Id: I5f6fb3b64db0585955defdec0fe1ee9555ba89ec
-rw-r--r--CMakeLists.txt6
-rw-r--r--include/142bot/bot.hpp7
-rw-r--r--include/142bot/db.hpp37
-rw-r--r--migrations/0001-init.sql7
-rw-r--r--src/bot.cpp51
-rw-r--r--src/db.cpp76
-rw-r--r--src/main.cpp2
7 files changed, 182 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ac2947..f26e300 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,12 +33,16 @@ find_package(fmt)
string(ASCII 27 Esc)
+find_library(PQXX_LIB pqxx)
+find_library(PQ_LIB pq)
+
include(GNUInstallDirs)
aux_source_directory("src" coresrc)
add_executable(142bot ${coresrc})
include_directories("include")
-target_link_libraries(142bot PRIVATE clog dpp fmt::fmt spdlog::spdlog pcre cpr::cpr)
+target_link_libraries(142bot PRIVATE clog dpp fmt::fmt spdlog::spdlog pcre
+ cpr::cpr ${PQXX_LIB} ${PQ_LIB})
add_dependencies(142bot clog dpp cpr fmt spdlog)
install(TARGETS 142bot)
diff --git a/include/142bot/bot.hpp b/include/142bot/bot.hpp
index 49aa956..a422416 100644
--- a/include/142bot/bot.hpp
+++ b/include/142bot/bot.hpp
@@ -1,6 +1,7 @@
#include <dpp/snowflake.h>
#include <dpp/user.h>
#include <dpp/dpp.h>
+#include <pqxx/pqxx>
#ifndef BOT_HPP
@@ -8,9 +9,11 @@
class Module;
class ModuleLoader;
class Bot {
+ pqxx::connection conn;
bool dev;
dpp::snowflake owner_id;
-
+private:
+ bool run_database_migrations();
public:
class dpp::cluster * core;
/* The bot's user from the ready event */
@@ -18,7 +21,7 @@ public:
Bot(bool development, dpp::cluster* cluster);
//virtual ~Bot();
-
+
void set_owner_id(dpp::snowflake id);
dpp::snowflake get_owner_id();
diff --git a/include/142bot/db.hpp b/include/142bot/db.hpp
new file mode 100644
index 0000000..69245d3
--- /dev/null
+++ b/include/142bot/db.hpp
@@ -0,0 +1,37 @@
+/*
+ * =====================================================================================
+ *
+ * Filename: db.hpp
+ *
+ * Description:
+ *
+ * Version: 1.0
+ * Created: 04/06/2023 11:38:35 AM
+ * Revision: none
+ * Compiler: gcc
+ *
+ * Author: Cara Salter (muirrum), cara@devcara.com
+ * Organization: Worcester Polytechnic Institute
+ *
+ * =====================================================================================
+ */
+
+#pragma once
+#include <vector>
+#include <map>
+#include <string>
+#include <variant>
+#include <pqxx/pqxx>
+
+
+namespace db {
+ typedef std::map<std::string, std::string> row;
+ typedef std::vector<row> resultset;
+
+ typedef std::vector<std::variant<float, std::string, uint64_t, int64_t, bool, int32_t, uint32_t, double>> paramlist;
+
+ pqxx::connection connect(const std::string &host, const std::string &user, const std::string &pass, const std::string &db, int port);
+ bool close();
+ resultset query(const std::string &format, const paramlist &parameters);
+ const std::string& error();
+}
diff --git a/migrations/0001-init.sql b/migrations/0001-init.sql
new file mode 100644
index 0000000..7a00ff0
--- /dev/null
+++ b/migrations/0001-init.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS spotify (
+ id SERIAL PRIMARY KEY,
+ spotify_username TEXT NOT NULL,
+ spotify_token TEXT NOT NULL,
+ spotify_token_expires TIMESTAMP NOT NULL,
+ spotify_refresh_token TEXT NOT NULL
+); \ No newline at end of file
diff --git a/src/bot.cpp b/src/bot.cpp
index 03bea02..ad818a0 100644
--- a/src/bot.cpp
+++ b/src/bot.cpp
@@ -1,21 +1,72 @@
#include <dpp/snowflake.h>
#include <stdlib.h>
+#include <string>
#include <142bot/bot.hpp>
#include <dpp/dpp.h>
#include <142bot/modules.hpp>
#include <142bot/util.hpp>
#include <fmt/format.h>
#include <fmt/format-inl.h>
+#include <pqxx/pqxx>
+#include <142bot/db.hpp>
+#include <filesystem>
+
+namespace fs = std::filesystem;
Bot::Bot(bool devel, dpp::cluster* cluster) {
dev = devel;
this->core = cluster;
+
+ std::ifstream f("config.json");
+ json cfg = json::parse(f);
+ std::string token = cfg.value("token", "bad-token");
+
+ this->conn = db::connect(cfg["postgres"]["host"], cfg["postgres"]["user"], cfg["postgres"]["pass"], cfg["postgres"]["database"], cfg["postgres"]["port"]);
+
+ run_database_migrations();
+
this->loader = new ModuleLoader(this);
this->loader->load_all();
// this->loader->LoadAll();
}
+/**
+ * Attempts to run migrations stored in a directory local to CWD.
+ *
+ * Returns false on any error
+*/
+bool Bot::run_database_migrations() {
+
+ // Start a transaction
+ this->core->log(dpp::ll_info, "Attempting database migrations...");
+ pqxx::work w(this->conn);
+ // Get all files in ./migrations
+ std::string path = "./migrations";
+ for (const auto &entry : fs::directory_iterator(path)) {
+ std::ifstream f(entry.path());
+ std::ostringstream sstr;
+ sstr << f.rdbuf();
+ std::string stmt = sstr.str();
+
+ this->core->log(dpp::ll_debug, fmt::format("Attempting to migrate database with statement {}", stmt));
+
+ try {
+ w.exec0(stmt);
+ } catch (std::exception &e) {
+ w.abort();
+ this->core->log(dpp::ll_error, e.what());
+ return false;
+ }
+
+ }
+
+ w.commit();
+ this->core->log(dpp::ll_info, "Done.");
+
+ return true;
+}
+
bool Bot::isDevMode() {
return dev;
}
diff --git a/src/db.cpp b/src/db.cpp
new file mode 100644
index 0000000..92e3d1d
--- /dev/null
+++ b/src/db.cpp
@@ -0,0 +1,76 @@
+/*
+ * =====================================================================================
+ *
+ * Filename: db.cpp
+ *
+ * Description: Connection to a postgres database
+ *
+ * Version: 1.0
+ * Created: 04/06/2023 11:40:39 AM
+ * Revision: none
+ * Compiler: gcc
+ *
+ * Author: Cara Salter (muirrum), cara@devcara.com
+ * Organization: Worcester Polytechnic Institute
+ *
+ * =====================================================================================
+ */
+#include <fmt/core.h>
+#include <mutex>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <142bot/db.hpp>
+#include <pqxx/pqxx>
+#include <fmt/format.h>
+#include <cstdarg>
+
+using namespace std;
+
+namespace db {
+ std::mutex db_mutex;
+ std::string _error;
+
+ /**
+ * Connects to a postgres database, returns false if error
+ **/
+ pqxx::connection connect(const std::string &host, const std::string &user, const std::string &pass, const std::string &db, int port) {
+ std::lock_guard<std::mutex> db_lock(db_mutex);
+
+ std::string cn_s = "postgresql://";
+
+ if (!user.empty()) {
+ cn_s = cn_s + user;
+ }
+ if (!pass.empty() && !user.empty()) {
+ cn_s = cn_s + ":" + pass;
+ }
+
+ if ((!user.empty() || !pass.empty())) {
+ cn_s = cn_s + "@";
+ }
+
+ if (!host.empty()) {
+ cn_s = cn_s + "localhost";
+ }
+ if (port != 0 && !host.empty()) {
+ cn_s = cn_s + ":" + std::to_string(port);
+ }
+ if (!db.empty()) {
+ cn_s = cn_s + "/" + db;
+ }
+
+ try {
+ pqxx::connection c{cn_s};
+ return c;
+ } catch (std::exception const &e) {
+ _error = e.what();
+ throw e;
+ }
+ }
+
+ const std::string& error() {
+ return _error;
+ }
+
+}
diff --git a/src/main.cpp b/src/main.cpp
index 8f3ad9a..f54e418 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include <dpp/dpp.h>
#include <dpp/json.h>
#include <142bot/bot.hpp>
+#include <142bot/db.hpp>
#include <spdlog/spdlog.h>
#include <spdlog/async.h>
@@ -17,7 +18,6 @@ int main(int argc, char const *argv[]) {
std::ifstream f("config.json");
json cfg = json::parse(f);
string token = cfg.value("token", "bad-token");
-
dpp::cluster bot(token, dpp::intents::i_all_intents);
std::shared_ptr<spdlog::logger> log;