mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
Fix ZeldaZach review for PR 7496: deck path in ctor, server-time baseline, single-query sync check
This commit is contained in:
parent
477605d1e0
commit
1433af321d
6 changed files with 30 additions and 41 deletions
|
|
@ -299,11 +299,9 @@ void DeckSyncManager::syncNow()
|
|||
.modified = QFileInfo(absolutePath).lastModified()});
|
||||
}
|
||||
|
||||
if (!firstSyncRun && sidecar.lastSyncSecs > 0) {
|
||||
sendSyncCheck(sidecar.lastSyncSecs);
|
||||
return;
|
||||
}
|
||||
fetchFullList();
|
||||
// Always ask the server first: its server_time becomes the sync baseline,
|
||||
// so uploads racing the DeckList response cannot fall outside the window.
|
||||
sendSyncCheck(sidecar.lastSyncSecs);
|
||||
}
|
||||
|
||||
void DeckSyncManager::fetchFullList()
|
||||
|
|
@ -334,6 +332,9 @@ void DeckSyncManager::onCheckFinished(const Response &response, const CommandCon
|
|||
return;
|
||||
}
|
||||
const Response_DeckSyncStatus &status = response.GetExtension(Response_DeckSyncStatus::ext);
|
||||
if (status.has_server_time()) {
|
||||
pendingServerTime = static_cast<qint64>(status.server_time());
|
||||
}
|
||||
DeckSyncSidecar sidecar(sidecarPath);
|
||||
if (!sidecar.load()) {
|
||||
fetchFullList();
|
||||
|
|
|
|||
|
|
@ -260,6 +260,13 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
|
||||
syncManager = new DeckSyncManager(
|
||||
client, [](const DeckList &deck) { return getDeckColorIdentity(deck, CardDatabaseManager::query()); }, this);
|
||||
syncManager->setDeckPath(SettingsCache::instance().paths().getDeckPath());
|
||||
connect(&SettingsCache::instance().paths(), &PathsSettings::deckPathChanged, this, [this] {
|
||||
const QString deckPath = SettingsCache::instance().paths().getDeckPath();
|
||||
localDirModel->setRootPath(deckPath);
|
||||
localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0));
|
||||
syncManager->setDeckPath(deckPath);
|
||||
});
|
||||
syncManager->setConflictDefault(SettingsCache::instance().deckSync().getConflictDefault());
|
||||
syncManager->setAutoSyncEnabled(SettingsCache::instance().deckSync().getAutoSync());
|
||||
syncManager->setSyncIntervalMinutes(SettingsCache::instance().deckSync().getSyncIntervalMinutes());
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ QString PathsSettings::getRedirectCachePath() const
|
|||
void PathsSettings::setDeckPath(const QString &_deckPath)
|
||||
{
|
||||
setValue(_deckPath, "decks");
|
||||
emit deckPathChanged();
|
||||
}
|
||||
|
||||
void PathsSettings::setFiltersPath(const QString &_filtersPath)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
void setAppDirWarningAcknowledged(bool _appDirWarningAcknowledged);
|
||||
|
||||
signals:
|
||||
void deckPathChanged();
|
||||
void cardDatabasePathChanged();
|
||||
void picsPathChanged();
|
||||
void themeChanged();
|
||||
|
|
|
|||
|
|
@ -898,51 +898,31 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckSetVisibility(const
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
bool AbstractServerSocketInterface::syncCheckHelper(int folderId,
|
||||
const QString &prefix,
|
||||
int userId,
|
||||
qint64 sinceSecs,
|
||||
Response_DeckSyncStatus *status)
|
||||
bool AbstractServerSocketInterface::syncCheckHelper(int userId, qint64 sinceSecs, Response_DeckSyncStatus *status)
|
||||
{
|
||||
QSqlQuery *query = sqlInterface->prepareQuery("select id, name from {prefix}_decklist_folders where id_parent = "
|
||||
":id_parent and id_user = :id_user");
|
||||
query->bindValue(":id_parent", folderId);
|
||||
query->bindValue(":id_user", userId);
|
||||
if (!sqlInterface->execSqlQuery(query)) {
|
||||
return false;
|
||||
}
|
||||
QList<std::pair<int, QString>> subfolders;
|
||||
while (query->next()) {
|
||||
subfolders.append({query->value(0).toInt(), query->value(1).toString()});
|
||||
}
|
||||
for (const auto &[subfolderId, subfolderName] : subfolders) {
|
||||
const QString path = prefix.isEmpty() ? subfolderName : prefix + "/" + subfolderName;
|
||||
if (!syncCheckHelper(subfolderId, path, userId, sinceSecs, status)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
query = sqlInterface->prepareQuery("select id, name, guid, hash, last_modified, deleted from "
|
||||
"{prefix}_decklist_files where id_folder = :id_folder and id_user = :id_user "
|
||||
"and (last_modified is null or last_modified > FROM_UNIXTIME(:since))");
|
||||
query->bindValue(":id_folder", folderId);
|
||||
// Single query over the user's files: folder rows are hard-deleted while
|
||||
// their files linger as tombstones, so walking the live folder tree would
|
||||
// miss deletes pointing at nonexistent folders. The client only checks
|
||||
// changed_files_size(), so folder paths are not reconstructed here.
|
||||
QSqlQuery *query = sqlInterface->prepareQuery("select id, guid, hash, last_modified, deleted from "
|
||||
"{prefix}_decklist_files where id_user = :id_user "
|
||||
"and (last_modified is null or last_modified >= "
|
||||
"FROM_UNIXTIME(:since))");
|
||||
query->bindValue(":id_user", userId);
|
||||
query->bindValue(":since", sinceSecs);
|
||||
if (!sqlInterface->execSqlQuery(query)) {
|
||||
return false;
|
||||
}
|
||||
while (query->next()) {
|
||||
const QString name = query->value(1).toString();
|
||||
DeckSyncChangedFile *changed = status->add_changed_files();
|
||||
changed->set_path((prefix.isEmpty() ? name : prefix + "/" + name).toStdString());
|
||||
changed->set_deck_id(query->value(0).toUInt());
|
||||
changed->set_guid(query->value(2).toString().toStdString());
|
||||
changed->set_hash(query->value(3).toString().toStdString());
|
||||
const QDateTime lastModified = query->value(4).toDateTime();
|
||||
changed->set_guid(query->value(1).toString().toStdString());
|
||||
changed->set_hash(query->value(2).toString().toStdString());
|
||||
const QDateTime lastModified = query->value(3).toDateTime();
|
||||
if (lastModified.isValid()) {
|
||||
changed->set_last_modified(lastModified.toSecsSinceEpoch());
|
||||
}
|
||||
changed->set_deleted(query->value(5).toBool());
|
||||
changed->set_deleted(query->value(4).toBool());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -957,7 +937,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckSyncCheck(const Com
|
|||
sqlInterface->checkSql();
|
||||
|
||||
Response_DeckSyncStatus *re = new Response_DeckSyncStatus;
|
||||
if (!syncCheckHelper(0, QString(), userInfo->id(), static_cast<qint64>(cmd.last_sync_time()), re)) {
|
||||
if (!syncCheckHelper(userInfo->id(), static_cast<qint64>(cmd.last_sync_time()), re)) {
|
||||
delete re;
|
||||
return Response::RespContextError;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,8 +165,7 @@ private:
|
|||
bool storeDeckVersion(int deckId, const QString &content, const QString &hash);
|
||||
DeckList *getDeckFromDatabase(int deckId);
|
||||
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc);
|
||||
bool
|
||||
syncCheckHelper(int folderId, const QString &prefix, int userId, qint64 sinceSecs, Response_DeckSyncStatus *status);
|
||||
bool syncCheckHelper(int userId, qint64 sinceSecs, Response_DeckSyncStatus *status);
|
||||
Response::ResponseCode cmdDeckSyncCheck(const Command_DeckSyncCheck &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdDeckDownloadPublic(const Command_DeckDownloadPublic &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdDeckShareCreate(const Command_DeckShareCreate &cmd, ResponseContainer &rc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue