[Client] DeckSyncProfile + sidecar + DeckDiff with tests

This commit is contained in:
Lukas Brübach 2026-10-11 14:26:12 +02:00 • committed by Lukas Brübach
parent 11fdfb4610
commit 1e97ab086b
12 changed files with 740 additions and 0 deletions

View file

@ -0,0 +1,97 @@
#include "deck_sync_sidecar.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
namespace
{
constexpr int SIDECAR_FORMAT_VERSION = 1;
} // namespace
DeckSyncSidecar::DeckSyncSidecar(const QString &_filePath) : filePath(_filePath)
{
}
bool DeckSyncSidecar::load()
{
recordMap.clear();
QFile file(filePath);
if (!file.exists()) {
return true;
}
if (!file.open(QIODevice::ReadOnly)) {
return false;
}
const QJsonDocument document = QJsonDocument::fromJson(file.readAll());
if (!document.isObject() || !document.object().value("records").isObject()) {
return false;
}
const QJsonObject records = document.object().value("records").toObject();
for (auto it = records.begin(); it != records.end(); ++it) {
if (!it.value().isObject()) {
continue;
}
const QJsonObject entry = it.value().toObject();
const DeckSyncRecord record{.guid = entry.value("guid").toString(),
.remoteId = entry.value("remoteId").toInt(-1),
.baseHash = entry.value("baseHash").toString(),
.lastSyncSecs = static_cast<qint64>(entry.value("lastSync").toDouble()),
.deleted = entry.value("deleted").toBool(false)};
recordMap.insert(it.key(), record);
}
return true;
}
bool DeckSyncSidecar::save() const
{
QJsonObject records;
for (auto it = recordMap.begin(); it != recordMap.end(); ++it) {
QJsonObject entry;
entry.insert("guid", it.value().guid);
entry.insert("remoteId", it.value().remoteId);
entry.insert("baseHash", it.value().baseHash);
entry.insert("lastSync", static_cast<double>(it.value().lastSyncSecs));
entry.insert("deleted", it.value().deleted);
records.insert(it.key(), entry);
}
QJsonObject root;
root.insert("version", SIDECAR_FORMAT_VERSION);
root.insert("records", records);
QDir().mkpath(QFileInfo(filePath).absolutePath());
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return false;
}
file.write(QJsonDocument(root).toJson(QJsonDocument::Compact));
return true;
}
bool DeckSyncSidecar::contains(const QString &relativePath) const
{
return recordMap.contains(relativePath);
}
DeckSyncRecord DeckSyncSidecar::get(const QString &relativePath) const
{
return recordMap.value(relativePath, DeckSyncRecord());
}
void DeckSyncSidecar::set(const QString &relativePath, const DeckSyncRecord &record)
{
recordMap.insert(relativePath, record);
}
void DeckSyncSidecar::remove(const QString &relativePath)
{
recordMap.remove(relativePath);
}
QMap<QString, DeckSyncRecord> DeckSyncSidecar::records() const
{
return recordMap;
}