From 99389eefba1883753c15c6f411fb8543c93f58a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 10 Feb 2018 17:36:33 +0100 Subject: Always return the oldest matching messages from MAM, even if no date is set --- src/database/database.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 3622963..c43ace4 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -185,13 +185,36 @@ std::vector Database::get_muc_logs(const std::string& owne request << " and " << Database::Date{} << "<=" << end_time; } + if (limit >= 0) + request.limit() << limit; + + auto result = request.execute(*Database::db); + + return {result.cbegin(), result.cend()}; +} + +std::vector Database::get_muc_most_recent_logs(const std::string& owner, const std::string& chan_name, const std::string& server, + int limit, const std::string& start) +{ + auto request = Database::muc_log_lines.select(); + request.where() << Database::Owner{} << "=" << owner << \ + " and " << Database::IrcChanName{} << "=" << chan_name << \ + " and " << Database::IrcServerName{} << "=" << server; + + if (!start.empty()) + { + const auto start_time = utils::parse_datetime(start); + if (start_time != -1) + request << " and " << Database::Date{} << ">=" << start_time; + } + request.order_by() << Id{} << " DESC "; if (limit >= 0) request.limit() << limit; auto result = request.execute(*Database::db); - + return {result.crbegin(), result.crend()}; } -- cgit v1.2.3 From 0280343ced6c520700c3ca508e2d04c6b512d319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 10 Feb 2018 19:51:59 +0100 Subject: =?UTF-8?q?Handle=20the=20=E2=80=9Cafter=E2=80=9D=20RSM=20value=20?= =?UTF-8?q?to=20page=20through=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/database.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index c43ace4..2d6fbbd 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -165,7 +165,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str } std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end) + int limit, const std::string& start, const std::string& end, const Id::real_type after_id) { auto request = Database::muc_log_lines.select(); request.where() << Database::Owner{} << "=" << owner << \ @@ -184,6 +184,10 @@ std::vector Database::get_muc_logs(const std::string& owne if (end_time != -1) request << " and " << Database::Date{} << "<=" << end_time; } + if (after_id != Id::unset_value) + { + request << " and " << Id{} << ">" << after_id; + } if (limit >= 0) request.limit() << limit; @@ -218,6 +222,35 @@ std::vector Database::get_muc_most_recent_logs(const std:: return {result.crbegin(), result.crend()}; } +Database::MucLogLine Database::get_muc_log(const std::string& owner, const std::string& chan_name, const std::string& server, + const std::string& uuid, const std::string& start, const std::string& end) +{ + auto request = Database::muc_log_lines.select(); + request.where() << Database::Owner{} << "=" << owner << \ + " and " << Database::IrcChanName{} << "=" << chan_name << \ + " and " << Database::IrcServerName{} << "=" << server << \ + " and " << Database::Uuid{} << "=" << uuid; + + if (!start.empty()) + { + const auto start_time = utils::parse_datetime(start); + if (start_time != -1) + request << " and " << Database::Date{} << ">=" << start_time; + } + if (!end.empty()) + { + const auto end_time = utils::parse_datetime(end); + if (end_time != -1) + request << " and " << Database::Date{} << "<=" << end_time; + } + + auto result = request.execute(*Database::db); + + if (result.empty()) + throw Database::RecordNotFound{}; + return result.front(); +} + void Database::add_roster_item(const std::string& local, const std::string& remote) { auto roster_item = Database::roster.row(); -- cgit v1.2.3 From fd7c365288b9c4db1d441b553d42b26e81715b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 13 Feb 2018 03:10:00 +0100 Subject: Use the same function for both history orders --- src/database/database.cpp | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 2d6fbbd..2a63a6b 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -165,8 +165,11 @@ std::string Database::store_muc_message(const std::string& owner, const std::str } std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end, const Id::real_type after_id) + int limit, const std::string& start, const std::string& end, const Id::real_type after_id, Database::Paging paging) { + if (limit == 0) + return {}; + auto request = Database::muc_log_lines.select(); request.where() << Database::Owner{} << "=" << owner << \ " and " << Database::IrcChanName{} << "=" << chan_name << \ @@ -189,37 +192,20 @@ std::vector Database::get_muc_logs(const std::string& owne request << " and " << Id{} << ">" << after_id; } - if (limit >= 0) - request.limit() << limit; - - auto result = request.execute(*Database::db); - - return {result.cbegin(), result.cend()}; -} - -std::vector Database::get_muc_most_recent_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start) -{ - auto request = Database::muc_log_lines.select(); - request.where() << Database::Owner{} << "=" << owner << \ - " and " << Database::IrcChanName{} << "=" << chan_name << \ - " and " << Database::IrcServerName{} << "=" << server; - - if (!start.empty()) - { - const auto start_time = utils::parse_datetime(start); - if (start_time != -1) - request << " and " << Database::Date{} << ">=" << start_time; - } - - request.order_by() << Id{} << " DESC "; + if (paging == Database::Paging::first) + request.order_by() << Id{} << " ASC "; + else + request.order_by() << Id{} << " DESC "; if (limit >= 0) request.limit() << limit; auto result = request.execute(*Database::db); - - return {result.crbegin(), result.crend()}; + + if (paging == Database::Paging::first) + return result; + else + return {result.crbegin(), result.crend()}; } Database::MucLogLine Database::get_muc_log(const std::string& owner, const std::string& chan_name, const std::string& server, -- cgit v1.2.3 From 4a2a280d76e45e165d5c4657f4a46eebf71594bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 13 Feb 2018 03:51:03 +0100 Subject: Support the element in MAM requests --- src/database/database.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 2a63a6b..b2413d0 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -165,7 +165,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str } std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end, const Id::real_type after_id, Database::Paging paging) + int limit, const std::string& start, const std::string& end, const Id::real_type reference_record_id, Database::Paging paging) { if (limit == 0) return {}; @@ -187,15 +187,21 @@ std::vector Database::get_muc_logs(const std::string& owne if (end_time != -1) request << " and " << Database::Date{} << "<=" << end_time; } - if (after_id != Id::unset_value) + if (reference_record_id != Id::unset_value) { - request << " and " << Id{} << ">" << after_id; + request << " and " << Id{}; + if (paging == Database::Paging::first) + request << ">"; + else + request << "<"; + request << reference_record_id; } + request.order_by() << Id{}; if (paging == Database::Paging::first) - request.order_by() << Id{} << " ASC "; + request << " ASC "; else - request.order_by() << Id{} << " DESC "; + request << " DESC "; if (limit >= 0) request.limit() << limit; -- cgit v1.2.3 From d3e07eee1335822643d7086b95590b60a4e002c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 16 Feb 2018 00:56:07 +0100 Subject: Sort archive messages by date (and only then by id) fix #3337 Because apparently the IDs are not always incrementing. We still use them to know the order of two messages that were received at the same second (in this case, the ID will always be incrementing). --- src/database/database.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index b2413d0..d19ed7a 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -197,11 +197,10 @@ std::vector Database::get_muc_logs(const std::string& owne request << reference_record_id; } - request.order_by() << Id{}; if (paging == Database::Paging::first) - request << " ASC "; + request.order_by() << Database::Date{} << " ASC, " << Id{} << " ASC "; else - request << " DESC "; + request.order_by() << Database::Date{} << " DESC, " << Id{} << " DESC "; if (limit >= 0) request.limit() << limit; -- cgit v1.2.3 From 577984faf2befaa7f11a1e4a115dc8d80805fec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 18 Mar 2018 02:31:18 +0100 Subject: Allow the execution of multiple commands after the IRC connection fix #3275 --- src/database/database.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/database/database.cpp') 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::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::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(); + 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(); + 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() = server_options.col(); + 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(); -- cgit v1.2.3 From 5af0a8040c33d07dacf78343eb9ed0a03437a65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 18 Mar 2018 02:50:33 +0100 Subject: Use a transaction around the DELETE + INSERT of the after_connection_commands Otherwise we can imagine that two clients changing this value at the same time would mix things up. ref #3275 --- src/database/database.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 812d27c..b1525d5 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -106,6 +106,8 @@ void Database::set_after_connection_commands(const Database::IrcServerOptions& s const auto id = server_options.col(); if (id == Id::unset_value) return ; + + Transaction transaction; auto query = Database::after_connection_commands.del(); query.where() << ForeignKey{} << "=" << id; query.execute(*Database::db); @@ -330,4 +332,23 @@ std::string Database::gen_uuid() return uuid_str; } +Transaction::Transaction() +{ + const auto result = Database::raw_exec("BEGIN"); + if (std::get(result) == false) + log_error("Failed to create SQL transaction: ", std::get(result)); + else + this->success = true; + +} + +Transaction::~Transaction() +{ + if (this->success) + { + const auto result = Database::raw_exec("END"); + if (std::get(result) == false) + log_error("Failed to end SQL transaction: ", std::get(result)); + } +} #endif -- cgit v1.2.3 From 9500bfd4ccb21b261fd8204180d78553704f7acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 18 Mar 2018 19:33:07 +0100 Subject: Reflect message IDs in channel MUCs fix #3283 --- src/database/database.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index b1525d5..02c5b4f 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -2,9 +2,9 @@ #ifdef USE_DATABASE #include -#include #include #include +#include #include #include @@ -325,11 +325,7 @@ void Database::close() std::string Database::gen_uuid() { - char uuid_str[37]; - uuid_t uuid; - uuid_generate(uuid); - uuid_unparse(uuid, uuid_str); - return uuid_str; + return utils::gen_uuid(); } Transaction::Transaction() -- cgit v1.2.3 From 857c7d3972a03cbeebf730d99b924d3710dee6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 10 Apr 2018 23:33:59 +0200 Subject: Use a different Date data type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLEASE backup your database before testing this commit, and report any migration issue. In postgresql, we use timestamp with timezone. In sqlite3 we use REAL (the date is expressed as julianday) This requires a migration of the muclogline_ table: In postgresql it’s pretty simple, we convert all the integer into timestamps With sqlite3, we actually rename the table, create the new one with the correct type, then copy everything to the new table, with a conversion function for the Date_ column, and then we delete the old table. fix #3343 --- src/database/database.cpp | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 02c5b4f..7cb0a45 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -46,6 +46,7 @@ void Database::open(const std::string& filename) Database::db = std::move(new_db); Database::muc_log_lines.create(*Database::db); Database::muc_log_lines.upgrade(*Database::db); + convert_date_format(*Database::db, Database::muc_log_lines); Database::global_options.create(*Database::db); Database::global_options.upgrade(*Database::db); Database::irc_server_options.create(*Database::db); @@ -57,9 +58,9 @@ void Database::open(const std::string& filename) Database::after_connection_commands.create(*Database::db); Database::after_connection_commands.upgrade(*Database::db); create_index(*Database::db, "archive_index", Database::muc_log_lines.get_name()); + Database::db->init_session(); } - Database::GlobalOptions Database::get_global_options(const std::string& owner) { auto request = Database::global_options.select(); @@ -175,7 +176,7 @@ Database::IrcChannelOptions Database::get_irc_channel_options_with_server_and_gl } std::string Database::store_muc_message(const std::string& owner, const std::string& chan_name, - const std::string& server_name, Database::time_point date, + const std::string& server_name, DateTime::time_point date, const std::string& body, const std::string& nick) { auto line = Database::muc_log_lines.row(); @@ -186,7 +187,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str line.col() = owner; line.col() = chan_name; line.col() = server_name; - line.col() = std::chrono::duration_cast(date.time_since_epoch()).count(); + line.col() = date; line.col() = body; line.col() = nick; @@ -210,13 +211,21 @@ std::vector Database::get_muc_logs(const std::string& owne { const auto start_time = utils::parse_datetime(start); if (start_time != -1) - request << " and " << Database::Date{} << ">=" << start_time; + { + DateTime datetime(start_time); + DatetimeWriter writer(datetime, *Database::db); + request << " and " << Database::Date{} << ">=" << writer; + } } if (!end.empty()) { const auto end_time = utils::parse_datetime(end); if (end_time != -1) - request << " and " << Database::Date{} << "<=" << end_time; + { + DateTime datetime(end_time); + DatetimeWriter writer(datetime, *Database::db); + request << " and " << Database::Date{} << "<=" << writer; + } } if (reference_record_id != Id::unset_value) { @@ -229,9 +238,9 @@ std::vector Database::get_muc_logs(const std::string& owne } if (paging == Database::Paging::first) - request.order_by() << Database::Date{} << " ASC, " << Id{} << " ASC "; + request.order_by() << Database::Date{} << " ASC"; else - request.order_by() << Database::Date{} << " DESC, " << Id{} << " DESC "; + request.order_by() << Database::Date{} << " DESC"; if (limit >= 0) request.limit() << limit; @@ -257,13 +266,21 @@ Database::MucLogLine Database::get_muc_log(const std::string& owner, const std:: { const auto start_time = utils::parse_datetime(start); if (start_time != -1) - request << " and " << Database::Date{} << ">=" << start_time; + { + DateTime datetime(start_time); + DatetimeWriter writer(datetime, *Database::db); + request << " and " << Database::Date{} << ">=" << writer; + } } if (!end.empty()) { const auto end_time = utils::parse_datetime(end); if (end_time != -1) - request << " and " << Database::Date{} << "<=" << end_time; + { + DateTime datetime(end_time); + DatetimeWriter writer(datetime, *Database::db); + request << " and " << Database::Date{} << "<=" << writer; + } } auto result = request.execute(*Database::db); @@ -347,4 +364,12 @@ Transaction::~Transaction() log_error("Failed to end SQL transaction: ", std::get(result)); } } + +void Transaction::rollback() +{ + this->success = false; + const auto result = Database::raw_exec("ROLLBACK"); + if (std::get(result) == false) + log_error("Failed to rollback SQL transaction: ", std::get(result)); +} #endif -- cgit v1.2.3 From 4bd7b6981bb49dd4111c908aaa34c34f677171f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 13 Apr 2018 23:35:06 +0200 Subject: Refactor that fixes a compilation issue in Release mode Some template specialization were not found, because they were not declared at the point they were used. We moved things around, things are less inter-dependant, and also now it works. --- src/database/database.cpp | 57 +++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 7cb0a45..c935139 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -1,6 +1,8 @@ #include "biboumi.h" #ifdef USE_DATABASE +#include +#include #include #include #include @@ -63,32 +65,28 @@ void Database::open(const std::string& filename) Database::GlobalOptions Database::get_global_options(const std::string& owner) { - auto request = Database::global_options.select(); + auto request = select(Database::global_options); request.where() << Owner{} << "=" << owner; - Database::GlobalOptions options{Database::global_options.get_name()}; auto result = request.execute(*Database::db); if (result.size() == 1) - options = result.front(); - else - options.col() = owner; + return result.front(); + Database::GlobalOptions options{Database::global_options.get_name()}; + options.col() = owner; return options; } Database::IrcServerOptions Database::get_irc_server_options(const std::string& owner, const std::string& server) { - auto request = Database::irc_server_options.select(); + auto request = select(Database::irc_server_options); request.where() << Owner{} << "=" << owner << " and " << Server{} << "=" << server; - Database::IrcServerOptions options{Database::irc_server_options.get_name()}; auto result = request.execute(*Database::db); if (result.size() == 1) - options = result.front(); - else - { - options.col() = owner; - options.col() = server; - } + return result.front(); + Database::IrcServerOptions options{Database::irc_server_options.get_name()}; + options.col() = owner; + options.col() = server; return options; } @@ -97,7 +95,7 @@ Database::AfterConnectionCommands Database::get_after_connection_commands(const const auto id = server_options.col(); if (id == Id::unset_value) return {}; - auto request = Database::after_connection_commands.select(); + auto request = select(Database::after_connection_commands); request.where() << ForeignKey{} << "=" << id; return request.execute(*Database::db); } @@ -116,26 +114,23 @@ void Database::set_after_connection_commands(const Database::IrcServerOptions& s for (auto& command: commands) { command.col() = server_options.col(); - command.save(Database::db); + save(command, *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(); + auto request = select(Database::irc_channel_options); request.where() << Owner{} << "=" << owner <<\ " and " << Server{} << "=" << server <<\ " and " << Channel{} << "=" << channel; - Database::IrcChannelOptions options{Database::irc_channel_options.get_name()}; auto result = request.execute(*Database::db); if (result.size() == 1) - options = result.front(); - else - { - options.col() = owner; - options.col() = server; - options.col() = channel; - } + return result.front(); + Database::IrcChannelOptions options{Database::irc_channel_options.get_name()}; + options.col() = owner; + options.col() = server; + options.col() = channel; return options; } @@ -191,7 +186,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str line.col() = body; line.col() = nick; - line.save(Database::db); + save(line, *Database::db); return uuid; } @@ -202,7 +197,7 @@ std::vector Database::get_muc_logs(const std::string& owne if (limit == 0) return {}; - auto request = Database::muc_log_lines.select(); + auto request = select(Database::muc_log_lines); request.where() << Database::Owner{} << "=" << owner << \ " and " << Database::IrcChanName{} << "=" << chan_name << \ " and " << Database::IrcServerName{} << "=" << server; @@ -256,7 +251,7 @@ std::vector Database::get_muc_logs(const std::string& owne Database::MucLogLine Database::get_muc_log(const std::string& owner, const std::string& chan_name, const std::string& server, const std::string& uuid, const std::string& start, const std::string& end) { - auto request = Database::muc_log_lines.select(); + auto request = select(Database::muc_log_lines); request.where() << Database::Owner{} << "=" << owner << \ " and " << Database::IrcChanName{} << "=" << chan_name << \ " and " << Database::IrcServerName{} << "=" << server << \ @@ -297,7 +292,7 @@ void Database::add_roster_item(const std::string& local, const std::string& remo roster_item.col() = local; roster_item.col() = remote; - roster_item.save(Database::db); + save(roster_item, *Database::db); } void Database::delete_roster_item(const std::string& local, const std::string& remote) @@ -311,7 +306,7 @@ void Database::delete_roster_item(const std::string& local, const std::string& r bool Database::has_roster_item(const std::string& local, const std::string& remote) { - auto query = Database::roster.select(); + auto query = select(Database::roster); query.where() << Database::LocalJid{} << "=" << local << \ " and " << Database::RemoteJid{} << "=" << remote; @@ -322,7 +317,7 @@ bool Database::has_roster_item(const std::string& local, const std::string& remo std::vector Database::get_contact_list(const std::string& local) { - auto query = Database::roster.select(); + auto query = select(Database::roster); query.where() << Database::LocalJid{} << "=" << local; return query.execute(*Database::db); @@ -330,7 +325,7 @@ std::vector Database::get_contact_list(const std::string& std::vector Database::get_full_roster() { - auto query = Database::roster.select(); + auto query = select(Database::roster); return query.execute(*Database::db); } -- cgit v1.2.3 From 5ef7ba08028065b03d51d1dc70bb35aeb41ae19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 14 Apr 2018 19:48:45 +0200 Subject: Use the Date to find a next page in RSM, not the id This way, it works, whatever the order of insertion in the database was. fix #3343 --- src/database/database.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index c935139..fb24ad3 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -192,7 +192,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str } std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end, const Id::real_type reference_record_id, Database::Paging paging) + int limit, const std::string& start, const std::string& end, const std::string& reference_uuid, Database::Paging paging) { if (limit == 0) return {}; @@ -222,14 +222,15 @@ std::vector Database::get_muc_logs(const std::string& owne request << " and " << Database::Date{} << "<=" << writer; } } - if (reference_record_id != Id::unset_value) + if (!reference_uuid.empty()) { - request << " and " << Id{}; + request << " and " << Database::Date{}; if (paging == Database::Paging::first) request << ">"; else request << "<"; - request << reference_record_id; + request << "(SELECT " << Database::Date{} << " FROM " << Database::muc_log_lines.get_name().data() + << " WHERE " << Database::Uuid{} << " = " << reference_uuid << ")"; } if (paging == Database::Paging::first) -- cgit v1.2.3 From a90f196a1ce779d502baf0aadff6e6917fec8a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 24 Apr 2018 19:13:10 +0200 Subject: Revert "Use the Date to find a next page in RSM, not the id" This reverts commit 5ef7ba08028065b03d51d1dc70bb35aeb41ae19d. --- src/database/database.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index fb24ad3..c935139 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -192,7 +192,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str } std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end, const std::string& reference_uuid, Database::Paging paging) + int limit, const std::string& start, const std::string& end, const Id::real_type reference_record_id, Database::Paging paging) { if (limit == 0) return {}; @@ -222,15 +222,14 @@ std::vector Database::get_muc_logs(const std::string& owne request << " and " << Database::Date{} << "<=" << writer; } } - if (!reference_uuid.empty()) + if (reference_record_id != Id::unset_value) { - request << " and " << Database::Date{}; + request << " and " << Id{}; if (paging == Database::Paging::first) request << ">"; else request << "<"; - request << "(SELECT " << Database::Date{} << " FROM " << Database::muc_log_lines.get_name().data() - << " WHERE " << Database::Uuid{} << " = " << reference_uuid << ")"; + request << reference_record_id; } if (paging == Database::Paging::first) -- cgit v1.2.3 From 61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 24 Apr 2018 19:19:06 +0200 Subject: Revert "Use a different Date data type" This reverts commit 857c7d3972a03cbeebf730d99b924d3710dee6a0. --- src/database/database.cpp | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index c935139..a09dfe3 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -48,7 +48,6 @@ void Database::open(const std::string& filename) Database::db = std::move(new_db); Database::muc_log_lines.create(*Database::db); Database::muc_log_lines.upgrade(*Database::db); - convert_date_format(*Database::db, Database::muc_log_lines); Database::global_options.create(*Database::db); Database::global_options.upgrade(*Database::db); Database::irc_server_options.create(*Database::db); @@ -60,9 +59,9 @@ void Database::open(const std::string& filename) Database::after_connection_commands.create(*Database::db); Database::after_connection_commands.upgrade(*Database::db); create_index(*Database::db, "archive_index", Database::muc_log_lines.get_name()); - Database::db->init_session(); } + Database::GlobalOptions Database::get_global_options(const std::string& owner) { auto request = select(Database::global_options); @@ -171,7 +170,7 @@ Database::IrcChannelOptions Database::get_irc_channel_options_with_server_and_gl } std::string Database::store_muc_message(const std::string& owner, const std::string& chan_name, - const std::string& server_name, DateTime::time_point date, + const std::string& server_name, Database::time_point date, const std::string& body, const std::string& nick) { auto line = Database::muc_log_lines.row(); @@ -182,7 +181,7 @@ std::string Database::store_muc_message(const std::string& owner, const std::str line.col() = owner; line.col() = chan_name; line.col() = server_name; - line.col() = date; + line.col() = std::chrono::duration_cast(date.time_since_epoch()).count(); line.col() = body; line.col() = nick; @@ -206,21 +205,13 @@ std::vector Database::get_muc_logs(const std::string& owne { const auto start_time = utils::parse_datetime(start); if (start_time != -1) - { - DateTime datetime(start_time); - DatetimeWriter writer(datetime, *Database::db); - request << " and " << Database::Date{} << ">=" << writer; - } + request << " and " << Database::Date{} << ">=" << start_time; } if (!end.empty()) { const auto end_time = utils::parse_datetime(end); if (end_time != -1) - { - DateTime datetime(end_time); - DatetimeWriter writer(datetime, *Database::db); - request << " and " << Database::Date{} << "<=" << writer; - } + request << " and " << Database::Date{} << "<=" << end_time; } if (reference_record_id != Id::unset_value) { @@ -233,9 +224,9 @@ std::vector Database::get_muc_logs(const std::string& owne } if (paging == Database::Paging::first) - request.order_by() << Database::Date{} << " ASC"; + request.order_by() << Database::Date{} << " ASC, " << Id{} << " ASC "; else - request.order_by() << Database::Date{} << " DESC"; + request.order_by() << Database::Date{} << " DESC, " << Id{} << " DESC "; if (limit >= 0) request.limit() << limit; @@ -261,21 +252,13 @@ Database::MucLogLine Database::get_muc_log(const std::string& owner, const std:: { const auto start_time = utils::parse_datetime(start); if (start_time != -1) - { - DateTime datetime(start_time); - DatetimeWriter writer(datetime, *Database::db); - request << " and " << Database::Date{} << ">=" << writer; - } + request << " and " << Database::Date{} << ">=" << start_time; } if (!end.empty()) { const auto end_time = utils::parse_datetime(end); if (end_time != -1) - { - DateTime datetime(end_time); - DatetimeWriter writer(datetime, *Database::db); - request << " and " << Database::Date{} << "<=" << writer; - } + request << " and " << Database::Date{} << "<=" << end_time; } auto result = request.execute(*Database::db); @@ -359,12 +342,4 @@ Transaction::~Transaction() log_error("Failed to end SQL transaction: ", std::get(result)); } } - -void Transaction::rollback() -{ - this->success = false; - const auto result = Database::raw_exec("ROLLBACK"); - if (std::get(result) == false) - log_error("Failed to rollback SQL transaction: ", std::get(result)); -} #endif -- cgit v1.2.3 From 1236b8a03bee403fcaa59d882d8e7fb9058b2280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 24 Apr 2018 20:24:58 +0200 Subject: Only use the ID to order archives fix #3343 --- src/database/database.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index a09dfe3..3b3e890 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -224,9 +224,9 @@ std::vector Database::get_muc_logs(const std::string& owne } if (paging == Database::Paging::first) - request.order_by() << Database::Date{} << " ASC, " << Id{} << " ASC "; + request.order_by() << Id{} << " ASC "; else - request.order_by() << Database::Date{} << " DESC, " << Id{} << " DESC "; + request.order_by() << Id{} << " DESC "; if (limit >= 0) request.limit() << limit; -- cgit v1.2.3 From b0168fd45b3683c2d6f61ccae67dcd5b918a363d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 29 Apr 2018 22:18:26 +0200 Subject: =?UTF-8?q?mam:=20Send=20=E2=80=9Cfin=20complete=E2=80=9D=20only?= =?UTF-8?q?=20when=20appropriate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also simplify how we did the whole “limit + 1” And fix one bad interpretation of the XEP for the case where the query has no after or before restriction. fix #3349 --- src/database/database.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 3b3e890..6e08ee1 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -190,12 +190,9 @@ std::string Database::store_muc_message(const std::string& owner, const std::str return uuid; } -std::vector Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, - int limit, const std::string& start, const std::string& end, const Id::real_type reference_record_id, Database::Paging paging) +std::tuple> Database::get_muc_logs(const std::string& owner, const std::string& chan_name, const std::string& server, + std::size_t limit, const std::string& start, const std::string& end, const Id::real_type reference_record_id, Database::Paging paging) { - if (limit == 0) - return {}; - auto request = select(Database::muc_log_lines); request.where() << Database::Owner{} << "=" << owner << \ " and " << Database::IrcChanName{} << "=" << chan_name << \ @@ -228,15 +225,26 @@ std::vector Database::get_muc_logs(const std::string& owne else request.order_by() << Id{} << " DESC "; - if (limit >= 0) - request.limit() << limit; + // Just a simple trick: to know whether we got the totality of the + // possible results matching this query (except for the limit), we just + // ask one more element. If we get that additional element, this means + // we don’t have everything. And then we just discard it. If we don’t + // have more, this means we have everything. + request.limit() << limit + 1; auto result = request.execute(*Database::db); + bool complete = true; + + if (result.size() == limit + 1) + { + complete = false; + result.erase(std::prev(result.end())); + } if (paging == Database::Paging::first) - return result; + return {complete, result}; else - return {result.crbegin(), result.crend()}; + return {complete, {result.crbegin(), result.crend()}}; } Database::MucLogLine Database::get_muc_log(const std::string& owner, const std::string& chan_name, const std::string& server, -- cgit v1.2.3 From 458ea53db3edc7318e88a2612baa793a1232cc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 3 Jul 2018 20:15:36 +0200 Subject: Fix a compile error with GCC 5.x fix #3366 --- src/database/database.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 6e08ee1..4867f52 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -242,9 +242,9 @@ std::tuple> Database::get_muc_logs(const } if (paging == Database::Paging::first) - return {complete, result}; + return std::make_tuple(complete, result); else - return {complete, {result.crbegin(), result.crend()}}; + return std::make_tuple(complete, std::vector(result.crbegin(), result.crend())); } Database::MucLogLine Database::get_muc_log(const std::string& owner, const std::string& chan_name, const std::string& server, -- cgit v1.2.3 From 782732ba167470fa99ab3d0900c02295b4684b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 4 Aug 2018 14:50:33 +0200 Subject: Remove a bunch of useless empty lines --- src/database/database.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 4867f52..3578c04 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -338,7 +338,6 @@ Transaction::Transaction() log_error("Failed to create SQL transaction: ", std::get(result)); else this->success = true; - } Transaction::~Transaction() -- cgit v1.2.3 From 0b51e3828116f6847865fae93893eb97a10d1cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 23 Aug 2018 20:30:11 +0200 Subject: MaxHistoryLength now has some sensible default value if the user set a negative one --- src/database/database.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/database/database.cpp') diff --git a/src/database/database.cpp b/src/database/database.cpp index 3578c04..9037ce1 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -162,10 +162,6 @@ Database::IrcChannelOptions Database::get_irc_channel_options_with_server_and_gl coptions.col() = get_first_non_empty(coptions.col(), soptions.col()); - coptions.col() = get_first_non_empty(coptions.col(), - soptions.col(), - goptions.col()); - return coptions; } -- cgit v1.2.3