Revert "Use a different Date data type"
This reverts commit 857c7d3972.
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
Version 8.0
|
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
|
- Add a complete='true' in MAM’s iq result when appropriate
|
||||||
- The “virtual” channel with an empty name (for example
|
- The “virtual” channel with an empty name (for example
|
||||||
%irc.freenode.net@biboumi) has been entirely removed.
|
%irc.freenode.net@biboumi) has been entirely removed.
|
||||||
|
|||||||
@@ -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));
|
chan_name.append(utils::empty_if_fixed_server("%" + hostname));
|
||||||
for (const auto& line: lines)
|
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->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
|
#else
|
||||||
(void)hostname;
|
(void)hostname;
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ void Database::open(const std::string& filename)
|
|||||||
Database::db = std::move(new_db);
|
Database::db = std::move(new_db);
|
||||||
Database::muc_log_lines.create(*Database::db);
|
Database::muc_log_lines.create(*Database::db);
|
||||||
Database::muc_log_lines.upgrade(*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.create(*Database::db);
|
||||||
Database::global_options.upgrade(*Database::db);
|
Database::global_options.upgrade(*Database::db);
|
||||||
Database::irc_server_options.create(*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.create(*Database::db);
|
||||||
Database::after_connection_commands.upgrade(*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());
|
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)
|
Database::GlobalOptions Database::get_global_options(const std::string& owner)
|
||||||
{
|
{
|
||||||
auto request = select(Database::global_options);
|
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,
|
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)
|
const std::string& body, const std::string& nick)
|
||||||
{
|
{
|
||||||
auto line = Database::muc_log_lines.row();
|
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<Owner>() = owner;
|
||||||
line.col<IrcChanName>() = chan_name;
|
line.col<IrcChanName>() = chan_name;
|
||||||
line.col<IrcServerName>() = server_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<Body>() = body;
|
||||||
line.col<Nick>() = nick;
|
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);
|
const auto start_time = utils::parse_datetime(start);
|
||||||
if (start_time != -1)
|
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())
|
if (!end.empty())
|
||||||
{
|
{
|
||||||
const auto end_time = utils::parse_datetime(end);
|
const auto end_time = utils::parse_datetime(end);
|
||||||
if (end_time != -1)
|
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)
|
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)
|
if (paging == Database::Paging::first)
|
||||||
request.order_by() << Database::Date{} << " ASC";
|
request.order_by() << Database::Date{} << " ASC, " << Id{} << " ASC ";
|
||||||
else
|
else
|
||||||
request.order_by() << Database::Date{} << " DESC";
|
request.order_by() << Database::Date{} << " DESC, " << Id{} << " DESC ";
|
||||||
|
|
||||||
if (limit >= 0)
|
if (limit >= 0)
|
||||||
request.limit() << limit;
|
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);
|
const auto start_time = utils::parse_datetime(start);
|
||||||
if (start_time != -1)
|
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())
|
if (!end.empty())
|
||||||
{
|
{
|
||||||
const auto end_time = utils::parse_datetime(end);
|
const auto end_time = utils::parse_datetime(end);
|
||||||
if (end_time != -1)
|
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);
|
auto result = request.execute(*Database::db);
|
||||||
@@ -359,12 +342,4 @@ Transaction::~Transaction()
|
|||||||
log_error("Failed to end SQL transaction: ", std::get<std::string>(result));
|
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
|
#endif
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <database/engine.hpp>
|
#include <database/engine.hpp>
|
||||||
|
|
||||||
#include <utils/optional_bool.hpp>
|
#include <utils/optional_bool.hpp>
|
||||||
#include <utils/datetime.hpp>
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -18,9 +17,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using time_point = std::chrono::system_clock::time_point;
|
||||||
struct RecordNotFound: public std::exception {};
|
struct RecordNotFound: public std::exception {};
|
||||||
enum class Paging { first, last };
|
enum class Paging { first, last };
|
||||||
|
|
||||||
@@ -36,8 +37,7 @@ class Database
|
|||||||
|
|
||||||
struct Server: Column<std::string> { static constexpr auto name = "server_"; };
|
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<time_point::rep> { static constexpr auto name = "date_"; };
|
||||||
struct Date: Column<DateTime> { static constexpr auto name = "date_"; };
|
|
||||||
|
|
||||||
struct Body: Column<std::string> { static constexpr auto name = "body_"; };
|
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 MucLogLineTable = Table<Id, Uuid, Owner, IrcChanName, IrcServerName, Date, Body, Nick>;
|
||||||
using MucLogLine = MucLogLineTable::RowType;
|
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 GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
|
||||||
using GlobalOptions = GlobalOptionsTable::RowType;
|
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 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,
|
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 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);
|
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 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.
|
* Some caches, to avoid doing very frequent query requests for a few options.
|
||||||
*/
|
*/
|
||||||
@@ -225,20 +216,7 @@ class Transaction
|
|||||||
public:
|
public:
|
||||||
Transaction();
|
Transaction();
|
||||||
~Transaction();
|
~Transaction();
|
||||||
void rollback();
|
|
||||||
bool success{false};
|
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 */
|
#endif /* USE_DATABASE */
|
||||||
|
|||||||
@@ -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;
|
|
||||||
};
|
|
||||||
+2
-16
@@ -13,7 +13,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <map>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
class DatabaseEngine
|
class DatabaseEngine
|
||||||
@@ -28,10 +27,7 @@ class DatabaseEngine
|
|||||||
DatabaseEngine(DatabaseEngine&&) = delete;
|
DatabaseEngine(DatabaseEngine&&) = delete;
|
||||||
DatabaseEngine& operator=(DatabaseEngine&&) = delete;
|
DatabaseEngine& operator=(DatabaseEngine&&) = delete;
|
||||||
|
|
||||||
enum class EngineType { None, Postgresql, Sqlite3, };
|
virtual std::set<std::string> get_all_columns_from_table(const std::string& table_name) = 0;
|
||||||
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::tuple<bool, std::string> raw_exec(const std::string& query) = 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 std::unique_ptr<Statement> prepare(const std::string& query) = 0;
|
||||||
virtual void extract_last_insert_rowid(Statement& statement) = 0;
|
virtual void extract_last_insert_rowid(Statement& statement) = 0;
|
||||||
@@ -39,17 +35,7 @@ class DatabaseEngine
|
|||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
virtual void convert_date_format(DatabaseEngine&) = 0;
|
virtual std::string id_column_type() = 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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t last_inserted_rowid{-1};
|
int64_t last_inserted_rowid{-1};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 {};
|
|
||||||
}
|
|
||||||
@@ -30,24 +30,6 @@ typename std::enable_if<N == sizeof...(T), void>::type
|
|||||||
update_autoincrement_id(std::tuple<T...>&, Statement&)
|
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
|
struct InsertQuery: public Query
|
||||||
{
|
{
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
@@ -96,7 +78,7 @@ struct InsertQuery: public Query
|
|||||||
template <typename... T>
|
template <typename... T>
|
||||||
void insert_values(const std::tuple<T...>& columns)
|
void insert_values(const std::tuple<T...>& columns)
|
||||||
{
|
{
|
||||||
this->body += " VALUES (";
|
this->body += "VALUES (";
|
||||||
this->insert_value(columns);
|
this->insert_value(columns);
|
||||||
this->body += ")";
|
this->body += ")";
|
||||||
}
|
}
|
||||||
@@ -109,9 +91,7 @@ struct InsertQuery: public Query
|
|||||||
|
|
||||||
if (!std::is_same<ColumnType, Id>::value)
|
if (!std::is_same<ColumnType, Id>::value)
|
||||||
{
|
{
|
||||||
this->body += before_value<ColumnType>();
|
|
||||||
this->body += "$" + std::to_string(index++);
|
this->body += "$" + std::to_string(index++);
|
||||||
this->body += after_value<ColumnType>();
|
|
||||||
if (N != sizeof...(T) - 1)
|
if (N != sizeof...(T) - 1)
|
||||||
this->body += ", ";
|
this->body += ", ";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#ifdef PQ_FOUND
|
#ifdef PQ_FOUND
|
||||||
|
|
||||||
#include <utils/scopeguard.hpp>
|
#include <utils/scopeguard.hpp>
|
||||||
#include <utils/tolower.hpp>
|
|
||||||
|
|
||||||
#include <database/query.hpp>
|
#include <database/query.hpp>
|
||||||
|
|
||||||
@@ -13,7 +12,6 @@
|
|||||||
#include <logger/logger.hpp>
|
#include <logger/logger.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <database/database.hpp>
|
|
||||||
|
|
||||||
PostgresqlEngine::PostgresqlEngine(PGconn*const conn):
|
PostgresqlEngine::PostgresqlEngine(PGconn*const conn):
|
||||||
conn(conn)
|
conn(conn)
|
||||||
@@ -54,14 +52,14 @@ std::unique_ptr<DatabaseEngine> PostgresqlEngine::open(const std::string& connin
|
|||||||
return std::make_unique<PostgresqlEngine>(con);
|
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);
|
auto statement = this->prepare(query);
|
||||||
std::map<std::string, std::string> columns;
|
std::set<std::string> columns;
|
||||||
|
|
||||||
while (statement->step() == StepResult::Row)
|
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;
|
return columns;
|
||||||
}
|
}
|
||||||
@@ -98,41 +96,9 @@ std::string PostgresqlEngine::get_returning_id_sql_string(const std::string& col
|
|||||||
return " RETURNING " + col_name;
|
return " RETURNING " + col_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PostgresqlEngine::id_column_type() const
|
std::string PostgresqlEngine::id_column_type()
|
||||||
{
|
{
|
||||||
return "SERIAL";
|
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
|
#endif
|
||||||
|
|||||||
@@ -23,22 +23,13 @@ class PostgresqlEngine: public DatabaseEngine
|
|||||||
~PostgresqlEngine();
|
~PostgresqlEngine();
|
||||||
|
|
||||||
static std::unique_ptr<DatabaseEngine> open(const std::string& string);
|
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::tuple<bool, std::string> raw_exec(const std::string& query) override final;
|
||||||
std::unique_ptr<Statement> prepare(const std::string& query) override;
|
std::unique_ptr<Statement> prepare(const std::string& query) override;
|
||||||
void extract_last_insert_rowid(Statement& statement) override;
|
void extract_last_insert_rowid(Statement& statement) override;
|
||||||
std::string get_returning_id_sql_string(const std::string& col_name) override;
|
std::string get_returning_id_sql_string(const std::string& col_name) override;
|
||||||
std::string id_column_type() const override;
|
std::string id_column_type() 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;
|
|
||||||
private:
|
private:
|
||||||
PGconn* const conn;
|
PGconn* const conn;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,13 +21,6 @@ void actual_bind(Statement& statement, const OptionalBool& value, int index)
|
|||||||
statement.bind_int64(index, -1);
|
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)
|
void actual_add_param(Query& query, const std::string& val)
|
||||||
{
|
{
|
||||||
query.params.push_back(val);
|
query.params.push_back(val);
|
||||||
@@ -56,12 +49,3 @@ Query& operator<<(Query& query, const std::string& str)
|
|||||||
actual_add_param(query, str);
|
actual_add_param(query, str);
|
||||||
return query;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <biboumi.h>
|
#include <biboumi.h>
|
||||||
|
|
||||||
#include <utils/optional_bool.hpp>
|
#include <utils/optional_bool.hpp>
|
||||||
#include <utils/datetime.hpp>
|
|
||||||
#include <database/statement.hpp>
|
#include <database/statement.hpp>
|
||||||
#include <database/column.hpp>
|
#include <database/column.hpp>
|
||||||
|
|
||||||
@@ -11,7 +10,6 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#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::string& value, int index);
|
||||||
void actual_bind(Statement& statement, const std::int64_t& 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);
|
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 OptionalBool& value, int index);
|
||||||
void actual_bind(Statement& statement, const DateTime& value, int index);
|
|
||||||
|
|
||||||
#ifdef DEBUG_SQL_QUERIES
|
#ifdef DEBUG_SQL_QUERIES
|
||||||
#include <utils/scopetimer.hpp>
|
#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);
|
void actual_add_param(Query& query, const OptionalBool& val);
|
||||||
|
|
||||||
template <typename T>
|
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&)
|
operator<<(Query& query, const T&)
|
||||||
{
|
{
|
||||||
query.body += T::name;
|
query.body += T::name;
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Query& operator<<(Query& query, const char* str);
|
||||||
|
Query& operator<<(Query& query, const std::string& str);
|
||||||
template <typename Integer>
|
template <typename Integer>
|
||||||
typename std::enable_if<std::is_integral<Integer>::value, Query&>::type
|
typename std::enable_if<std::is_integral<Integer>::value, Query&>::type
|
||||||
operator<<(Query& query, const Integer& i)
|
operator<<(Query& query, const Integer& i)
|
||||||
@@ -93,6 +92,3 @@ operator<<(Query& query, const Integer& i)
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
Query& operator<<(Query& query, const char* str);
|
|
||||||
Query& operator<<(Query& query, const std::string& str);
|
|
||||||
Query& operator<<(Query& query, const DatetimeWriter& datetime);
|
|
||||||
|
|||||||
@@ -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 {};
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
#include <database/table.hpp>
|
#include <database/table.hpp>
|
||||||
#include <database/database.hpp>
|
#include <database/database.hpp>
|
||||||
#include <database/statement.hpp>
|
#include <database/statement.hpp>
|
||||||
#include <utils/datetime.hpp>
|
|
||||||
#include <database/query.hpp>
|
#include <database/query.hpp>
|
||||||
|
#include <logger/logger.hpp>
|
||||||
#include <database/row.hpp>
|
#include <database/row.hpp>
|
||||||
|
|
||||||
#include <utils/optional_bool.hpp>
|
#include <utils/optional_bool.hpp>
|
||||||
@@ -43,14 +43,6 @@ extract_row_value(Statement& statement, const int i)
|
|||||||
return result;
|
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>
|
template <std::size_t N=0, typename... T>
|
||||||
typename std::enable_if<N < sizeof...(T), void>::type
|
typename std::enable_if<N < sizeof...(T), void>::type
|
||||||
extract_row_values(Row<T...>& row, Statement& statement)
|
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&)
|
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>
|
template <typename... T>
|
||||||
struct SelectQuery: public Query
|
struct SelectQuery: public Query
|
||||||
{
|
{
|
||||||
@@ -104,8 +78,7 @@ struct SelectQuery: public Query
|
|||||||
using ColumnsType = std::tuple<T...>;
|
using ColumnsType = std::tuple<T...>;
|
||||||
using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnsType>()))>::type;
|
using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnsType>()))>::type;
|
||||||
|
|
||||||
this->body += " ";
|
this->body += " " + std::string{ColumnType::name};
|
||||||
this->body += before_column<ColumnType>() + ColumnType::name + after_column<ColumnType>();
|
|
||||||
|
|
||||||
if (N < (sizeof...(T) - 1))
|
if (N < (sizeof...(T) - 1))
|
||||||
this->body += ", ";
|
this->body += ", ";
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
#ifdef SQLITE3_FOUND
|
#ifdef SQLITE3_FOUND
|
||||||
|
|
||||||
#include <database/database.hpp>
|
|
||||||
#include <database/select_query.hpp>
|
|
||||||
#include <database/sqlite3_engine.hpp>
|
#include <database/sqlite3_engine.hpp>
|
||||||
|
|
||||||
#include <database/sqlite3_statement.hpp>
|
#include <database/sqlite3_statement.hpp>
|
||||||
|
|
||||||
#include <database/query.hpp>
|
#include <database/query.hpp>
|
||||||
@@ -24,17 +21,16 @@ Sqlite3Engine::~Sqlite3Engine()
|
|||||||
sqlite3_close(this->db);
|
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;
|
char* errmsg;
|
||||||
std::string query{"PRAGMA table_info(" + table_name + ")"};
|
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 {
|
int res = sqlite3_exec(this->db, query.data(), [](void* param, int columns_nb, char** columns, char**) -> int {
|
||||||
constexpr int name_column = 1;
|
constexpr int name_column = 1;
|
||||||
constexpr int data_type_column = 2;
|
std::set<std::string>* result = static_cast<std::set<std::string>*>(param);
|
||||||
auto* result = static_cast<std::map<std::string, std::string>*>(param);
|
if (name_column < columns_nb)
|
||||||
if (name_column < columns_nb && data_type_column < columns_nb)
|
result->insert(utils::tolower(columns[name_column]));
|
||||||
(*result)[utils::tolower(columns[name_column])] = utils::tolower(columns[data_type_column]);
|
|
||||||
return 0;
|
return 0;
|
||||||
}, &result, &errmsg);
|
}, &result, &errmsg);
|
||||||
|
|
||||||
@@ -47,48 +43,6 @@ std::map<std::string, std::string> Sqlite3Engine::get_all_columns_from_table(con
|
|||||||
return result;
|
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)
|
std::unique_ptr<DatabaseEngine> Sqlite3Engine::open(const std::string& filename)
|
||||||
{
|
{
|
||||||
sqlite3* new_db;
|
sqlite3* new_db;
|
||||||
@@ -138,19 +92,9 @@ void Sqlite3Engine::extract_last_insert_rowid(Statement&)
|
|||||||
this->last_inserted_rowid = sqlite3_last_insert_rowid(this->db);
|
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";
|
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
|
#endif
|
||||||
|
|||||||
@@ -23,19 +23,12 @@ class Sqlite3Engine: public DatabaseEngine
|
|||||||
~Sqlite3Engine();
|
~Sqlite3Engine();
|
||||||
|
|
||||||
static std::unique_ptr<DatabaseEngine> open(const std::string& string);
|
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::tuple<bool, std::string> raw_exec(const std::string& query) override final;
|
||||||
std::unique_ptr<Statement> prepare(const std::string& query) override;
|
std::unique_ptr<Statement> prepare(const std::string& query) override;
|
||||||
void extract_last_insert_rowid(Statement& statement) override;
|
void extract_last_insert_rowid(Statement& statement) override;
|
||||||
std::string id_column_type() const override;
|
std::string id_column_type() 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;
|
|
||||||
private:
|
private:
|
||||||
sqlite3* const db;
|
sqlite3* const db;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ std::string ToSQLType(DatabaseEngine& db)
|
|||||||
return db.id_column_type();
|
return db.id_column_type();
|
||||||
else if (std::is_same<typename T::real_type, std::string>::value)
|
else if (std::is_same<typename T::real_type, std::string>::value)
|
||||||
return "TEXT";
|
return "TEXT";
|
||||||
else if (std::is_same<typename T::real_type, DateTime>::value)
|
|
||||||
return db.datetime_column_type();
|
|
||||||
else
|
else
|
||||||
return "INTEGER";
|
return "INTEGER";
|
||||||
}
|
}
|
||||||
@@ -98,16 +96,16 @@ class Table
|
|||||||
|
|
||||||
template <std::size_t N=0>
|
template <std::size_t N=0>
|
||||||
typename std::enable_if<N < sizeof...(T), void>::type
|
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;
|
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_to_table<ColumnType>(db, this->name);
|
||||||
add_column_if_not_exists<N+1>(db, existing_columns);
|
add_column_if_not_exists<N+1>(db, existing_columns);
|
||||||
}
|
}
|
||||||
template <std::size_t N=0>
|
template <std::size_t N=0>
|
||||||
typename std::enable_if<N == sizeof...(T), void>::type
|
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>
|
template <std::size_t N=0>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -805,7 +805,7 @@ void BiboumiComponent::send_archived_message(const Database::MucLogLine& log_lin
|
|||||||
|
|
||||||
XmlSubNode delay(forwarded, "delay");
|
XmlSubNode delay(forwarded, "delay");
|
||||||
delay["xmlns"] = DELAY_NS;
|
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");
|
XmlSubNode submessage(forwarded, "message");
|
||||||
submessage["xmlns"] = CLIENT_NS;
|
submessage["xmlns"] = CLIENT_NS;
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_DATABASE
|
#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");
|
Stanza message("message");
|
||||||
message["to"] = jid_to;
|
message["to"] = jid_to;
|
||||||
@@ -417,7 +417,7 @@ void XmppComponent::send_history_message(const std::string& muc_name, const std:
|
|||||||
XmlSubNode delay(message, "delay");
|
XmlSubNode delay(message, "delay");
|
||||||
delay["xmlns"] = DELAY_NS;
|
delay["xmlns"] = DELAY_NS;
|
||||||
delay["from"] = muc_name + "@" + this->served_hostname;
|
delay["from"] = muc_name + "@" + this->served_hostname;
|
||||||
delay["stamp"] = timestamp.to_string();
|
delay["stamp"] = utils::to_string(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->send_stanza(message);
|
this->send_stanza(message);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <network/tcp_client_socket_handler.hpp>
|
#include <network/tcp_client_socket_handler.hpp>
|
||||||
#include <database/database.hpp>
|
#include <database/database.hpp>
|
||||||
#include <xmpp/xmpp_parser.hpp>
|
#include <xmpp/xmpp_parser.hpp>
|
||||||
#include <utils/datetime.hpp>
|
|
||||||
#include <xmpp/body.hpp>
|
#include <xmpp/body.hpp>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -142,7 +141,7 @@ public:
|
|||||||
* Send a message, with a <delay/> element, part of a MUC history
|
* 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,
|
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
|
#endif
|
||||||
/**
|
/**
|
||||||
* Send an unavailable presence for this nick
|
* Send an unavailable presence for this nick
|
||||||
|
|||||||
@@ -1953,7 +1953,7 @@ if __name__ == '__main__':
|
|||||||
<query xmlns='urn:xmpp:mam:2' queryid='qid3'>
|
<query xmlns='urn:xmpp:mam:2' queryid='qid3'>
|
||||||
<x xmlns='jabber:x:data' type='submit'>
|
<x xmlns='jabber:x:data' type='submit'>
|
||||||
<field var='FORM_TYPE' type='hidden'> <value>urn:xmpp:mam:2</value></field>
|
<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>
|
</x>
|
||||||
</query></iq>"""),
|
</query></iq>"""),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user