Browse Source

feat(db): add file hash to file history

Not currently used, but there are plans to display if a transfered file
has been modified, which the file hash will be needed for. Adding file
hash at the same time as file history also saves a db schema update.
reviewable/pr5354/r9
Anthony Bilinski 7 years ago committed by Mick Sayson
parent
commit
8427be6678
  1. 2
      src/core/corefile.cpp
  2. 2
      src/core/toxfile.h
  3. 20
      src/persistence/history.cpp
  4. 5
      src/persistence/history.h
  5. 6
      src/widget/form/chatform.cpp

2
src/core/corefile.cpp

@ -438,6 +438,7 @@ void CoreFile::onFileDataCallback(Tox* tox, uint32_t friendId, uint32_t fileId,
return; return;
} }
file->bytesSent += length; file->bytesSent += length;
file->hashGenerator->addData((const char*)data.get(), length);
} }
if (!tox_file_send_chunk(tox, friendId, fileId, pos, data.get(), nread, nullptr)) { if (!tox_file_send_chunk(tox, friendId, fileId, pos, data.get(), nread, nullptr)) {
@ -492,6 +493,7 @@ void CoreFile::onFileRecvChunkCallback(Tox* tox, uint32_t friendId, uint32_t fil
else else
file->file->write((char*)data, length); file->file->write((char*)data, length);
file->bytesSent += length; file->bytesSent += length;
file->hashGenerator->addData((const char*)data, length);
if (file->fileKind != TOX_FILE_KIND_AVATAR) if (file->fileKind != TOX_FILE_KIND_AVATAR)
emit static_cast<Core*>(core)->fileTransferInfo(*file); emit static_cast<Core*>(core)->fileTransferInfo(*file);

2
src/core/toxfile.h

@ -3,6 +3,7 @@
#include <QString> #include <QString>
#include <memory> #include <memory>
#include <QCryptographicHash>
class QFile; class QFile;
class QTimer; class QTimer;
@ -51,6 +52,7 @@ struct ToxFile
FileDirection direction; FileDirection direction;
QByteArray avatarData; QByteArray avatarData;
QByteArray resumeFileId; QByteArray resumeFileId;
std::shared_ptr<QCryptographicHash> hashGenerator = std::make_shared<QCryptographicHash>(QCryptographicHash::Sha256);
}; };
#endif // CORESTRUCTS_H #endif // CORESTRUCTS_H

20
src/persistence/history.cpp

@ -90,6 +90,7 @@ History::History(std::shared_ptr<RawDatabase> db)
"file_restart_id BLOB NOT NULL," "file_restart_id BLOB NOT NULL,"
"file_name BLOB NOT NULL, " "file_name BLOB NOT NULL, "
"file_path BLOB NOT NULL," "file_path BLOB NOT NULL,"
"file_hash BLOB NOT NULL,"
"file_size INTEGER NOT NULL," "file_size INTEGER NOT NULL,"
"direction INTEGER NOT NULL," "direction INTEGER NOT NULL,"
"file_state INTEGER NOT NULL);" "file_state INTEGER NOT NULL);"
@ -279,13 +280,13 @@ void History::onFileInsertionReady(FileDbInsertionData data)
auto fileId = data.fileId; auto fileId = data.fileId;
queries += queries +=
RawDatabase::Query(QStringLiteral("INSERT INTO file_transfers (chat_id, file_restart_id, " RawDatabase::Query(QStringLiteral("INSERT INTO file_transfers (chat_id, file_restart_id, "
"file_path, file_name, file_size, direction, file_state) " "file_path, file_name, file_hash, file_size, direction, file_state) "
"VALUES (%1, ?, ?, ?, %2, %3, %4);") "VALUES (%1, ?, ?, ?, ?, %2, %3, %4);")
.arg(peerId) .arg(peerId)
.arg(data.size) .arg(data.size)
.arg(static_cast<int>(data.direction)) .arg(static_cast<int>(data.direction))
.arg(ToxFile::CANCELED), .arg(ToxFile::CANCELED),
{data.fileId.toUtf8(), data.filePath.toUtf8(), data.fileName}, {data.fileId.toUtf8(), data.filePath.toUtf8(), data.fileName, QByteArray()},
[weakThis, fileId](int64_t id) { [weakThis, fileId](int64_t id) {
auto pThis = weakThis.lock(); auto pThis = weakThis.lock();
if (pThis) { if (pThis) {
@ -306,7 +307,7 @@ void History::onFileInserted(int64_t dbId, QString fileId)
{ {
auto& fileInfo = fileInfos[fileId]; auto& fileInfo = fileInfos[fileId];
if (fileInfo.finished) { if (fileInfo.finished) {
db->execLater(generateFileFinished(dbId, fileInfo.success, fileInfo.filePath)); db->execLater(generateFileFinished(dbId, fileInfo.success, fileInfo.filePath, fileInfo.fileHash));
fileInfos.remove(fileId); fileInfos.remove(fileId);
} else { } else {
fileInfo.finished = false; fileInfo.finished = false;
@ -314,16 +315,16 @@ void History::onFileInserted(int64_t dbId, QString fileId)
} }
} }
RawDatabase::Query History::generateFileFinished(int64_t id, bool success, const QString& filePath) RawDatabase::Query History::generateFileFinished(int64_t id, bool success, const QString& filePath, const QByteArray& fileHash)
{ {
auto file_state = success ? ToxFile::FINISHED : ToxFile::CANCELED; auto file_state = success ? ToxFile::FINISHED : ToxFile::CANCELED;
if (filePath.length()) { if (filePath.length()) {
return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " return RawDatabase::Query(QStringLiteral("UPDATE file_transfers "
"SET file_state = %1, file_path = ? " "SET file_state = %1, file_path = ?, file_hash = ?"
"WHERE id = %2") "WHERE id = %2")
.arg(file_state) .arg(file_state)
.arg(id), .arg(id),
{filePath.toUtf8()}); {filePath.toUtf8(), fileHash});
} else { } else {
return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " return RawDatabase::Query(QStringLiteral("UPDATE file_transfers "
"SET finished = %1 " "SET finished = %1 "
@ -405,15 +406,16 @@ void History::addNewMessage(const QString& friendPk, const QString& message, con
insertIdCallback)); insertIdCallback));
} }
void History::setFileFinished(const QString& fileId, bool success, const QString& filePath) void History::setFileFinished(const QString& fileId, bool success, const QString& filePath, const QByteArray& fileHash)
{ {
auto& fileInfo = fileInfos[fileId]; auto& fileInfo = fileInfos[fileId];
if (fileInfo.fileId == -1) { if (fileInfo.fileId == -1) {
fileInfo.finished = true; fileInfo.finished = true;
fileInfo.success = success; fileInfo.success = success;
fileInfo.filePath = filePath; fileInfo.filePath = filePath;
fileInfo.fileHash = fileHash;
} else { } else {
db->execLater(generateFileFinished(fileInfo.fileId, success, filePath)); db->execLater(generateFileFinished(fileInfo.fileId, success, filePath, fileHash));
} }
fileInfos.remove(fileId); fileInfos.remove(fileId);

5
src/persistence/history.h

@ -167,7 +167,7 @@ public:
const QByteArray& fileName, const QString& filePath, int64_t size, const QByteArray& fileName, const QString& filePath, int64_t size,
const QString& sender, const QDateTime& time, QString const& dispName); const QString& sender, const QDateTime& time, QString const& dispName);
void setFileFinished(const QString& fileId, bool success, const QString& filePath); void setFileFinished(const QString& fileId, bool success, const QString& filePath, const QByteArray& fileHash);
QList<HistMessage> getChatHistoryFromDate(const QString& friendPk, const QDateTime& from, QList<HistMessage> getChatHistoryFromDate(const QString& friendPk, const QDateTime& from,
const QDateTime& to); const QDateTime& to);
@ -198,7 +198,7 @@ private:
const QDateTime& to, int numMessages); const QDateTime& to, int numMessages);
static RawDatabase::Query generateFileFinished(int64_t fileId, bool success, static RawDatabase::Query generateFileFinished(int64_t fileId, bool success,
const QString& filePath); const QString& filePath, const QByteArray& fileHash);
void dbSchemaUpgrade(); void dbSchemaUpgrade();
std::shared_ptr<RawDatabase> db; std::shared_ptr<RawDatabase> db;
@ -210,6 +210,7 @@ private:
bool finished = false; bool finished = false;
bool success = false; bool success = false;
QString filePath; QString filePath;
QByteArray fileHash;
int64_t fileId = -1; int64_t fileId = -1;
}; };

