Browse Source

refactor(history): Moved creaton of RawDatabase from History constuctor

pull/3823/head
Diadlo 9 years ago
parent
commit
b522da5bed
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
  1. 231
      src/persistence/history.cpp
  2. 59
      src/persistence/history.h
  3. 113
      src/persistence/profile.cpp
  4. 4
      src/persistence/profile.h

231
src/persistence/history.cpp

@ -1,12 +1,30 @@ @@ -1,12 +1,30 @@
#include "history.h"
#include "src/persistence/profile.h"
#include "src/persistence/settings.h"
#include "src/persistence/db/rawdatabase.h"
#include "src/persistence/historykeeper.h"
/*
Copyright © 2015-2016 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QDebug>
#include <cassert>
using namespace std;
#include "db/rawdatabase.h"
#include "history.h"
#include "historykeeper.h"
#include "profile.h"
#include "settings.h"
/**
* @class History
@ -18,33 +36,43 @@ using namespace std; @@ -18,33 +36,43 @@ using namespace std;
*/
/**
* @brief Opens the profile database and prepares to work with the history.
* @param profileName Profile name to load.
* @param password If empty, the database will be opened unencrypted.
* @brief Prepares the database to work with the history.
* @param db This database will be prepared for use with the history.
*/
History::History(const QString &profileName, const QString &password)
: db{getDbPath(profileName), password}
History::History(std::shared_ptr<RawDatabase> db)
: db(db)
{
if (!isValid())
{
init();
qWarning() << "Database not open, init failed";
return;
}
/**
* @brief Opens the profile database, and import from the old database.
* @param profileName Profile name to load.
* @param password If empty, the database will be opened unencrypted.
* @param oldHistory Old history to import.
*/
History::History(const QString &profileName, const QString &password, const HistoryKeeper &oldHistory)
: History{profileName, password}
db->execLater("CREATE TABLE IF NOT EXISTS peers (id INTEGER PRIMARY KEY, public_key TEXT NOT NULL UNIQUE);"
"CREATE TABLE IF NOT EXISTS aliases (id INTEGER PRIMARY KEY, owner INTEGER,"
"display_name BLOB NOT NULL, UNIQUE(owner, display_name));"
"CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, "
"chat_id INTEGER NOT NULL, sender_alias INTEGER NOT NULL, "
"message BLOB NOT NULL);"
"CREATE TABLE IF NOT EXISTS faux_offline_pending (id INTEGER PRIMARY KEY);");
// Cache our current peers
db->execLater(RawDatabase::Query{"SELECT public_key, id FROM peers;", [this](const QVector<QVariant>& row)
{
import(oldHistory);
peers[row[0].toString()] = row[1].toInt();
}});
}
History::~History()
{
if (!isValid())
{
return;
}
// We could have execLater requests pending with a lambda attached,
// so clear the pending transactions first
db.sync();
db->sync();
}
/**
@ -53,42 +81,20 @@ History::~History() @@ -53,42 +81,20 @@ History::~History()
*/
bool History::isValid()
{
return db.isOpen();
return db && db->isOpen();
}
/**
* @brief Changes the database password, will encrypt or decrypt if necessary.
* @param password Password to set.
*/
void History::setPassword(const QString& password)
{
db.setPassword(password);
}
/**
* @brief Moves the database file on disk to match the new name.
* @param newName New name.
* @brief Erases all the chat history from the database.
*/
void History::rename(const QString &newName)
void History::eraseHistory()
{
db.rename(getDbPath(newName));
}
/**
* @brief Deletes the on-disk database file.
* @return True if success, false otherwise.
*/
bool History::remove()
if (!isValid())
{
return db.remove();
return;
}
/**
* @brief Erases all the chat history from the database.
*/
void History::eraseHistory()
{
db.execNow("DELETE FROM faux_offline_pending;"
db->execNow("DELETE FROM faux_offline_pending;"
"DELETE FROM history;"
"DELETE FROM aliases;"
"DELETE FROM peers;"
@ -101,11 +107,20 @@ void History::eraseHistory() @@ -101,11 +107,20 @@ void History::eraseHistory()
*/
void History::removeFriendHistory(const QString& friendPk)
{
if (!isValid())
{
return;
}
if (!peers.contains(friendPk))
{
return;
}
int64_t id = peers[friendPk];
if (db.execNow(QString("DELETE FROM faux_offline_pending "
QString queryText = QString(
"DELETE FROM faux_offline_pending "
"WHERE faux_offline_pending.id IN ( "
" SELECT faux_offline_pending.id FROM faux_offline_pending "
" LEFT JOIN history ON faux_offline_pending.id = history.id "
@ -114,7 +129,9 @@ void History::removeFriendHistory(const QString &friendPk) @@ -114,7 +129,9 @@ void History::removeFriendHistory(const QString &friendPk)
"DELETE FROM history WHERE chat_id=%1; "
"DELETE FROM aliases WHERE owner=%1; "
"DELETE FROM peers WHERE id=%1; "
"VACUUM;").arg(id)))
"VACUUM;").arg(id);
if (db->execNow(queryText))
{
peers.remove(friendPk);
}
@ -149,11 +166,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr @@ -149,11 +166,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr
else
{
if (peers.isEmpty())
{
peerId = 0;
}
else
peerId = *max_element(begin(peers), end(peers))+1;
{
peerId = *std::max_element(peers.begin(), peers.end()) + 1;
}
peers[friendPk] = peerId;
queries += RawDatabase::Query{("INSERT INTO peers (id, public_key) VALUES (%1, '"+friendPk+"');").arg(peerId)};
queries += RawDatabase::Query(("INSERT INTO peers (id, public_key) "
"VALUES (%1, '" + friendPk + "');")
.arg(peerId));
}
// Get the db id of the sender of the message
@ -165,11 +189,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr @@ -165,11 +189,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr
else
{
if (peers.isEmpty())
{
senderId = 0;
}
else
senderId = *max_element(begin(peers), end(peers))+1;
{
senderId = *std::max_element(peers.begin(), peers.end()) + 1;
}
peers[sender] = senderId;
queries += RawDatabase::Query{("INSERT INTO peers (id, public_key) VALUES (%1, '"+sender+"');").arg(senderId)};
queries += RawDatabase::Query{("INSERT INTO peers (id, public_key) "
"VALUES (%1, '" + sender + "');")
.arg(senderId)};
}
queries += RawDatabase::Query(QString("INSERT OR IGNORE INTO aliases (owner, display_name) VALUES (%1, ?);")
@ -187,7 +218,12 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr @@ -187,7 +218,12 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr
{message.toUtf8(), dispName.toUtf8()}, insertIdCallback);
if (!isSent)
queries += RawDatabase::Query{"INSERT INTO faux_offline_pending (id) VALUES (last_insert_rowid());"};
{
queries += RawDatabase::Query{
"INSERT INTO faux_offline_pending (id) VALUES ("
" last_insert_rowid()"
");"};
}
return queries;
}
@ -202,10 +238,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr @@ -202,10 +238,18 @@ QVector<RawDatabase::Query> History::generateNewMessageQueries(const QString &fr
* @param dispName Name, which should be displayed.
* @param insertIdCallback Function, called after query execution.
*/
void History::addNewMessage(const QString &friendPk, const QString &message, const QString &sender,
const QDateTime &time, bool isSent, QString dispName, std::function<void(int64_t)> insertIdCallback)
void History::addNewMessage(const QString& friendPk, const QString& message,
const QString& sender, const QDateTime& time,
bool isSent, QString dispName,
std::function<void(int64_t)> insertIdCallback)
{
db.execLater(generateNewMessageQueries(friendPk, message, sender, time, isSent, dispName, insertIdCallback));
if (!isValid())
{
return;
}
db->execLater(generateNewMessageQueries(friendPk, message, sender, time,
isSent, dispName, insertIdCallback));
}
/**
@ -215,13 +259,21 @@ void History::addNewMessage(const QString &friendPk, const QString &message, con @@ -215,13 +259,21 @@ void History::addNewMessage(const QString &friendPk, const QString &message, con
* @param to End of period to fetch.
* @return List of messages.
*/
QList<History::HistMessage> History::getChatHistory(const QString &friendPk, const QDateTime &from, const QDateTime &to)
QList<History::HistMessage> History::getChatHistory(const QString& friendPk,
const QDateTime& from,
const QDateTime& to)
{
if (!isValid())
{
return {};
}
QList<HistMessage> messages;
auto rowCallback = [&messages](const QVector<QVariant>& row)
{
// dispName and message could have null bytes, QString::fromUtf8 truncates on null bytes so we strip them
// dispName and message could have null bytes, QString::fromUtf8
// truncates on null bytes so we strip them
messages += {row[0].toLongLong(),
row[1].isNull(),
QDateTime::fromMSecsSinceEpoch(row[2].toLongLong()),
@ -232,14 +284,18 @@ QList<History::HistMessage> History::getChatHistory(const QString &friendPk, con @@ -232,14 +284,18 @@ QList<History::HistMessage> History::getChatHistory(const QString &friendPk, con
};
// Don't forget to update the rowCallback if you change the selected columns!
db.execNow({QString("SELECT history.id, faux_offline_pending.id, timestamp, chat.public_key, "
"aliases.display_name, sender.public_key, message FROM history "
QString queryText = QString(
"SELECT history.id, faux_offline_pending.id, timestamp, "
"chat.public_key, aliases.display_name, sender.public_key, "
"message FROM history "
"LEFT JOIN faux_offline_pending ON history.id = faux_offline_pending.id "
"JOIN peers chat ON chat_id = chat.id "
"JOIN aliases ON sender_alias = aliases.id "
"JOIN peers sender ON aliases.owner = sender.id "
"WHERE timestamp BETWEEN %1 AND %2 AND chat.public_key='%3';")
.arg(from.toMSecsSinceEpoch()).arg(to.toMSecsSinceEpoch()).arg(friendPk), rowCallback});
.arg(from.toMSecsSinceEpoch()).arg(to.toMSecsSinceEpoch()).arg(friendPk);
db->execNow({queryText, rowCallback});
return messages;
}
@ -250,45 +306,15 @@ QList<History::HistMessage> History::getChatHistory(const QString &friendPk, con @@ -250,45 +306,15 @@ QList<History::HistMessage> History::getChatHistory(const QString &friendPk, con
*
* @param id Message ID.
*/
void History::markAsSent(qint64 id)
{
db.execLater(QString("DELETE FROM faux_offline_pending WHERE id=%1;").arg(id));
}
/**
* @brief Retrieves the path to the database file for a given profile.
* @param profileName Profile name.
* @return Path to database.
*/
QString History::getDbPath(const QString &profileName)
{
return Settings::getInstance().getSettingsDirPath() + profileName + ".db";
}
/**
* @brief Makes sure the history tables are created
*/
void History::init()
void History::markAsSent(qint64 messageId)
{
if (!isValid())
{
qWarning() << "Database not open, init failed";
return;
}
db.execLater("CREATE TABLE IF NOT EXISTS peers (id INTEGER PRIMARY KEY, public_key TEXT NOT NULL UNIQUE);"
"CREATE TABLE IF NOT EXISTS aliases (id INTEGER PRIMARY KEY, owner INTEGER,"
"display_name BLOB NOT NULL, UNIQUE(owner, display_name));"
"CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, "
"chat_id INTEGER NOT NULL, sender_alias INTEGER NOT NULL, "
"message BLOB NOT NULL);"
"CREATE TABLE IF NOT EXISTS faux_offline_pending (id INTEGER PRIMARY KEY);");
// Cache our current peers
db.execLater(RawDatabase::Query{"SELECT public_key, id FROM peers;", [this](const QVector<QVariant>& row)
{
peers[row[0].toString()] = row[1].toInt();
}});
db->execLater(QString("DELETE FROM faux_offline_pending WHERE id=%1;")
.arg(messageId));
}
/**
@ -312,14 +338,15 @@ void History::import(const HistoryKeeper &oldHistory) @@ -312,14 +338,15 @@ void History::import(const HistoryKeeper &oldHistory)
QList<HistoryKeeper::HistMessage> oldMessages = oldHistory.exportMessagesDeleteFile();
for (const HistoryKeeper::HistMessage& msg : oldMessages)
{
queries += generateNewMessageQueries(msg.chat, msg.message, msg.sender, msg.timestamp, true, msg.dispName);
queries += generateNewMessageQueries(msg.chat, msg.message, msg.sender,
msg.timestamp, true, msg.dispName);
if (queries.size() >= batchSize)
{
db.execLater(queries);
db->execLater(queries);
queries.clear();
}
}
db.execLater(queries);
db.sync();
db->execLater(queries);
db->sync();
qDebug() << "Imported old database in" << t.elapsed() << "ms";
}

59
src/persistence/history.h

@ -1,24 +1,48 @@ @@ -1,24 +1,48 @@
/*
Copyright © 2015-2016 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HISTORY_H
#define HISTORY_H
#include <tox/toxencryptsave.h>
#include <QDateTime>
#include <QVector>
#include <QHash>
#include <cstdint>
#include <tox/toxencryptsave.h>
#include "src/persistence/db/rawdatabase.h"
class Profile;
class HistoryKeeper;
class RawDatabase;
class History
{
public:
struct HistMessage
{
HistMessage(qint64 id, bool isSent, QDateTime timestamp, QString chat, QString dispName, QString sender, QString message) :
chat{chat}, sender{sender}, message{message}, dispName{dispName}, timestamp{timestamp}, id{id}, isSent{isSent} {}
HistMessage(qint64 id, bool isSent, QDateTime timestamp, QString chat,
QString dispName, QString sender, QString message)
: chat{chat}, sender{sender}, message{message}, dispName{dispName}
, timestamp{timestamp}, id{id}, isSent{isSent}
{
}
QString chat;
QString sender;
@ -30,33 +54,32 @@ public: @@ -30,33 +54,32 @@ public:
};
public:
History(const QString& profileName, const QString& password);
History(const QString& profileName, const QString& password, const HistoryKeeper& oldHistory);
History(std::shared_ptr<RawDatabase> db);
~History();
bool isValid();
void import(const HistoryKeeper& oldHistory);
void setPassword(const QString& password);
void rename(const QString& newName);
bool remove();
void eraseHistory();
void removeFriendHistory(const QString& friendPk);
void addNewMessage(const QString& friendPk, const QString& message, const QString& sender,
const QDateTime &time, bool isSent, QString dispName,
void addNewMessage(const QString& friendPk, const QString& message,
const QString& sender, const QDateTime& time,
bool isSent, QString dispName,
std::function<void(int64_t)> insertIdCallback={});
QList<HistMessage> getChatHistory(const QString& friendPk, const QDateTime &from, const QDateTime &to);
void markAsSent(qint64 id);
static QString getDbPath(const QString& profileName);
QList<HistMessage> getChatHistory(const QString& friendPk,
const QDateTime& from,
const QDateTime& to);
void markAsSent(qint64 messageId);
protected:
void init();
QVector<RawDatabase::Query> generateNewMessageQueries(const QString& friendPk, const QString& message,
const QString& sender, const QDateTime &time, bool isSent, QString dispName,
QVector<RawDatabase::Query> generateNewMessageQueries(
const QString& friendPk, const QString& message,
const QString& sender, const QDateTime& time,
bool isSent, QString dispName,
std::function<void(int64_t)> insertIdCallback={});
private:
RawDatabase db;
std::shared_ptr<RawDatabase> db;
QHash<QString, int64_t> peers;
};

113
src/persistence/profile.cpp

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
Copyright © 2015 by The qTox Project
Copyright © 2015-2016 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
@ -18,23 +18,25 @@ @@ -18,23 +18,25 @@
*/
#include "profile.h"
#include "profilelocker.h"
#include "src/persistence/settings.h"
#include "src/persistence/historykeeper.h"
#include "src/core/core.h"
#include "src/widget/gui.h"
#include "src/widget/widget.h"
#include "src/nexus.h"
#include <cassert>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QObject>
#include <QSaveFile>
#include <QThread>
#include <QObject>
#include <QDebug>
#include <cassert>
#include <sodium.h>
#include "profile.h"
#include "profilelocker.h"
#include "settings.h"
#include "historykeeper.h"
#include "src/core/core.h"
#include "src/nexus.h"
#include "src/widget/gui.h"
#include "src/widget/widget.h"
/**
* @class Profile
* @brief Manages user profiles.
@ -53,24 +55,30 @@ @@ -53,24 +55,30 @@
QVector<QString> Profile::profiles;
Profile::Profile(QString name, const QString& password, bool isNewProfile)
: name{name}, password{password},
newProfile{isNewProfile}, isRemoved{false}
: name{name}, password{password}
, database(std::make_shared<RawDatabase>(getDbPath(name), password))
, newProfile{isNewProfile}, isRemoved{false}
{
if (!password.isEmpty())
{
passkey = *core->createPasskey(password);
}
Settings& s = Settings::getInstance();
s.setCurrentProfile(name);
s.saveGlobal();
// At this point it's too early to load the personal settings (Nexus will do it), so we always load
// the history, and if it fails we can't change the setting now, but we keep a nullptr
history.reset(new History{name, password});
if (!history->isValid())
// At this point it's too early to load the personal settings (Nexus will do
// it), so we always load the history, and if it fails we can't change the
// setting now, but we keep a nullptr
if (database->isOpen())
{
history.reset(new History(database));
}
else
{
qWarning() << "Failed to open history for profile" << name;
GUI::showError(QObject::tr("Error"), QObject::tr("qTox couldn't open your chat logs, they will be disabled."));
history.release();
}
coreThread = new QThread();
@ -155,13 +163,18 @@ Profile* Profile::loadProfile(QString name, const QString &password) @@ -155,13 +163,18 @@ Profile* Profile::loadProfile(QString name, const QString &password)
else
{
if (!password.isEmpty())
{
qWarning() << "We have a password, but the tox save file is not encrypted";
}
}
}
Profile* p = new Profile(name, password, false);
if (p->history && HistoryKeeper::isFileExist(!password.isEmpty()))
{
p->history->import(*HistoryKeeper::getInstance(*p));
}
return p;
}
@ -200,7 +213,10 @@ Profile* Profile::createProfile(QString name, QString password) @@ -200,7 +213,10 @@ Profile* Profile::createProfile(QString name, QString password)
Profile::~Profile()
{
if (!isRemoved && core->isReady())
{
saveToxSave();
}
delete core;
delete coreThread;
if (!isRemoved)
@ -227,7 +243,10 @@ QVector<QString> Profile::getFilesByExt(QString extension) @@ -227,7 +243,10 @@ QVector<QString> Profile::getFilesByExt(QString extension)
QFileInfoList list = dir.entryInfoList();
out.reserve(list.size());
for (QFileInfo file : list)
{
out += file.completeBaseName();
}
return out;
}
@ -242,7 +261,10 @@ void Profile::scanProfiles() @@ -242,7 +261,10 @@ void Profile::scanProfiles()
for (QString toxfile : toxfiles)
{
if (!inifiles.contains(toxfile))
{
Settings::getInstance().createPersonal(toxfile);
}
profiles.append(toxfile);
}
}
@ -324,13 +346,17 @@ QByteArray Profile::loadToxSave() @@ -324,13 +346,17 @@ QByteArray Profile::loadToxSave()
data = core->decryptData(data, passkey);
if (data.isEmpty())
{
qCritical() << "Failed to decrypt the tox save file";
}
}
else
{
if (!password.isEmpty())
{
qWarning() << "We have a password, but the tox save file is not encrypted";
}
}
fail:
saveFile.close();
@ -470,7 +496,9 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo @@ -470,7 +496,9 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
{
return {};
}
QByteArray pic = file.readAll();
if (encrypted && !pic.isEmpty())
@ -480,6 +508,7 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo @@ -480,6 +508,7 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo
auto passkey = core->createPasskey(password, salt);
pic = core->decryptData(pic, *passkey);
}
return pic;
}
@ -491,7 +520,9 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo @@ -491,7 +520,9 @@ QByteArray Profile::loadAvatarData(const QString &ownerId, const QString &passwo
void Profile::saveAvatar(QByteArray pic, const QString& ownerId)
{
if (!password.isEmpty() && !pic.isEmpty())
{
pic = core->encryptData(pic, passkey);
}
QString path = avatarPath(ownerId);
QDir(Settings::getInstance().getSettingsDirPath()).mkdir("avatars");
@ -656,15 +687,14 @@ QVector<QString> Profile::remove() @@ -656,15 +687,14 @@ QVector<QString> Profile::remove()
qWarning() << "Could not remove file " << historyLegacyUnencrypted.fileName();
}
if (history)
{
if (!history->remove() && QFile::exists(History::getDbPath(name)))
QString dbPath = getDbPath(name);
if (database->isOpen() && !database->remove() && QFile::exists(dbPath))
{
ret.push_back(History::getDbPath(name));
qWarning() << "Could not remove file " << History::getDbPath(name);
ret.push_back(dbPath);
qWarning() << "Could not remove file " << dbPath;
}
history.release();
}
database.reset();
return ret;
}
@ -680,17 +710,24 @@ bool Profile::rename(QString newName) @@ -680,17 +710,24 @@ bool Profile::rename(QString newName)
newPath = Settings::getInstance().getSettingsDirPath() + newName;
if (!ProfileLocker::lock(newName))
{
return false;
}
QFile::rename(path + ".tox", newPath + ".tox");
QFile::rename(path + ".ini", newPath + ".ini");
if (history)
history->rename(newName);
if (database)
{
database->rename(newName);
}
bool resetAutorun = Settings::getInstance().getAutorun();
Settings::getInstance().setAutorun(false);
Settings::getInstance().setCurrentProfile(newName);
if (resetAutorun)
{
Settings::getInstance().setAutorun(true); // fixes -p flag in autostart command line
}
name = newName;
return true;
@ -703,7 +740,9 @@ bool Profile::rename(QString newName) @@ -703,7 +740,9 @@ bool Profile::rename(QString newName)
bool Profile::checkPassword()
{
if (isRemoved)
{
return false;
}
return !loadToxSave().isEmpty();
}
@ -725,7 +764,10 @@ void Profile::restartCore() @@ -725,7 +764,10 @@ void Profile::restartCore()
{
GUI::setEnabled(false); // Core::reset re-enables it
if (!isRemoved && core->isReady())
{
saveToxSave();
}
QMetaObject::invokeMethod(core, "reset");
}
@ -741,11 +783,12 @@ void Profile::setPassword(const QString &newPassword) @@ -741,11 +783,12 @@ void Profile::setPassword(const QString &newPassword)
passkey = *core->createPasskey(password);
saveToxSave();
if (history)
if (database)
{
history->setPassword(newPassword);
Nexus::getDesktopGUI()->reloadHistory();
database->setPassword(newPassword);
}
Nexus::getDesktopGUI()->reloadHistory();
saveAvatar(avatar, core->getSelfId().publicKey);
QVector<uint32_t> friendList = core->getFriendList();
@ -756,3 +799,13 @@ void Profile::setPassword(const QString &newPassword) @@ -756,3 +799,13 @@ void Profile::setPassword(const QString &newPassword)
saveAvatar(loadAvatarData(friendPublicKey,oldPassword),friendPublicKey);
}
}
/**
* @brief Retrieves the path to the database file for a given profile.
* @param profileName Profile name.
* @return Path to database.
*/
QString Profile::getDbPath(const QString& profileName)
{
return Settings::getInstance().getSettingsDirPath() + profileName + ".db";
}

4
src/persistence/profile.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
Copyright © 2015 by The qTox Project
Copyright © 2015-2016 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
@ -76,6 +76,7 @@ public: @@ -76,6 +76,7 @@ public:
static bool exists(QString name);
static bool isEncrypted(QString name);
static QString getDbPath(const QString& profileName);
private:
Profile(QString name, const QString& password, bool newProfile);
@ -87,6 +88,7 @@ private: @@ -87,6 +88,7 @@ private:
QThread* coreThread;
QString name, password;
TOX_PASS_KEY passkey;
std::shared_ptr<RawDatabase> database;
std::unique_ptr<History> history;
bool newProfile;
bool isRemoved;

Loading…
Cancel
Save