From e52c293a41af27b00a917733a3d88ad217b28bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 25 Nov 2019 09:23:18 +0100 Subject: [PATCH] add checks and fix bugs --- src/colnod/databaseapi.cpp | 32 ++++++++++++++++++++++++++------ src/colnod/databaseapi.h | 5 ++++- src/colnod/syncmanager.cpp | 25 ++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index cadd378..4233d92 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -96,6 +96,18 @@ void DatabaseAPI::setLastUpdate(const QHash> &to qInfo(database) << equals; } +void DatabaseAPI::setLastUpdate(const QList ids) +{ + auto query = mDbMan->createQuery(); + for (const auto &id : ids){ + query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id"); + query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(getNow()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":id", id); + mDbMan->executeQuery(query); + } + +} + qint64 DatabaseAPI::getNow() { auto query = mDbMan->execPlainSql("SELECT EXTRACT(EPOCH FROM NOW())*1000"); @@ -105,15 +117,14 @@ qint64 DatabaseAPI::getNow() void DatabaseAPI::initNewTokens() { - auto query = mDbMan->execPlainSql("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " - "FROM colnod_token WHERE name IS NULL"); + auto query = mDbMan->execPlainSql("SELECT * FROM colnod_token WHERE name IS NULL"); QHash> tokensToInit; - while (query.next()){ - auto token = std::make_shared(); - token->fromSQLRecord(query); + auto list = utils->tableFromQuery(query); + for (const auto &token : list) { qint16 num = getNumOfTokensOfSubject(token->subjectId()); token->setName(getSubjectNameByTokenId(token->id()) + "_mobile_" + QString::number(num + 1)); token->setDescription("mobile"); + token->setTokenData(token->tokenData().toUpper()); tokensToInit.insert(token->id(), token); } uploadTokens(tokensToInit); @@ -166,7 +177,7 @@ void DatabaseAPI::deleteItems(const QList &ids, const QString &tableNam } } -std::shared_ptr DatabaseAPI::getLastUpdate(const QString &id) +std::shared_ptr DatabaseAPI::getToken(const QString &id) { auto query = mDbMan->createQuery(); query.prepare("SELECT * FROM colnod_token WHERE id = :id"); @@ -178,6 +189,15 @@ std::shared_ptr DatabaseAPI::getLastUpdate(const QString &id) return list.at(0); } +bool DatabaseAPI::isAlreadyDeleted(const QString &id) +{ + auto token = getToken(id); + if (token->lastUpdate() >= token->lastModified()) + return true; + return false; + +} + bool DatabaseAPI::exists(const QString &id, const QString &tableName) { auto query = mDbMan->createQuery(); diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index a5e7982..db1f9ea 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -24,6 +24,7 @@ public: qint64 getLastSync(); void setLastSync(qint64 timestamp); void setLastUpdate(const QHash > &tokens); + void setLastUpdate(const QList ids); qint64 getNow(); void initNewTokens(); @@ -33,7 +34,9 @@ public: void uploadSubjects(const QHash > &subjects); void deleteItems(const QList &ids, const QString &tableName); - std::shared_ptr getLastUpdate(const QString &id); + std::shared_ptr getToken(const QString &id); + + bool isAlreadyDeleted(const QString &id); private: bool exists(const QString &id, const QString &tableName); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 0783570..d1dafe4 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -95,23 +95,39 @@ void SyncManager::prepareData() QList conflicts; QList alreadySynced; + // check modifed tokens from colnod, dont want update token, if it was edited in db after or has been already synced for (const auto &colnodToken : colnodDataToProcess->updatedTokens) { if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) { + // updated in db later if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) { conflicts.append(colnodToken->id()); } continue; } - auto token = database->getLastUpdate(colnodToken->id()); + auto token = database->getToken(colnodToken->id()); if ( token ) + // alredy synced ( tokens are same ) if (token == colnodToken) alreadySynced.append(colnodToken->id()); } + // remove tokens which should be not updated for (const auto &id : conflicts) colnodDataToProcess->updatedTokens.remove(id); for (const auto &id : alreadySynced) colnodDataToProcess->updatedTokens.remove(id); + conflicts.clear(); + + // chech for already deleted ( in previous synced tokens were deleted from colnod, so it come to this sync but we dont want to sync it again + for (const auto &id : colnodDataToProcess->deletedTokens) { + if (database->isAlreadyDeleted(id)) { + conflicts.append(id); + } + } + for (const auto &id : conflicts) { + colnodDataToProcess->deletedTokens.removeOne(id); + } + qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE MODIFIED IN DATABASE"; qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; @@ -119,14 +135,16 @@ void SyncManager::prepareData() conflicts.clear(); - for (const auto &databaseToken : databaseData->updatedTokens) { + // chech modified from db, remove token if it was edited in colnod later + for (const auto &databaseToken : databaseDataToProcess->updatedTokens) { if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) { if (databaseToken < colnodDataToProcess->updatedTokens.value(databaseToken->id())) conflicts.append(databaseToken->id()); } else { + // restriction cauesed by colnod rest api if (databaseToken->description() != "mobile") { - qWarning(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description and won't be pushed to Colnod"; + qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; conflicts.append(databaseToken->id()); } } @@ -160,6 +178,7 @@ void SyncManager::updateLastUpdate(qint64 syncBegin) Timestamp time; time.set_timestamp(syncBegin); colnod->getTokensUpdated(time); + database->setLastUpdate(databaseDataToProcess->deletedTokens); connect(colnod.get(), &ColnodAPI::partOfDataReady, [=](const std::shared_ptr &data){ database->setLastUpdate(data->updatedTokens); emit syncFinished();