6
src/widget/form/chatform.cpp

@ -329,19 +329,19 @@ void ChatForm::startFileSend(ToxFile file)
void ChatForm::onFileTransferFinished(ToxFile file) void ChatForm::onFileTransferFinished(ToxFile file)
{ {
history->setFileFinished(file.resumeFileId, true, file.filePath); history->setFileFinished(file.resumeFileId, true, file.filePath, file.hashGenerator->result());
} }
void ChatForm::onFileTransferBrokenUnbroken(ToxFile file, bool broken) void ChatForm::onFileTransferBrokenUnbroken(ToxFile file, bool broken)
{ {
if (broken) { if (broken) {
history->setFileFinished(file.resumeFileId, false, file.filePath); history->setFileFinished(file.resumeFileId, false, file.filePath, file.hashGenerator->result());
} }
} }
void ChatForm::onFileTransferCancelled(ToxFile file) void ChatForm::onFileTransferCancelled(ToxFile file)
{ {
history->setFileFinished(file.resumeFileId, false, file.filePath); history->setFileFinished(file.resumeFileId, false, file.filePath, file.hashGenerator->result());
} }
void ChatForm::onFileRecvRequest(ToxFile file) void ChatForm::onFileRecvRequest(ToxFile file)

Loading…
Cancel
Save