From 80c550ff033d3c163cce5a412ddeb051995e5461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Thu, 21 Nov 2019 10:39:55 +0100 Subject: [PATCH] Finished Info output --- src/colnod/colnodapi.cpp | 22 +++++++---- src/colnod/colnodapi.h | 1 + src/colnod/databaseapi.cpp | 53 ++++++++++++++++--------- src/colnod/databaseapi.h | 2 +- src/colnod/subject.cpp | 6 +++ src/colnod/subject.h | 2 + src/colnod/syncmanager.cpp | 79 +++++++++++++++++++++++++++++--------- src/colnod/token.cpp | 2 +- 8 files changed, 121 insertions(+), 46 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 051a0e6..099fcba 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -126,6 +126,7 @@ void ColnodAPI::setTokens(const QHash> &tokens) emit partOfDataProcessFinished(); } else { + qWarning(colnod) << "Tokens wasn't updated"; // TODO: error: data wasnt upload to colnod } }); @@ -141,6 +142,7 @@ void ColnodAPI::deleteTokens(const QList &ids) emit partOfDataProcessFinished(); } else { + qWarning(colnod) << "Tokens wasn't deleted"; // TODO: error: data wasnt upload to colnod } }); @@ -188,12 +190,12 @@ void ColnodAPI::areDataReady() { if (++amountData == 4) { - qDebug(colnod) << "COLNOD DATA:"; - qDebug(colnod) << TAB << data->updatedTokens.size() << "TOKENS TO UPDATE"; - qDebug(colnod) << TAB << data->deletedTokens.size() << "TOKENS TO DELETE"; - qDebug(colnod) << TAB << data->updatedSubjects.size() << "SUBJECTS TO UPDATE"; - qDebug(colnod) << TAB << data->deletedSubjects.size() << "SUBJECTS TO DELETE"; - qDebug(colnod) << UNDERSCORE << endl; + qInfo(colnod) << TAB << "-> COLNOD DATA:"; + qInfo(colnod) << TAB << TAB << data->updatedTokens.size() << "TOKENS WERE MODIFIED"; + qInfo(colnod) << TAB << TAB << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION"; + qInfo(colnod) << TAB << TAB << data->updatedSubjects.size() << "SUBJECTS WERE MODIFIED"; + qInfo(colnod) << TAB << TAB << data->deletedSubjects.size() << "SUBJECTS MARKED FOR DELETION"; + qInfo(colnod) << DASH; emit downloadDataFinished(data); newData(); @@ -202,8 +204,14 @@ void ColnodAPI::areDataReady() void ColnodAPI::isDataProcessFinished() { - if (++amountProccessesFinished == 2) + if (++amountProccessesFinished == 2) { + qInfo(colnod) << TAB << "-> DATA PROCESSED TO COLNOD:"; + qInfo(colnod) << TAB << TAB << data->updatedTokens.size() << "TOKENS UPDATED"; + qInfo(colnod) << TAB << TAB << data->deletedTokens.size() << "TOKENS DELETED"; + qInfo(colnod) << DASH; + emit dataProcessFinished(); + } } void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData) diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index b418f00..5b5502c 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -27,6 +27,7 @@ class AuthToken : public serversdk::DatabaseTable { class Timestamp : public serversdk::DatabaseTable { Q_OBJECT TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0) +public: QString toDateString() { return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index b5fb088..99b81e5 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -21,37 +21,44 @@ bool DatabaseAPI::open() void DatabaseAPI::downloadData() { - auto updatedQuery = 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 EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = false"); + auto updatedQuery = mDbMan->execPlainSql("SELECT * " + "FROM colnod_token WHERE last_modified > last_update AND deleted = false"); auto deletedQuery = mDbMan->execPlainSql("SELECT id " - "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = true"); + "FROM colnod_token WHERE last_modified > last_update AND deleted = true"); emit downloadDataFinished(composeData(updatedQuery, deletedQuery)); } void DatabaseAPI::processData(std::shared_ptr data) -{ +{ uploadTokens(data->updatedTokens); uploadSubjects(data->updatedSubjects); deleteItems(data->deletedTokens, "colnod_token"); deleteItems(data->deletedSubjects, "colnod_subject"); + + qInfo(database) << TAB << "-> DATA PROCESSED TO DATABASE:"; + qInfo(database) << TAB << TAB << data->updatedTokens.size() << "TOKENS UPDATED"; + qInfo(database) << TAB << TAB << data->deletedTokens.size() << "TOKENS DELETED"; + qInfo(database) << TAB << TAB << data->updatedSubjects.size() << "SUBJECTS UPDATED"; + qInfo(database) << TAB << TAB << data->deletedSubjects.size() << "SUBJECTS DELETED"; + qInfo(database) << DASH; } + std::shared_ptr DatabaseAPI::composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery) { auto data = std::make_shared(); - while (updatedQuery.next()) { - auto token = std::make_shared(); - token->fromSQLRecord(updatedQuery); + auto list = utils->tableFromQuery(updatedQuery); + for (const auto &token : list) { data->updatedTokens.insert(token->id(), token); } while (deletedQuery.next()) { data->deletedTokens.append(deletedQuery.value(0).toString()); } - qDebug(database) << "DATABASE DATA:"; - qDebug(database) << TAB << data->updatedTokens.size() << "TOKENS TO UPDATE"; - qDebug(database) << TAB << data->deletedTokens.size() << "TOKENS TO DELETE"; - qDebug(database) << DASH ; + qInfo(database) << TAB << "-> DATABASE DATA:"; + qInfo(database) << TAB << TAB << data->updatedTokens.size() << "TOKENS WERE MODIFIED"; + qInfo(database) << TAB << TAB << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION"; + qInfo(database) << DASH ; return data; @@ -85,6 +92,10 @@ void DatabaseAPI::setLastUpdate(QHash> tokens) query.bindValue(":id", token->id()); mDbMan->executeQuery(query); } + + qInfo(database) << EQUALS; + qInfo(database) << "Synchronize last update in database with colnod"; + qInfo(database) << EQUALS; } qint64 DatabaseAPI::getNow() @@ -112,7 +123,6 @@ void DatabaseAPI::initNewTokens() void DatabaseAPI::uploadTokens(QHash> tokens) { - // TODO: auto query = mDbMan->createQuery(); for (const auto &token : tokens) { if (exists(token->id(), "colnod_token")) { @@ -127,10 +137,17 @@ void DatabaseAPI::uploadTokens(QHash> tokens) void DatabaseAPI::uploadSubjects(QHash> subjects) { - // TODO: auto query = mDbMan->createQuery(); for (const auto &subject : subjects) { - // TODO: attributes + for (const auto &attribute : subject->getAttributes()) { + if (exists(attribute->id(), "colnod_subject_attribute")) { + query = utils->updateTable(attribute.get(), "colnod_subject_attribute"); + } + else { + query = utils->insertIntoTable(attribute.get(), "colnod_subject_attribute"); + } + query = mDbMan->executeQuery(query); + } // NOTE: about actions if (exists(subject->id(), "colnod_subject")) { query = utils->updateTable(subject.get(), "colnod_subject"); @@ -144,7 +161,6 @@ void DatabaseAPI::uploadSubjects(QHash> subjec void DatabaseAPI::deleteItems(QList ids, const QString &tableName) { - // TODO: auto query = mDbMan->createQuery(); QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz"); for (const auto &id : ids) { @@ -155,18 +171,17 @@ void DatabaseAPI::deleteItems(QList ids, const QString &tableName) } } -//TODO: return whole token -QDateTime DatabaseAPI::getLastUpdate(const QString &id) +std::shared_ptr DatabaseAPI::getLastUpdate(const QString &id) { auto query = mDbMan->createQuery(); query.prepare("SELECT last_update FROM colnod_token WHERE id = :id"); query.bindValue(":id", id); mDbMan->executeQuery(query); if (query.next()) { - return query.value(0).toDateTime(); + return utils->tableFromQuery(query).at(0); } else { - return QDateTime(); + return nullptr; } } diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index ac8a842..183d386 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -33,7 +33,7 @@ public: void uploadSubjects(QHash > subjects); void deleteItems(QList ids, const QString &tableName); - QDateTime getLastUpdate(const QString &id); + std::shared_ptr getLastUpdate(const QString &id); private: bool exists(const QString &id, const QString &tableName); diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index 9a052fa..5764874 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -14,6 +14,7 @@ bool Subject::fromJson(const QByteArray &data) for (auto key : attr.keys()) { auto newAtr = std::make_shared(); + newAtr->setId(id + " " + key); newAtr->setSubjectId(id); newAtr->setAttributeKey(key); newAtr->setAttributeValue(attr.value(key).toString()); @@ -25,3 +26,8 @@ bool Subject::fromJson(const QByteArray &data) bool res = fromVariantMap(variant); return res; } + +QList > Subject::getAttributes() +{ + return attributes; +} diff --git a/src/colnod/subject.h b/src/colnod/subject.h index 6652dc9..9f17fd0 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -30,6 +30,8 @@ public: explicit Subject(const QString& name); bool fromJson(const QByteArray &data) override; + QList> getAttributes(); + private: QList> attributes; diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 74fc584..68a9161 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -25,17 +25,28 @@ bool SyncManager::init() void SyncManager::run() { qint64 syncBegin = database->getNow(); + + qInfo(syncmanager) << EQUALS; + qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; + database->initNewTokens(); downloadData(); connect(this, &SyncManager::dataReady, [=](){ - qDebug(syncmanager) << "FINISH"; prepareData(); connect(this, &SyncManager::dataProcessFinished, [=](){ updateLastUpdate(syncBegin); connect(this, &SyncManager::syncFinished, [=](){ database->setLastSync(syncBegin); + + qInfo(syncmanager) << "Update last synchronization time to time of this sync (" + << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") + << ")"; + qInfo(syncmanager) << EQUALS; + qInfo(syncmanager) << "SYNCHRONIZATION FINISHED"; + qInfo(syncmanager) << EQUALS; + QCoreApplication::exit(); }); }); @@ -46,9 +57,11 @@ void SyncManager::run() void SyncManager::downloadData() { - qInfo(syncmanager) << EQUALS << endl; - qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN" << endl; - qInfo(syncmanager) << UNDERSCORE; + qInfo(syncmanager) << EQUALS; + qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN"; + qInfo(syncmanager) << DASH; + qInfo(syncmanager) << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; + qInfo(syncmanager) << DASH; connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); @@ -59,44 +72,74 @@ void SyncManager::downloadData() // finds conflicts -> changes on both sides (colnod and DB), apply newer change void SyncManager::prepareData() { + qInfo(syncmanager) << EQUALS; + qInfo(syncmanager) << "PREPARING DATA -> BEGIN"; + qInfo(syncmanager) << DASH; + qInfo(syncmanager) << "Resolve conflicts ( changes on same item on both Colnod and DB ):"; + qInfo(syncmanager) << DASH; + + colnodDataToProcess = std::make_shared(*colnodData); databaseDataToProcess = std::make_shared(*databaseData); - QList idsToDelete; + QList conflicts; + QList alreadySynced; for (const auto &colnodToken : colnodDataToProcess->updatedTokens) { if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) { if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) { - idsToDelete.append(colnodToken->id()); + conflicts.append(colnodToken->id()); } continue; } - auto dbLastUpdate = database->getLastUpdate(colnodToken->id()); - if ( !dbLastUpdate.isNull() ) - // TODO: compare whole structure of token - if (dbLastUpdate == colnodToken->lastUpdate()) - idsToDelete.append(colnodToken->id()); + auto token = database->getLastUpdate(colnodToken->id()); + if ( !token ) + if (token == colnodToken) + alreadySynced.append(colnodToken->id()); } - for (const auto &id : idsToDelete) + for (const auto &id : conflicts) + colnodDataToProcess->updatedTokens.remove(id); + for (const auto &id : alreadySynced) colnodDataToProcess->updatedTokens.remove(id); - idsToDelete.clear(); + 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"; + qInfo(syncmanager) << DASH; + + conflicts.clear(); for (const auto &databaseToken : databaseData->updatedTokens) { if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) { if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken->id())) - idsToDelete.append(databaseToken->id()); + conflicts.append(databaseToken->id()); } } - for (const auto &id : idsToDelete) + for (const auto &id : conflicts) colnodDataToProcess->updatedTokens.remove(id); + + qInfo(syncmanager) << TAB << "-> DATABASE DATA - CHANGES:"; + qInfo(syncmanager) << TAB << TAB << conflicts.size() << "TOKENS WERE MODIFIED IN COLNOD"; + qInfo(syncmanager) << DASH; + + qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; + qInfo(syncmanager) << EQUALS; } void SyncManager::processData() { + qInfo(syncmanager) << EQUALS; + qInfo(syncmanager) << "PROCESSING DATA -> BEGIN"; + qInfo(syncmanager) << DASH; + qInfo(syncmanager) << "Push changes to both Colnod ad Database:"; + qInfo(syncmanager) << DASH; + database->processData(colnodDataToProcess); connect(colnod.get(), &ColnodAPI::dataProcessFinished, this, &SyncManager::dataProcessFinished); colnod->processData(databaseDataToProcess); + + qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; + qInfo(syncmanager) << EQUALS; } void SyncManager::updateLastUpdate(qint64 syncBegin) @@ -112,13 +155,13 @@ void SyncManager::updateLastUpdate(qint64 syncBegin) void SyncManager::areDataReady() { - if (++dataAmount == 2) + if (++dataAmount == 2) { - qDebug(syncmanager) << "DOWNLOADING DATA -> FINISHED" << endl << endl; + qDebug(syncmanager) << "DOWNLOADING DATA -> FINISHED"; qDebug(syncmanager) << EQUALS; - qDebug(syncmanager) << EQUALS << endl << endl; emit dataReady(); + } } void SyncManager::saveColnodData(const std::shared_ptr &data) diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index f7b5079..882b9f0 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -93,7 +93,7 @@ void Token::fromSQLRecord(const QSqlQuery& query) setNoValidity(query.value(6).toBool()); setEnabled(query.value(3).toBool()); QDateTime date = query.value(4).toDateTime(); - setLastUpdate(date); // WARNING: resolve how lastUpdate should me stored + setLastUpdate(date); setName(query.value(5).toString()); a_timeToLive = query.value(7).toInt(); a_tokenBits = query.value(8).toInt();