summaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2018-03-18 02:31:18 +0100
committerlouiz’ <louiz@louiz.org>2018-03-18 02:31:18 +0100
commit577984faf2befaa7f11a1e4a115dc8d80805fec7 (patch)
treedb65417e4dc37123841309f9c9ee8d375bf9e003 /src/database
parentad7aa5b7090f093a8a167a3fcb29c421881946f7 (diff)
downloadbiboumi-577984faf2befaa7f11a1e4a115dc8d80805fec7.tar.gz
biboumi-577984faf2befaa7f11a1e4a115dc8d80805fec7.tar.bz2
biboumi-577984faf2befaa7f11a1e4a115dc8d80805fec7.tar.xz
biboumi-577984faf2befaa7f11a1e4a115dc8d80805fec7.zip
Allow the execution of multiple commands after the IRC connection
fix #3275
Diffstat (limited to 'src/database')
-rw-r--r--src/database/column.hpp4
-rw-r--r--src/database/database.cpp29
-rw-r--r--src/database/database.hpp10
-rw-r--r--src/database/delete_query.hpp33
-rw-r--r--src/database/table.hpp7
5 files changed, 82 insertions, 1 deletions
diff --git a/src/database/column.hpp b/src/database/column.hpp
index 9367701..50c9c14 100644
--- a/src/database/column.hpp
+++ b/src/database/column.hpp
@@ -13,6 +13,10 @@ struct Column
T value{};
};
+struct ForeignKey: Column<std::size_t> {
+ static constexpr auto name = "fk_";
+};
+
struct Id: Column<std::size_t> {
static constexpr std::size_t unset_value = static_cast<std::size_t>(-1);
static constexpr auto name = "id_";
diff --git a/src/database/database.cpp b/src/database/database.cpp
index d19ed7a..812d27c 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -21,6 +21,7 @@ Database::GlobalOptionsTable Database::global_options("globaloptions_");
Database::IrcServerOptionsTable Database::irc_server_options("ircserveroptions_");
Database::IrcChannelOptionsTable Database::irc_channel_options("ircchanneloptions_");
Database::RosterTable Database::roster("roster");
+Database::AfterConnectionCommandsTable Database::after_connection_commands("after_connection_commands_");
std::map<Database::CacheKey, Database::EncodingIn::real_type> Database::encoding_in_cache{};
Database::GlobalPersistent::GlobalPersistent():
@@ -53,6 +54,8 @@ void Database::open(const std::string& filename)
Database::irc_channel_options.upgrade(*Database::db);
Database::roster.create(*Database::db);
Database::roster.upgrade(*Database::db);
+ Database::after_connection_commands.create(*Database::db);
+ Database::after_connection_commands.upgrade(*Database::db);
create_index<Database::Owner, Database::IrcChanName, Database::IrcServerName>(*Database::db, "archive_index", Database::muc_log_lines.get_name());
}
@@ -88,6 +91,32 @@ Database::IrcServerOptions Database::get_irc_server_options(const std::string& o
return options;
}
+Database::AfterConnectionCommands Database::get_after_connection_commands(const IrcServerOptions& server_options)
+{
+ const auto id = server_options.col<Id>();
+ if (id == Id::unset_value)
+ return {};
+ auto request = Database::after_connection_commands.select();
+ request.where() << ForeignKey{} << "=" << id;
+ return request.execute(*Database::db);
+}
+
+void Database::set_after_connection_commands(const Database::IrcServerOptions& server_options, Database::AfterConnectionCommands& commands)
+{
+ const auto id = server_options.col<Id>();
+ if (id == Id::unset_value)
+ return ;
+ auto query = Database::after_connection_commands.del();
+ query.where() << ForeignKey{} << "=" << id;
+ query.execute(*Database::db);
+
+ for (auto& command: commands)
+ {
+ command.col<ForeignKey>() = server_options.col<Id>();
+ command.save(Database::db);
+ }
+}
+
Database::IrcChannelOptions Database::get_irc_channel_options(const std::string& owner, const std::string& server, const std::string& channel)
{
auto request = Database::irc_channel_options.select();
diff --git a/src/database/database.hpp b/src/database/database.hpp
index 8a967d8..0e88be8 100644
--- a/src/database/database.hpp
+++ b/src/database/database.hpp
@@ -92,7 +92,7 @@ class Database
using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
using GlobalOptions = GlobalOptionsTable::RowType;
- using IrcServerOptionsTable = Table<Id, Owner, Server, Pass, AfterConnectionCommand, TlsPorts, Ports, Username, Realname, VerifyCert, TrustedFingerprint, EncodingOut, EncodingIn, MaxHistoryLength, Address>;
+ using IrcServerOptionsTable = Table<Id, Owner, Server, Pass, TlsPorts, Ports, Username, Realname, VerifyCert, TrustedFingerprint, EncodingOut, EncodingIn, MaxHistoryLength, Address>;
using IrcServerOptions = IrcServerOptionsTable::RowType;
using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent, RecordHistoryOptional>;
@@ -101,6 +101,9 @@ class Database
using RosterTable = Table<LocalJid, RemoteJid>;
using RosterItem = RosterTable::RowType;
+ using AfterConnectionCommandsTable = Table<Id, ForeignKey, AfterConnectionCommand>;
+ using AfterConnectionCommands = std::vector<AfterConnectionCommandsTable::RowType>;
+
Database() = default;
~Database() = default;
@@ -121,6 +124,9 @@ class Database
static IrcChannelOptions get_irc_channel_options_with_server_and_global_default(const std::string& owner,
const std::string& server,
const std::string& channel);
+ static AfterConnectionCommands get_after_connection_commands(const IrcServerOptions& server_options);
+ static void set_after_connection_commands(const IrcServerOptions& server_options, AfterConnectionCommands& commands);
+
/**
* Get all the lines between (optional) start and end dates, with a (optional) limit.
* If after_id is set, only the records after it will be returned.
@@ -158,6 +164,8 @@ class Database
static IrcServerOptionsTable irc_server_options;
static IrcChannelOptionsTable irc_channel_options;
static RosterTable roster;
+ static AfterConnectionCommandsTable after_connection_commands;
+
static std::unique_ptr<DatabaseEngine> db;
/**
diff --git a/src/database/delete_query.hpp b/src/database/delete_query.hpp
new file mode 100644
index 0000000..dce705b
--- /dev/null
+++ b/src/database/delete_query.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <database/query.hpp>
+#include <database/engine.hpp>
+
+class DeleteQuery: public Query
+{
+public:
+ DeleteQuery(const std::string& name):
+ Query("DELETE")
+ {
+ this->body += " from " + name;
+ }
+
+ DeleteQuery& where()
+ {
+ this->body += " WHERE ";
+ return *this;
+ };
+
+ void execute(DatabaseEngine& db)
+ {
+ auto statement = db.prepare(this->body);
+ if (!statement)
+ return;
+#ifdef DEBUG_SQL_QUERIES
+ const auto timer = this->log_and_time();
+#endif
+ statement->bind(std::move(this->params));
+ if (statement->step() != StepResult::Done)
+ log_error("Failed to execute DELETE command");
+ }
+};
diff --git a/src/database/table.hpp b/src/database/table.hpp
index 680e7cc..c8c1bdd 100644
--- a/src/database/table.hpp
+++ b/src/database/table.hpp
@@ -3,6 +3,7 @@
#include <database/engine.hpp>
#include <database/select_query.hpp>
+#include <database/delete_query.hpp>
#include <database/row.hpp>
#include <algorithm>
@@ -85,6 +86,12 @@ class Table
return select;
}
+ auto del()
+ {
+ DeleteQuery query(this->name);
+ return query;
+ }
+
const std::string& get_name() const
{
return this->name;