diff options
author | louiz’ <louiz@louiz.org> | 2018-04-24 19:19:06 +0200 |
---|---|---|
committer | louiz’ <louiz@louiz.org> | 2018-04-24 20:25:40 +0200 |
commit | 61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24 (patch) | |
tree | f1da873798506627587ef7cdce23062d556b454a | |
parent | a90f196a1ce779d502baf0aadff6e6917fec8a02 (diff) | |
download | biboumi-61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24.tar.gz biboumi-61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24.tar.bz2 biboumi-61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24.tar.xz biboumi-61de6b1dac4ef29627f3bdb9ce11b6c0d06f4a24.zip |
Revert "Use a different Date data type"
This reverts commit 857c7d3972a03cbeebf730d99b924d3710dee6a0.
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | src/bridge/bridge.cpp | 4 | ||||
-rw-r--r-- | src/database/database.cpp | 43 | ||||
-rw-r--r-- | src/database/database.hpp | 30 | ||||
-rw-r--r-- | src/database/datetime_writer.hpp | 32 | ||||
-rw-r--r-- | src/database/engine.hpp | 18 | ||||
-rw-r--r-- | src/database/insert_query.cpp | 21 | ||||
-rw-r--r-- | src/database/insert_query.hpp | 22 | ||||
-rw-r--r-- | src/database/postgresql_engine.cpp | 44 | ||||
-rw-r--r-- | src/database/postgresql_engine.hpp | 13 | ||||
-rw-r--r-- | src/database/query.cpp | 16 | ||||
-rw-r--r-- | src/database/query.hpp | 10 | ||||
-rw-r--r-- | src/database/select_query.cpp | 21 | ||||
-rw-r--r-- | src/database/select_query.hpp | 31 | ||||
-rw-r--r-- | src/database/sqlite3_engine.cpp | 68 | ||||
-rw-r--r-- | src/database/sqlite3_engine.hpp | 11 | ||||
-rw-r--r-- | src/database/table.hpp | 8 | ||||
-rw-r--r-- | src/utils/datetime.hpp | 56 | ||||
-rw-r--r-- | src/xmpp/biboumi_component.cpp | 2 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.cpp | 4 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.hpp | 3 | ||||
-rw-r--r-- | tests/end_to_end/__main__.py | 2 |
22 files changed, 46 insertions, 415 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dfb909a..432248b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,8 +1,6 @@ Version 8.0 =========== -- Changed the data type used to store the dates in the database. This - requires an automatic migration on the first start. - Add a complete='true' in MAM’s iq result when appropriate - The “virtual” channel with an empty name (for example %irc.freenode.net@biboumi) has been entirely removed. diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index defb9a5..1c646fe 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -1009,9 +1009,9 @@ void Bridge::send_room_history(const std::string& hostname, std::string chan_nam chan_name.append(utils::empty_if_fixed_server("%" + hostname)); for (const auto& line: lines) { - const DateTime& datetime = line.col<Database::Date>(); + const auto seconds = line.col<Database::Date>(); this->xmpp.send_history_message(chan_name, line.col<Database::Nick>(), line.col<Database::Body>(), - this->user_jid + "/" + resource, datetime); + this->user_jid + "/" + resource, seconds); } #else (void)hostname; 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::Owner, Database::IrcChanName, Database::IrcServerName>(*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>() = owner; line.col<IrcChanName>() = chan_name; line.col<IrcServerName>() = server_name; - line.col<Date>() = date; + line.col<Date>() = std::chrono::duration_cast<std::chrono::seconds>(date.time_since_epoch()).count(); line.col<Body>() = body; line.col<Nick>() = nick; @@ -206,21 +205,13 @@ std::vector<Database::MucLogLine> 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::MucLogLine> 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<std::string>(result)); } } - -void Transaction::rollback() -{ - this->success = false; - const auto result = Database::raw_exec("ROLLBACK"); - if (std::get<bool>(result) == false) - log_error("Failed to rollback SQL transaction: ", std::get<std::string>(result)); -} #endif diff --git a/src/database/database.hpp b/src/database/database.hpp index 75ff8f3..d986ecc 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -10,7 +10,6 @@ #include <database/engine.hpp> #include <utils/optional_bool.hpp> -#include <utils/datetime.hpp> #include <chrono> #include <string> @@ -18,9 +17,11 @@ #include <memory> #include <map> + class Database { public: + using time_point = std::chrono::system_clock::time_point; struct RecordNotFound: public std::exception {}; enum class Paging { first, last }; @@ -36,8 +37,7 @@ class Database struct Server: Column<std::string> { static constexpr auto name = "server_"; }; - struct OldDate: Column<std::chrono::system_clock::time_point::rep> { static constexpr auto name = "date_"; }; - struct Date: Column<DateTime> { static constexpr auto name = "date_"; }; + struct Date: Column<time_point::rep> { static constexpr auto name = "date_"; }; struct Body: Column<std::string> { static constexpr auto name = "body_"; }; @@ -88,8 +88,6 @@ class Database using MucLogLineTable = Table<Id, Uuid, Owner, IrcChanName, IrcServerName, Date, Body, Nick>; using MucLogLine = MucLogLineTable::RowType; - using OldMucLogLineTable = Table<Id, Uuid, Owner, IrcChanName, IrcServerName, OldDate, Body, Nick>; - using OldMucLogLine = OldMucLogLineTable::RowType; using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>; using GlobalOptions = GlobalOptionsTable::RowType; @@ -143,7 +141,7 @@ class Database */ static MucLogLine 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=""); static std::string store_muc_message(const std::string& owner, const std::string& chan_name, const std::string& server_name, - DateTime::time_point date, const std::string& body, const std::string& nick); + time_point date, const std::string& body, const std::string& nick); static void add_roster_item(const std::string& local, const std::string& remote); static bool has_roster_item(const std::string& local, const std::string& remote); @@ -170,13 +168,6 @@ class Database static std::unique_ptr<DatabaseEngine> db; - static DatabaseEngine::EngineType engine_type() - { - if (Database::db) - return Database::db->engine_type(); - return DatabaseEngine::EngineType::None; - } - /** * Some caches, to avoid doing very frequent query requests for a few options. */ @@ -225,20 +216,7 @@ class Transaction public: Transaction(); ~Transaction(); - void rollback(); bool success{false}; }; -template <typename... T> -void convert_date_format(DatabaseEngine& db, Table<T...> table) -{ - const auto existing_columns = db.get_all_columns_from_table(table.get_name()); - const auto date_pair = existing_columns.find(Database::Date::name); - if (date_pair != existing_columns.end() && date_pair->second == "integer") - { - log_info("Converting Date_ format to the new one."); - db.convert_date_format(db); - } -} - #endif /* USE_DATABASE */ diff --git a/src/database/datetime_writer.hpp b/src/database/datetime_writer.hpp deleted file mode 100644 index b104911..0000000 --- a/src/database/datetime_writer.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <utils/datetime.hpp> -#include <database/engine.hpp> - -#include <logger/logger.hpp> -#include <database/postgresql_engine.hpp> -#include <database/sqlite3_engine.hpp> - -class DatetimeWriter -{ -public: - DatetimeWriter(DateTime datetime, const DatabaseEngine& engine): - datetime(datetime), - engine(engine) - {} - - long double get_value() const - { - const long double epoch_duration = this->datetime.epoch().count(); - const long double epoch_seconds = epoch_duration / std::chrono::system_clock::period::den; - return this->engine.epoch_to_floating_value(epoch_seconds); - } - std::string escape_param_number(int value) const - { - return this->engine.escape_param_number(value); - } - -private: - const DateTime datetime; - const DatabaseEngine& engine; -}; diff --git a/src/database/engine.hpp b/src/database/engine.hpp index ecf047f..41dccf5 100644 --- a/src/database/engine.hpp +++ b/src/database/engine.hpp @@ -13,7 +13,6 @@ #include <string> #include <vector> #include <tuple> -#include <map> #include <set> class DatabaseEngine @@ -28,10 +27,7 @@ class DatabaseEngine DatabaseEngine(DatabaseEngine&&) = delete; DatabaseEngine& operator=(DatabaseEngine&&) = delete; - enum class EngineType { None, Postgresql, Sqlite3, }; - virtual EngineType engine_type() const = 0; - - virtual std::map<std::string, std::string> get_all_columns_from_table(const std::string& table_name) = 0; + virtual std::set<std::string> get_all_columns_from_table(const std::string& table_name) = 0; virtual std::tuple<bool, std::string> raw_exec(const std::string& query) = 0; virtual std::unique_ptr<Statement> prepare(const std::string& query) = 0; virtual void extract_last_insert_rowid(Statement& statement) = 0; @@ -39,17 +35,7 @@ class DatabaseEngine { return {}; } - virtual void convert_date_format(DatabaseEngine&) = 0; - virtual std::string id_column_type() const = 0; - virtual std::string datetime_column_type() const = 0; - virtual long double epoch_to_floating_value(long double seconds) const = 0; - virtual std::string escape_param_number(int nb) const - { - return "$" + std::to_string(nb); - } - virtual void init_session() - { - } + virtual std::string id_column_type() = 0; int64_t last_inserted_rowid{-1}; }; diff --git a/src/database/insert_query.cpp b/src/database/insert_query.cpp deleted file mode 100644 index f72d67f..0000000 --- a/src/database/insert_query.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <database/insert_query.hpp> - -template <> -std::string before_value<Database::Date>() -{ - if (Database::engine_type() == DatabaseEngine::EngineType::Sqlite3) - return "julianday("; - if (Database::engine_type() == DatabaseEngine::EngineType::Postgresql) - return "to_timestamp("; - return {}; -} - -template <> -std::string after_value<Database::Date>() -{ - if (Database::engine_type() == DatabaseEngine::EngineType::Sqlite3) - return ", \"unixepoch\")"; - if (Database::engine_type() == DatabaseEngine::EngineType::Postgresql) - return ")"; - return {}; -} diff --git a/src/database/insert_query.hpp b/src/database/insert_query.hpp index cd1942f..230e873 100644 --- a/src/database/insert_query.hpp +++ b/src/database/insert_query.hpp @@ -30,24 +30,6 @@ typename std::enable_if<N == sizeof...(T), void>::type update_autoincrement_id(std::tuple<T...>&, Statement&) {} -template <typename T> -std::string before_value() -{ - return {}; -} - -template <typename T> -std::string after_value() -{ - return {}; -} - -template <> -std::string before_value<Database::Date>(); - -template <> -std::string after_value<Database::Date>(); - struct InsertQuery: public Query { template <typename... T> @@ -96,7 +78,7 @@ struct InsertQuery: public Query template <typename... T> void insert_values(const std::tuple<T...>& columns) { - this->body += " VALUES ("; + this->body += "VALUES ("; this->insert_value(columns); this->body += ")"; } @@ -109,9 +91,7 @@ struct InsertQuery: public Query if (!std::is_same<ColumnType, Id>::value) { - this->body += before_value<ColumnType>(); this->body += "$" + std::to_string(index++); - this->body += after_value<ColumnType>(); if (N != sizeof...(T) - 1) this->body += ", "; } diff --git a/src/database/postgresql_engine.cpp b/src/database/postgresql_engine.cpp index d97f2ff..59bc885 100644 --- a/src/database/postgresql_engine.cpp +++ b/src/database/postgresql_engine.cpp @@ -2,7 +2,6 @@ #ifdef PQ_FOUND #include <utils/scopeguard.hpp> -#include <utils/tolower.hpp> #include <database/query.hpp> @@ -13,7 +12,6 @@ #include <logger/logger.hpp> #include <cstring> -#include <database/database.hpp> PostgresqlEngine::PostgresqlEngine(PGconn*const conn): conn(conn) @@ -54,14 +52,14 @@ std::unique_ptr<DatabaseEngine> PostgresqlEngine::open(const std::string& connin return std::make_unique<PostgresqlEngine>(con); } -std::map<std::string, std::string> PostgresqlEngine::get_all_columns_from_table(const std::string& table_name) +std::set<std::string> PostgresqlEngine::get_all_columns_from_table(const std::string& table_name) { - const auto query = "SELECT column_name, data_type from information_schema.columns where table_name='" + table_name + "'"; + const auto query = "SELECT column_name from information_schema.columns where table_name='" + table_name + "'"; auto statement = this->prepare(query); - std::map<std::string, std::string> columns; + std::set<std::string> columns; while (statement->step() == StepResult::Row) - columns[utils::tolower(statement->get_column_text(0))] = utils::tolower(statement->get_column_text(1)); + columns.insert(statement->get_column_text(0)); return columns; } @@ -98,41 +96,9 @@ std::string PostgresqlEngine::get_returning_id_sql_string(const std::string& col return " RETURNING " + col_name; } -std::string PostgresqlEngine::id_column_type() const +std::string PostgresqlEngine::id_column_type() { return "SERIAL"; } -std::string PostgresqlEngine::datetime_column_type() const -{ - return "TIMESTAMP"; -} - -void PostgresqlEngine::convert_date_format(DatabaseEngine& db) -{ - const auto table_name = Database::muc_log_lines.get_name(); - const std::string column_name = Database::Date::name; - const std::string query = "ALTER TABLE " + table_name + " ALTER COLMUN " + column_name + " SET DATA TYPE timestamp USING to_timestamp(" + column_name + ")"; - - auto result = db.raw_exec(query); - if (!std::get<bool>(result)) - log_error("Failed to execute query: ", std::get<std::string>(result)); -} - -std::string PostgresqlEngine::escape_param_number(int nb) const -{ - return "to_timestamp(" + DatabaseEngine::escape_param_number(nb) + ")"; -} - -void PostgresqlEngine::init_session() -{ - const auto res = this->raw_exec("SET SESSION TIME ZONE 'UTC'"); - if (!std::get<bool>(res)) - log_error("Failed to set UTC timezone: ", std::get<std::string>(res)); -} -long double PostgresqlEngine::epoch_to_floating_value(long double seconds) const -{ - return seconds; -} - #endif diff --git a/src/database/postgresql_engine.hpp b/src/database/postgresql_engine.hpp index 70215d4..1a9c249 100644 --- a/src/database/postgresql_engine.hpp +++ b/src/database/postgresql_engine.hpp @@ -23,22 +23,13 @@ class PostgresqlEngine: public DatabaseEngine ~PostgresqlEngine(); static std::unique_ptr<DatabaseEngine> open(const std::string& string); - EngineType engine_type() const override - { - return EngineType::Postgresql; - } - std::map<std::string, std::string> get_all_columns_from_table(const std::string& table_name) override final; + std::set<std::string> get_all_columns_from_table(const std::string& table_name) override final; std::tuple<bool, std::string> raw_exec(const std::string& query) override final; std::unique_ptr<Statement> prepare(const std::string& query) override; void extract_last_insert_rowid(Statement& statement) override; std::string get_returning_id_sql_string(const std::string& col_name) override; - std::string id_column_type() const override; - std::string datetime_column_type() const override; - void convert_date_format(DatabaseEngine& engine) override; - long double epoch_to_floating_value(long double seconds) const override; - void init_session() override; - std::string escape_param_number(int nb) const override; + std::string id_column_type() override; private: PGconn* const conn; }; diff --git a/src/database/query.cpp b/src/database/query.cpp index 6d20302..d72066e 100644 --- a/src/database/query.cpp +++ b/src/database/query.cpp @@ -21,13 +21,6 @@ void actual_bind(Statement& statement, const OptionalBool& value, int index) statement.bind_int64(index, -1); } -void actual_bind(Statement& statement, const DateTime& value, int index) -{ - const auto epoch = value.epoch().count(); - const auto result = std::to_string(static_cast<long double>(epoch) / std::chrono::system_clock::period::den); - statement.bind_text(index, result); -} - void actual_add_param(Query& query, const std::string& val) { query.params.push_back(val); @@ -56,12 +49,3 @@ Query& operator<<(Query& query, const std::string& str) actual_add_param(query, str); return query; } - -Query& operator<<(Query& query, const DatetimeWriter& datetime_writer) -{ - query.body += datetime_writer.escape_param_number(query.current_param++); - actual_add_param(query, datetime_writer.get_value()); - return query; -} - - diff --git a/src/database/query.hpp b/src/database/query.hpp index 910271a..ba28b1a 100644 --- a/src/database/query.hpp +++ b/src/database/query.hpp @@ -3,7 +3,6 @@ #include <biboumi.h> #include <utils/optional_bool.hpp> -#include <utils/datetime.hpp> #include <database/statement.hpp> #include <database/column.hpp> @@ -11,7 +10,6 @@ #include <vector> #include <string> -#include <database/datetime_writer.hpp> void actual_bind(Statement& statement, const std::string& value, int index); void actual_bind(Statement& statement, const std::int64_t& value, int index); @@ -21,7 +19,6 @@ void actual_bind(Statement& statement, const T& value, int index) actual_bind(statement, static_cast<std::int64_t>(value), index); } void actual_bind(Statement& statement, const OptionalBool& value, int index); -void actual_bind(Statement& statement, const DateTime& value, int index); #ifdef DEBUG_SQL_QUERIES #include <utils/scopetimer.hpp> @@ -77,13 +74,15 @@ void actual_add_param(Query& query, const std::string& val); void actual_add_param(Query& query, const OptionalBool& val); template <typename T> -typename std::enable_if<!std::is_arithmetic<T>::value, Query&>::type +typename std::enable_if<!std::is_integral<T>::value, Query&>::type operator<<(Query& query, const T&) { query.body += T::name; return query; } +Query& operator<<(Query& query, const char* str); +Query& operator<<(Query& query, const std::string& str); template <typename Integer> typename std::enable_if<std::is_integral<Integer>::value, Query&>::type operator<<(Query& query, const Integer& i) @@ -93,6 +92,3 @@ operator<<(Query& query, const Integer& i) return query; } -Query& operator<<(Query& query, const char* str); -Query& operator<<(Query& query, const std::string& str); -Query& operator<<(Query& query, const DatetimeWriter& datetime); diff --git a/src/database/select_query.cpp b/src/database/select_query.cpp deleted file mode 100644 index 970b06c..0000000 --- a/src/database/select_query.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <database/select_query.hpp> - -template <> -std::string before_column<Database::Date>() -{ - if (Database::engine_type() == DatabaseEngine::EngineType::Sqlite3) - return "strftime(\"%Y-%m-%dT%H:%M:%SZ\", "; - else if (Database::engine_type() == DatabaseEngine::EngineType::Postgresql) - return "to_char("; - return {}; -} - -template <> -std::string after_column<Database::Date>() -{ - if (Database::engine_type() == DatabaseEngine::EngineType::Sqlite3) - return ")"; - else if (Database::engine_type() == DatabaseEngine::EngineType::Postgresql) - return R"(, 'YYYY-MM-DD"T"HH24:MM:SS"Z"'))"; - return {}; -} diff --git a/src/database/select_query.hpp b/src/database/select_query.hpp index 0de4fe5..b9fdc06 100644 --- a/src/database/select_query.hpp +++ b/src/database/select_query.hpp @@ -5,8 +5,8 @@ #include <database/table.hpp> #include <database/database.hpp> #include <database/statement.hpp> -#include <utils/datetime.hpp> #include <database/query.hpp> +#include <logger/logger.hpp> #include <database/row.hpp> #include <utils/optional_bool.hpp> @@ -43,14 +43,6 @@ extract_row_value(Statement& statement, const int i) return result; } -template <typename T> -typename std::enable_if<std::is_same<DateTime, T>::value, T>::type -extract_row_value(Statement& statement, const int i) -{ - const std::string timestamp = statement.get_column_text(i); - return {timestamp}; -} - template <std::size_t N=0, typename... T> typename std::enable_if<N < sizeof...(T), void>::type extract_row_values(Row<T...>& row, Statement& statement) @@ -68,24 +60,6 @@ typename std::enable_if<N == sizeof...(T), void>::type extract_row_values(Row<T...>&, Statement&) {} -template <typename ColumnType> -std::string before_column() -{ - return {}; -} - -template <typename ColumnType> -std::string after_column() -{ - return {}; -} - -template <> -std::string before_column<Database::Date>(); - -template <> -std::string after_column<Database::Date>(); - template <typename... T> struct SelectQuery: public Query { @@ -104,8 +78,7 @@ struct SelectQuery: public Query using ColumnsType = std::tuple<T...>; using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnsType>()))>::type; - this->body += " "; - this->body += before_column<ColumnType>() + ColumnType::name + after_column<ColumnType>(); + this->body += " " + std::string{ColumnType::name}; if (N < (sizeof...(T) - 1)) this->body += ", "; diff --git a/src/database/sqlite3_engine.cpp b/src/database/sqlite3_engine.cpp index b6ac1a1..5e3bba1 100644 --- a/src/database/sqlite3_engine.cpp +++ b/src/database/sqlite3_engine.cpp @@ -2,10 +2,7 @@ #ifdef SQLITE3_FOUND -#include <database/database.hpp> -#include <database/select_query.hpp> #include <database/sqlite3_engine.hpp> - #include <database/sqlite3_statement.hpp> #include <database/query.hpp> @@ -24,17 +21,16 @@ Sqlite3Engine::~Sqlite3Engine() sqlite3_close(this->db); } -std::map<std::string, std::string> Sqlite3Engine::get_all_columns_from_table(const std::string& table_name) +std::set<std::string> Sqlite3Engine::get_all_columns_from_table(const std::string& table_name) { - std::map<std::string, std::string> result; + std::set<std::string> result; char* errmsg; std::string query{"PRAGMA table_info(" + table_name + ")"}; int res = sqlite3_exec(this->db, query.data(), [](void* param, int columns_nb, char** columns, char**) -> int { constexpr int name_column = 1; - constexpr int data_type_column = 2; - auto* result = static_cast<std::map<std::string, std::string>*>(param); - if (name_column < columns_nb && data_type_column < columns_nb) - (*result)[utils::tolower(columns[name_column])] = utils::tolower(columns[data_type_column]); + std::set<std::string>* result = static_cast<std::set<std::string>*>(param); + if (name_column < columns_nb) + result->insert(utils::tolower(columns[name_column])); return 0; }, &result, &errmsg); @@ -47,48 +43,6 @@ std::map<std::string, std::string> Sqlite3Engine::get_all_columns_from_table(con return result; } -template <typename... T> -static auto make_select_query(const Row<T...>&, const std::string& name) -{ - return SelectQuery<T...>{name}; -} - -void Sqlite3Engine::convert_date_format(DatabaseEngine& db) -{ - Transaction transaction{}; - auto rollback = [&transaction] (const std::string& error_msg) - { - log_error("Failed to execute query: ", error_msg); - transaction.rollback(); - }; - - const auto real_name = Database::muc_log_lines.get_name(); - const auto tmp_name = real_name + "tmp_"; - const std::string date_name = Database::Date::name; - - auto result = db.raw_exec("ALTER TABLE " + real_name + " RENAME TO " + tmp_name); - if (!std::get<bool>(result)) - return rollback(std::get<std::string>(result)); - - Database::muc_log_lines.create(db); - - Database::OldMucLogLineTable old_muc_log_line(tmp_name); - auto select_query = make_select_query(old_muc_log_line.row(), old_muc_log_line.get_name()); - - auto& select_body = select_query.body; - auto begin = select_body.find(date_name); - select_body.replace(begin, date_name.size(), "julianday("+date_name+", 'unixepoch')"); - select_body = "INSERT INTO " + real_name + " " + select_body; - - result = db.raw_exec(select_body); - if (!std::get<bool>(result)) - return rollback(std::get<std::string>(result)); - - result = db.raw_exec("DROP TABLE " + tmp_name); - if (!std::get<bool>(result)) - return rollback(std::get<std::string>(result)); -} - std::unique_ptr<DatabaseEngine> Sqlite3Engine::open(const std::string& filename) { sqlite3* new_db; @@ -138,19 +92,9 @@ void Sqlite3Engine::extract_last_insert_rowid(Statement&) this->last_inserted_rowid = sqlite3_last_insert_rowid(this->db); } -std::string Sqlite3Engine::id_column_type() const +std::string Sqlite3Engine::id_column_type() { return "INTEGER PRIMARY KEY AUTOINCREMENT"; } -std::string Sqlite3Engine::datetime_column_type() const -{ - return "REAL"; -} - -long double Sqlite3Engine::epoch_to_floating_value(long double d) const -{ - return (d / 86400.0) + 2440587.5; -} - #endif diff --git a/src/database/sqlite3_engine.hpp b/src/database/sqlite3_engine.hpp index 1b37e8c..a7bfcdb 100644 --- a/src/database/sqlite3_engine.hpp +++ b/src/database/sqlite3_engine.hpp @@ -23,19 +23,12 @@ class Sqlite3Engine: public DatabaseEngine ~Sqlite3Engine(); static std::unique_ptr<DatabaseEngine> open(const std::string& string); - EngineType engine_type() const override - { - return EngineType::Sqlite3; - } - std::map<std::string, std::string> get_all_columns_from_table(const std::string& table_name) override final; + std::set<std::string> get_all_columns_from_table(const std::string& table_name) override final; std::tuple<bool, std::string> raw_exec(const std::string& query) override final; std::unique_ptr<Statement> prepare(const std::string& query) override; void extract_last_insert_rowid(Statement& statement) override; - std::string id_column_type() const override; - std::string datetime_column_type() const override; - void convert_date_format(DatabaseEngine&) override; - long double epoch_to_floating_value(long double d) const override; + std::string id_column_type() override; private: sqlite3* const db; }; diff --git a/src/database/table.hpp b/src/database/table.hpp index 4c96151..0b8bfc0 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -18,8 +18,6 @@ std::string ToSQLType(DatabaseEngine& db) return db.id_column_type(); else if (std::is_same<typename T::real_type, std::string>::value) return "TEXT"; - else if (std::is_same<typename T::real_type, DateTime>::value) - return db.datetime_column_type(); else return "INTEGER"; } @@ -98,16 +96,16 @@ class Table template <std::size_t N=0> typename std::enable_if<N < sizeof...(T), void>::type - add_column_if_not_exists(DatabaseEngine& db, const std::map<std::string, std::string>& existing_columns) + add_column_if_not_exists(DatabaseEngine& db, const std::set<std::string>& existing_columns) { using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnTypes>()))>::type; - if (existing_columns.find(ColumnType::name) == existing_columns.end()) + if (existing_columns.count(ColumnType::name) == 0) add_column_to_table<ColumnType>(db, this->name); add_column_if_not_exists<N+1>(db, existing_columns); } template <std::size_t N=0> typename std::enable_if<N == sizeof...(T), void>::type - add_column_if_not_exists(DatabaseEngine&, const std::map<std::string, std::string>&) + add_column_if_not_exists(DatabaseEngine&, const std::set<std::string>&) {} template <std::size_t N=0> diff --git a/src/utils/datetime.hpp b/src/utils/datetime.hpp deleted file mode 100644 index 656b318..0000000 --- a/src/utils/datetime.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include <chrono> -#include <string> - -#include <logger/logger.hpp> - -class DateTime -{ -public: - enum class Engine { - Postgresql, - Sqlite3, - } engine{Engine::Sqlite3}; - - using time_point = std::chrono::system_clock::time_point; - - DateTime(): - s{}, - t{} - { } - - DateTime(std::time_t t): - t(std::chrono::seconds(t)) - {} - - DateTime(std::string s): - s(std::move(s)) - {} - - DateTime& operator=(const std::string& s) - { - this->s = s; - return *this; - } - - DateTime& operator=(const time_point t) - { - this->t = t; - return *this; - } - - const std::string& to_string() const - { - return this->s; - } - - time_point::duration epoch() const - { - return this->t.time_since_epoch(); - } - -private: - std::string s; - time_point t; -}; diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 95b38f0..6dc5fc5 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -805,7 +805,7 @@ void BiboumiComponent::send_archived_message(const Database::MucLogLine& log_lin XmlSubNode delay(forwarded, "delay"); delay["xmlns"] = DELAY_NS; - delay["stamp"] = log_line.col<Database::Date>().to_string(); + delay["stamp"] = utils::to_string(log_line.col<Database::Date>()); XmlSubNode submessage(forwarded, "message"); submessage["xmlns"] = CLIENT_NS; diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index bec88ea..b3d925e 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -399,7 +399,7 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str } #ifdef USE_DATABASE -void XmppComponent::send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body_txt, const std::string& jid_to, const DateTime& timestamp) +void XmppComponent::send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body_txt, const std::string& jid_to, Database::time_point::rep timestamp) { Stanza message("message"); message["to"] = jid_to; @@ -417,7 +417,7 @@ void XmppComponent::send_history_message(const std::string& muc_name, const std: XmlSubNode delay(message, "delay"); delay["xmlns"] = DELAY_NS; delay["from"] = muc_name + "@" + this->served_hostname; - delay["stamp"] = timestamp.to_string(); + delay["stamp"] = utils::to_string(timestamp); } this->send_stanza(message); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 960c801..e18da40 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -6,7 +6,6 @@ #include <network/tcp_client_socket_handler.hpp> #include <database/database.hpp> #include <xmpp/xmpp_parser.hpp> -#include <utils/datetime.hpp> #include <xmpp/body.hpp> #include <unordered_map> @@ -142,7 +141,7 @@ public: * Send a message, with a <delay/> element, part of a MUC history */ void send_history_message(const std::string& muc_name, const std::string& nick, const std::string& body, - const std::string& jid_to, const DateTime& timestamp); + const std::string& jid_to, Database::time_point::rep timestamp); #endif /** * Send an unavailable presence for this nick diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 6c575a8..82321eb 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1953,7 +1953,7 @@ if __name__ == '__main__': <query xmlns='urn:xmpp:mam:2' queryid='qid3'> <x xmlns='jabber:x:data' type='submit'> <field var='FORM_TYPE' type='hidden'> <value>urn:xmpp:mam:2</value></field> - <field var='start'><value>2222-06-07T00:00:00Z</value></field> + <field var='start'><value>3016-06-07T00:00:00Z</value></field> </x> </query></iq>"""), |