Use a different Date data type

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
This commit is contained in:
louiz’
2018-04-11 00:25:18 +02:00
parent 0cd848e532
commit 857c7d3972
21 changed files with 417 additions and 46 deletions
+26 -4
View File
@@ -10,6 +10,7 @@
#include <database/engine.hpp>
#include <utils/optional_bool.hpp>
#include <utils/datetime.hpp>
#include <chrono>
#include <string>
@@ -17,11 +18,9 @@
#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 };
@@ -37,7 +36,8 @@ class Database
struct Server: Column<std::string> { static constexpr auto name = "server_"; };
struct Date: Column<time_point::rep> { static constexpr auto name = "date_"; };
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 Body: Column<std::string> { static constexpr auto name = "body_"; };
@@ -88,6 +88,8 @@ 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;
@@ -141,7 +143,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,
time_point date, const std::string& body, const std::string& nick);
DateTime::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);
@@ -168,6 +170,13 @@ 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.
*/
@@ -216,7 +225,20 @@ 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 */