From 108eefcf1668bac09efe11bc7451ab311c90eeaa Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Thu, 28 Nov 2019 15:55:54 +0100 Subject: [PATCH 01/22] adding method to use old algorithm using cloning --- src/colnod/syncmanager.cpp | 99 +++++++++++++++++++++++ src/colnod/syncmanager.h | 1 + test/auto/syncmanager/tst_syncmanager.cpp | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index cccecec..8a20701 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -136,6 +136,105 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< return nullptr; } +std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData) +{ + Q_UNUSED(databaseData); + Q_UNUSED(colnodData); + + 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; + + + Q_ASSERT(colnodData); + Q_ASSERT(databaseData); + + + // TODO: why copy data? + std::shared_ptr cloneColnodDataToProcess = std::make_shared(*colnodData); + std::shared_ptr cloneDatabaseDataToProcess = std::make_shared(*databaseData); + + 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 : cloneColnodDataToProcess->updatedTokens) { + if (cloneDatabaseDataToProcess->updatedTokens.contains(colnodToken->id())) { + // updated in db later + if (cloneDatabaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) { + conflicts.append(colnodToken->id()); + } + continue; + } + 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) + cloneColnodDataToProcess->updatedTokens.remove(id); + for (const auto &id : alreadySynced) + cloneColnodDataToProcess->updatedTokens.remove(id); + + qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; + qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE TOO"; + qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; + + + + 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 : cloneColnodDataToProcess->deletedTokens) { + if (database->isAlreadyDeleted(id)) { + conflicts.append(id); + } + } + for (const auto &id : conflicts) { + cloneColnodDataToProcess->deletedTokens.removeOne(id); + } + + qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ALREADY DELETED"; + qInfo(syncmanager) << dash; + + conflicts.clear(); + + // chech modified from db, remove token if it was edited in colnod later + for (const auto &databaseToken : cloneDatabaseDataToProcess->updatedTokens) { + if (cloneColnodDataToProcess->updatedTokens.contains(databaseToken->id())) { + if (databaseToken < cloneColnodDataToProcess->updatedTokens.value(databaseToken->id())) + conflicts.append(databaseToken->id()); + } + else { + // restriction cauesed by colnod rest api + if (databaseToken->description() != "mobile") { + qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; + conflicts.append(databaseToken->id()); + } + } + } + for (const auto &id : conflicts) + cloneColnodDataToProcess->updatedTokens.remove(id); + + qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; + qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN IN COLNOD TOO"; + qInfo(syncmanager) << dash; + + qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; + qInfo(syncmanager) << equals; + + // Prepare data + auto preparedData = std::make_unique(); + preparedData->colnodData = cloneColnodDataToProcess; + preparedData->databaseData = databaseDataToProcess; + + return preparedData; +} + bool SyncManager::downloadData() { bool res = true; diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 5fbfa31..21a9749 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -26,6 +26,7 @@ private: * @todo rename when removed old aproach */ std::unique_ptr prepareDataNew(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); + std::unique_ptr prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); private: bool downloadData(); diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index ff3fbaf..b190c83 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -18,12 +18,13 @@ void SyncManagerTest::sync_init_test() QVERIFY(sync.databaseInitialization()); } + void SyncManagerTest::prepareData_test() { SyncManager sync(true); auto dbData = std::make_shared(); auto colnodData = std::make_shared(); - QVERIFY2(sync.prepareDataNew(dbData, colnodData), "finish unitest"); + QVERIFY2(sync.prepareDataUsindOld(dbData, colnodData), "finish unitest"); } QTEST_MAIN(SyncManagerTest) From aeb2782920f2c11d10f10fdb65a6387bd76f4515 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 10:03:13 +0100 Subject: [PATCH 02/22] clang: fixing warnings --- src/app/main.cpp | 4 ++-- src/colnod/colnodapi.cpp | 23 +++++++++++------------ src/colnod/colnodapi.h | 12 ++++++------ src/colnod/data.h | 8 +++++--- src/colnod/databaseapi.cpp | 9 +++------ src/colnod/databaseapi.h | 10 +++++----- src/colnod/syncmanager.cpp | 4 ++-- src/colnod/syncmanager.h | 2 +- test/auto/colnod/tst_colnodapi.cpp | 4 ++-- test/auto/syncmanager/tst_syncmanager.cpp | 8 +++++++- 10 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 34b50bf..3b35c33 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -45,13 +45,13 @@ int main(int argc, char *argv[]) // Initialize database and colnod API if (!syncManager.databaseInitialization()) { - qCritical("Not possible to initialize sync application"); + qCritical() << "Not possible to initialize sync application"; return -1; } // Synchronizaiton if (!syncManager.startSynchronization()) { - qCritical("Not possible to start synchronization"); + qCritical() << "Not possible to start synchronization"; return -1; } diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 1433581..fc283d8 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -1,10 +1,12 @@ #include "colnodapi.h" +#include + Q_LOGGING_CATEGORY(colnod, "colnod.api"); -ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const bool &dryMode, const QString &userName, const QString &password) - :mReqMan(reqMan), mUserName(userName), mPassword(password), mDryMode(dryMode) +ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const bool &dryMode, QString userName, QString password) + :mReqMan(reqMan), mUserName(std::move(userName)), mPassword(std::move(password)), mDryMode(dryMode) { // ----------------------------------- mReqMan->setIgnoreSsl(true); @@ -35,7 +37,7 @@ void ColnodAPI::downloadData(const Timestamp &time) auto data = std::make_shared(); - auto errorHandler = [=](std::shared_ptr request){ + auto errorHandler = [=](const std::shared_ptr& request){ if (!checkRequest(request)) { qWarning(colnod) << "ERROR during calling" << request->url() << ", request unsuccessful"; mValid = false; @@ -215,10 +217,7 @@ std::shared_ptr ColnodAPI::composeRequest(const QString &end bool ColnodAPI::checkRequest(const std::shared_ptr &request) { - if (request->status() == 200) { - return true; - } - return false; + return request->status() == 200; } bool ColnodAPI::isValid() @@ -257,7 +256,7 @@ void ColnodAPI::setUserName(const QString &userName) mUserName = userName; } -void ColnodAPI::areDataReady(std::shared_ptr data) +void ColnodAPI::areDataReady(const std::shared_ptr& data) { if (++amountData == 4) { @@ -280,12 +279,12 @@ void ColnodAPI::isDataProcessFinished() } } -void ColnodAPI::saveUpdatedTokens(std::shared_ptr data, const QByteArray &responseData) +void ColnodAPI::saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData) { data->loadTokensFromJson(responseData); } -void ColnodAPI::saveDeletedTokens(std::shared_ptr data, const QByteArray &responseData) +void ColnodAPI::saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); @@ -294,12 +293,12 @@ void ColnodAPI::saveDeletedTokens(std::shared_ptr data, const QByteArray & } } -void ColnodAPI::saveUpdatedSubjects(std::shared_ptr data, const QByteArray &responseData) +void ColnodAPI::saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData) { data->loadSubjectsFormJson(responseData); } -void ColnodAPI::saveDeletedSubjects(std::shared_ptr data, const QByteArray &responseData) +void ColnodAPI::saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 68ed360..300208b 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -48,7 +48,7 @@ class ColnodAPI: public QObject Q_OBJECT public: ColnodAPI() = default; - ColnodAPI(serversdk::RequestManager* reqManconst, const bool &dryMode = false, const QString &userName = "spaceti", const QString &password = "spaceti1"); + ColnodAPI(serversdk::RequestManager* reqManconst, const bool &dryMode = false, QString userName = "spaceti", QString password = "spaceti1"); void downloadData(const Timestamp &time); void processData(const std::shared_ptr &data); @@ -76,14 +76,14 @@ public: bool isValid(); private: - Q_SLOT void areDataReady(std::shared_ptr data); + Q_SLOT void areDataReady(const std::shared_ptr& data); Q_SLOT void isDataProcessFinished(); private: - void saveUpdatedTokens(std::shared_ptr data, const QByteArray &responseData); - void saveUpdatedSubjects(std::shared_ptr data, const QByteArray &responseData); - void saveDeletedTokens(std::shared_ptr data, const QByteArray &responseData); - void saveDeletedSubjects(std::shared_ptr data, const QByteArray &responseData); + void saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData); + void saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData); + void saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData); + void saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData); void newData(); diff --git a/src/colnod/data.h b/src/colnod/data.h index a0f607a..bfc1eef 100644 --- a/src/colnod/data.h +++ b/src/colnod/data.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "token.h" #include "subject.h" @@ -13,7 +15,7 @@ constexpr auto tab = "\t"; class Message { public: - static QString massageTemplate(QString action, QString item, QString source, QString itemInfo) + static QString massageTemplate(const QString& action, const QString& item, const QString& source, const QString& itemInfo) { return action + " " + item + " in " + source + ", " + item + ": '" + itemInfo + "'"; } @@ -41,8 +43,8 @@ struct PreparedData { public: PreparedData() = default; - PreparedData(const std::shared_ptr &database, const std::shared_ptr &colnod) - :databaseData(database), colnodData(colnod) + PreparedData(std::shared_ptr database, std::shared_ptr colnod) + :databaseData(std::move(database)), colnodData(std::move(colnod)) { } diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 7c4b695..b32d23c 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -12,7 +12,7 @@ DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan, bool dryMode) mDbMan->setDryMode(dryMode); } -bool DatabaseAPI::open(QString host, QString name, QString user, QString password) +bool DatabaseAPI::open(const QString& host, const QString& name, const QString& user, const QString& password) { return mDbMan->openPostgres(host, name, user, password); } @@ -135,7 +135,7 @@ void DatabaseAPI::setLastUpdate(const QHash> &to qInfo(database) << equals; } -void DatabaseAPI::setLastUpdate(const QList ids) +void DatabaseAPI::setLastUpdate(const QList& ids) { auto query = mDbMan->createQuery(); for (const auto &id : ids){ @@ -299,10 +299,7 @@ bool DatabaseAPI::isAlreadyDeleted(const QString &id) qWarning(database) << "Token deleted in colnod doesn't exists in db, will be noted as already deleted in stats"; return true; } - if (token->deleted()) - return true; - return false; - + return token->deleted(); } bool DatabaseAPI::isValid() diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index 8668b2f..f127a9d 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -20,10 +20,10 @@ class DatabaseAPI : public QObject public: explicit DatabaseAPI(serversdk::DatabaseManager *dbMan, bool dryMode); - bool open(QString host = "192.168.1.94", - QString name = "deloitte", - QString user = "postgres", - QString password = "34rjkciea12"); + bool open(const QString& host = "192.168.1.94", + const QString& name = "deloitte", + const QString& user = "postgres", + const QString& password = "34rjkciea12"); bool executeQuery(QSqlQuery &query, const QString &statement = QString()); @@ -32,7 +32,7 @@ public: qint64 getLastSync(); void setLastSync(qint64 timestamp); void setLastUpdate(const QHash > &tokens); - void setLastUpdate(const QList ids); + void setLastUpdate(const QList& ids); qint64 getNow(); void initNewTokens(); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 6e025dd..a84a7e0 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -63,7 +63,7 @@ bool SyncManager::startSynchronization() colnod->downloadData(Timestamp(syncBegin)); - connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr colnodData) { + connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](const std::shared_ptr& colnodData) { if (!colnodData) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; QCoreApplication::exit(-1); @@ -202,7 +202,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< return preparedData; } -void SyncManager::initNewToken(std::shared_ptr token) +void SyncManager::initNewToken(const std::shared_ptr& token) { qint16 num = database->getNumOfTokensOfSubject(token->subjectId()); token->setName(database->getSubjectNameByTokenId(token->id()) + "_mobile_" + QString::number(num + 1)); diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 2d9478d..267efc0 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -29,7 +29,7 @@ private: std::unique_ptr prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); private: - void initNewToken(std::shared_ptr token); + void initNewToken(const std::shared_ptr& token); bool downloadData(); bool prepareData(); diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp index dedd554..5c2fffb 100644 --- a/test/auto/colnod/tst_colnodapi.cpp +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -68,7 +68,7 @@ void ColnodTest::download_data_test() auto data = qvariant_cast>(spy.at(0).at(0)); QVERIFY(data); - QVERIFY(data->updatedTokens.size() > 0); + QVERIFY(! data->updatedTokens.isEmpty()); QVERIFY(data->updatedTokens.contains("5e2f1260-da1c-441f-9644-24dfe3b97b2a")); } { @@ -79,7 +79,7 @@ void ColnodTest::download_data_test() auto data = qvariant_cast>(spy.at(0).at(0)); QVERIFY(data); - QVERIFY(data->updatedTokens.size() == 0); + QVERIFY(! data->updatedTokens.isEmpty()); } } diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index b190c83..bd244f0 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -24,7 +24,13 @@ void SyncManagerTest::prepareData_test() SyncManager sync(true); auto dbData = std::make_shared(); auto colnodData = std::make_shared(); - QVERIFY2(sync.prepareDataUsindOld(dbData, colnodData), "finish unitest"); + + auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); + auto newPreparedData = sync.prepareDataNew(dbData, colnodData); + + QCOMPARE(newPreparedData, oldPreparedData); + + } QTEST_MAIN(SyncManagerTest) From 9afde747c8b022e9c9eecb405b09eb25d8ec2c8c Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 10:06:56 +0100 Subject: [PATCH 03/22] server-sdk: clang-checks fix --- server-sdk | 2 +- test/auto/colnod/tst_colnodapi.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server-sdk b/server-sdk index a818055..031b6c2 160000 --- a/server-sdk +++ b/server-sdk @@ -1 +1 @@ -Subproject commit a818055b75dc0de97e26be44cbbfd2e94516c09e +Subproject commit 031b6c2535408bce18a5d7bbc5842f9ee4384328 diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp index 5c2fffb..fd91abc 100644 --- a/test/auto/colnod/tst_colnodapi.cpp +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -62,6 +62,7 @@ void ColnodTest::download_data_test() ColnodAPI colnod(&reqMan); { QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + QVERIFY(spy.isValid()); colnod.downloadData(Timestamp(1570190399259)); QVERIFY(spy.wait()); From f3077d9f0afeda3ef998df8df5ece5f676b62ed1 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 13:18:46 +0100 Subject: [PATCH 04/22] unittest: adding multiple checks for prepareData_test --- src/colnod/syncmanager.cpp | 5 ++- test/auto/colnod/tst_colnodapi.cpp | 43 +++++++++++++---------- test/auto/syncmanager/tst_syncmanager.cpp | 17 ++++++--- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index a84a7e0..148a311 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -204,6 +204,8 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< void SyncManager::initNewToken(const std::shared_ptr& token) { + Q_ASSERT(database); + Q_ASSERT(token); qint16 num = database->getNumOfTokensOfSubject(token->subjectId()); token->setName(database->getSubjectNameByTokenId(token->id()) + "_mobile_" + QString::number(num + 1)); token->setDescription("mobile"); @@ -214,9 +216,6 @@ void SyncManager::initNewToken(const std::shared_ptr& token) std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData) { - Q_UNUSED(databaseData); - Q_UNUSED(colnodData); - qInfo(syncmanager) << equals; qInfo(syncmanager) << "PREPARING DATA -> BEGIN"; qInfo(syncmanager) << dash; diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp index fd91abc..2ae370e 100644 --- a/test/auto/colnod/tst_colnodapi.cpp +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -21,6 +21,7 @@ private slots: void login(); void getTokens(); void download_data_test(); + void download_data_test_now(); void download_data_fail_test(); private: @@ -60,28 +61,32 @@ void ColnodTest::download_data_test() { serversdk::RequestManager reqMan; ColnodAPI colnod(&reqMan); - { - QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); - QVERIFY(spy.isValid()); - colnod.downloadData(Timestamp(1570190399259)); - QVERIFY(spy.wait()); - auto data = qvariant_cast>(spy.at(0).at(0)); - QVERIFY(data); + QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + QVERIFY(spy.isValid()); + colnod.downloadData(Timestamp(1570190399259)); + QVERIFY(spy.wait()); - QVERIFY(! data->updatedTokens.isEmpty()); - QVERIFY(data->updatedTokens.contains("5e2f1260-da1c-441f-9644-24dfe3b97b2a")); - } - { - Timestamp time(QDateTime::currentMSecsSinceEpoch()); - colnod.downloadData(time); - QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); - QVERIFY(spy.wait()); - auto data = qvariant_cast>(spy.at(0).at(0)); - QVERIFY(data); + auto data = qvariant_cast>(spy.at(0).at(0)); + QVERIFY(data); - QVERIFY(! data->updatedTokens.isEmpty()); - } + QVERIFY(! data->updatedTokens.isEmpty()); + QVERIFY(data->updatedTokens.contains("5e2f1260-da1c-441f-9644-24dfe3b97b2a")); +} + +void ColnodTest::download_data_test_now() +{ + serversdk::RequestManager reqMan; + ColnodAPI colnod(&reqMan); + + Timestamp time(QDateTime::currentMSecsSinceEpoch()); + colnod.downloadData(time); + QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); + QVERIFY(spy.wait()); + auto data = qvariant_cast>(spy.at(0).at(0)); + QVERIFY(data); + + QVERIFY(data->updatedTokens.isEmpty()); } void ColnodTest::download_data_fail_test() diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index bd244f0..95a43ce 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -25,12 +25,21 @@ void SyncManagerTest::prepareData_test() auto dbData = std::make_shared(); auto colnodData = std::make_shared(); + auto token = std::make_shared(); + token->setId("id1"); + dbData->updatedTokens.insert("id1", token); + + auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); - - QCOMPARE(newPreparedData, oldPreparedData); - - + QVERIFY(oldPreparedData->databaseData->updatedTokens.contains("id1")); + QVERIFY(newPreparedData->databaseData->updatedTokens.contains("id1")); + QVERIFY(oldPreparedData->databaseData->updatedSubjects.isEmpty()); + QVERIFY(newPreparedData->databaseData->updatedSubjects.isEmpty()); + QVERIFY(oldPreparedData->databaseData->deletedTokens.isEmpty()); + QVERIFY(newPreparedData->databaseData->deletedTokens.isEmpty()); + QVERIFY(oldPreparedData->databaseData->deletedSubjects.isEmpty()); + QVERIFY(newPreparedData->databaseData->deletedSubjects.isEmpty()); } QTEST_MAIN(SyncManagerTest) From e8e8184add6d11f5783e3b305025237bdcb54264 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 14:23:36 +0100 Subject: [PATCH 05/22] unittest: data driven testing for tokens and prepareData ( failing ) --- src/colnod/syncmanager.cpp | 108 +-------------------- src/colnod/syncmanager.h | 8 +- test/auto/syncmanager/tst_syncmanager.cpp | 109 +++++++++++++++++++++- 3 files changed, 114 insertions(+), 111 deletions(-) diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 148a311..58e9ac3 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -92,7 +92,7 @@ bool SyncManager::startSynchronization() connect(this, &SyncManager::dataReady, [=](){ - prepareData(); + //prepareData(); connect(this, &SyncManager::dataProcessFinished, [=](){ @@ -305,7 +305,7 @@ std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared // Prepare data auto preparedData = std::make_unique(); preparedData->colnodData = cloneColnodDataToProcess; - preparedData->databaseData = databaseDataToProcess; + preparedData->databaseData = cloneDatabaseDataToProcess; return preparedData; } @@ -319,7 +319,7 @@ bool SyncManager::downloadData() qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; qInfo(syncmanager) << dash; - connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); + //connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); //connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); //database->downloadData(); //colnod->downloadData(); @@ -327,96 +327,6 @@ bool SyncManager::downloadData() return res; } -// finds conflicts -> changes on both sides (colnod and DB), apply newer change -bool 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; - - - Q_ASSERT(colnodData); - Q_ASSERT(databaseData); - - - // TODO: why copy data? - colnodDataToProcess = std::make_shared(*colnodData); - databaseDataToProcess = std::make_shared(*databaseData); - - 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->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); - - qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE TOO"; - qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; - - - - 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 << tab << conflicts.size() << "TOKENS WERE ALREADY DELETED"; - qInfo(syncmanager) << dash; - - conflicts.clear(); - - // 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") { - qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; - conflicts.append(databaseToken->id()); - } - } - } - for (const auto &id : conflicts) - colnodDataToProcess->updatedTokens.remove(id); - - qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN IN COLNOD TOO"; - qInfo(syncmanager) << dash; - - qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; - qInfo(syncmanager) << equals; - return true; -} bool SyncManager::processData() { @@ -454,15 +364,3 @@ void SyncManager::areDataReady() emit dataReady(); } } - -void SyncManager::saveColnodData(const std::shared_ptr &data) -{ - colnodData = data; - areDataReady(); -} - -void SyncManager::saveDatabaseData(const std::shared_ptr &data) -{ - databaseData = data; - areDataReady(); -} diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 267efc0..4276d7e 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -32,14 +32,12 @@ private: void initNewToken(const std::shared_ptr& token); bool downloadData(); - bool prepareData(); + //bool prepareData(); bool processData(); void updateLastUpdate(qint64 syncBegin); private: - Q_SLOT void saveColnodData(const std::shared_ptr &data); - Q_SLOT void saveDatabaseData(const std::shared_ptr &data); Q_SLOT void areDataReady(); signals: @@ -56,8 +54,8 @@ private: serversdk::DatabaseManager dbMan; Timestamp mlastSync; - std::shared_ptr colnodData; - std::shared_ptr databaseData; +// std::shared_ptr colnodData; +// std::shared_ptr databaseData; std::shared_ptr colnodDataToProcess; std::shared_ptr databaseDataToProcess; diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index 95a43ce..ff45e89 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -6,12 +6,37 @@ class SyncManagerTest : public QObject { Q_OBJECT +private: + std::shared_ptr tokenFromString(const QString &text); private slots: + void tokenFromString_test(); void sync_init_test(); void prepareData_test(); + void prepareData_tokens(); + void prepareData_tokens_data(); }; +std::shared_ptr SyncManagerTest::tokenFromString(const QString &text) +{ + auto split = text.split(","); + if (split.count() != 2) + return nullptr; + + auto token = std::make_shared(); + token->setId(split.first()); + token->setDescription("mobile"); + token->setLastUpdate(QDateTime::fromString(split.last(), "yyyyMMdd:HHmmss")); + return token; +} + +void SyncManagerTest::tokenFromString_test() +{ + auto token = tokenFromString("id1,20191010:232300"); + QCOMPARE(token->id(), QStringLiteral("id1")); + QCOMPARE(token->lastUpdate(), QDateTime::fromString("20191010:232300", "yyyyMMdd:HHmmss")); +} + void SyncManagerTest::sync_init_test() { SyncManager sync(true); @@ -22,14 +47,15 @@ void SyncManagerTest::sync_init_test() void SyncManagerTest::prepareData_test() { SyncManager sync(true); + QVERIFY(sync.databaseInitialization()); auto dbData = std::make_shared(); auto colnodData = std::make_shared(); auto token = std::make_shared(); + token->setDescription("mobile"); token->setId("id1"); dbData->updatedTokens.insert("id1", token); - auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); QVERIFY(oldPreparedData->databaseData->updatedTokens.contains("id1")); @@ -42,6 +68,87 @@ void SyncManagerTest::prepareData_test() QVERIFY(newPreparedData->databaseData->deletedSubjects.isEmpty()); } +void SyncManagerTest::prepareData_tokens() +{ + SyncManager sync(true); + QVERIFY(sync.databaseInitialization()); + + + + QFETCH(QString, db_token_updated); + QFETCH(QString, db_token_deleted); + QFETCH(QString, colnod_token_updated); + QFETCH(QString, colnod_token_deleted); + QFETCH(QString, expected_db_tokens_toupdate); + QFETCH(QString, expected_db_tokens_todelete); + QFETCH(QString, expected_colnod_tokens_toupdate); + QFETCH(QString, expected_colnod_tokens_todelete); + + // fake data + auto dbData = std::make_shared(); + auto colnodData = std::make_shared(); + + // Database + auto utoken = tokenFromString(db_token_updated); + if ( utoken ) + dbData->updatedTokens.insert(utoken->id(), utoken); + auto dtoken = tokenFromString(db_token_deleted); + if ( dtoken ) + dbData->deletedTokens.append(dtoken->id()); + + // Colnod + auto colnod_utoken = tokenFromString(colnod_token_updated); + if ( colnod_utoken ) + colnodData->updatedTokens.insert(colnod_utoken->id(), colnod_utoken); + auto colnod_dtoken = tokenFromString(colnod_token_deleted); + if ( colnod_dtoken ) + colnodData->deletedTokens.append(colnod_dtoken->id()); + + auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); + auto newPreparedData = sync.prepareDataNew(dbData, colnodData); + + QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); + QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); + QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); + QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + + QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); + QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); + QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); + QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + +} + +void SyncManagerTest::prepareData_tokens_data() +{ + QTest::addColumn("db_token_updated"); + QTest::addColumn("db_token_deleted"); + QTest::addColumn("colnod_token_updated"); + QTest::addColumn("colnod_token_deleted"); + QTest::addColumn("expected_db_tokens_toupdate"); + QTest::addColumn("expected_db_tokens_todelete"); + QTest::addColumn("expected_colnod_tokens_toupdate"); + QTest::addColumn("expected_colnod_tokens_todelete"); + + // in: db 1 new token + // out: 1 db token must be updated in colnod + QTest::newRow("db 1 update") << "id1,20191010:23:23:00" << "" + << "" << "" + // expected database: toupdate << todelete + << "id1" << "" + // expected colnod: toupdate << todelete + << "" << ""; + // in: id1 in database new/updated + // in: id1 deleted in colnod + // out: 1 colnod token must be deleted from database + QTest::newRow("delete 1 existing token in database") << "id1,20191010:23:23:00" << "" + << "" << "id1,20191010:23:23:00" + // expected database: toupdate << todelete + << "" << "id1" + // expected colnod: toupdate << todelete + << "" << ""; +} + QTEST_MAIN(SyncManagerTest) #include "tst_syncmanager.moc" From 79cebf913057ee0745038926ef224ce01aa149e9 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 15:05:02 +0100 Subject: [PATCH 06/22] fix warning: qRegisterMetaType --- test/auto/colnod/tst_colnodapi.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp index 2ae370e..c480e59 100644 --- a/test/auto/colnod/tst_colnodapi.cpp +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -7,6 +7,7 @@ Q_DECLARE_METATYPE(std::shared_ptr) Q_DECLARE_METATYPE(std::shared_ptr); + class ColnodTest : public QObject { Q_OBJECT @@ -14,7 +15,7 @@ public: ColnodTest() { qRegisterMetaType>(); - qRegisterMetaType>(); + qRegisterMetaType>("std::shared_ptr"); } private slots: @@ -60,6 +61,7 @@ void ColnodTest::getTokens() void ColnodTest::download_data_test() { serversdk::RequestManager reqMan; + //reqMan.setIgnoreSsl(true); ColnodAPI colnod(&reqMan); QSignalSpy spy(&colnod, &ColnodAPI::downloadDataFinished); From 443a76e50ffe658c10e7efab40be639b434e6f12 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Mon, 2 Dec 2019 15:07:24 +0100 Subject: [PATCH 07/22] trying to solve unittest crash ( adding more checks ) fixed cppcheck warning --- src/colnod/colnodapi.cpp | 16 ++++++++++++++-- src/colnod/data.h | 3 +-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index fc283d8..8314b77 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -26,14 +26,26 @@ void ColnodAPI::downloadData(const Timestamp &time) auto login = requestLogin(); connect(login.get(), &serversdk::Request::finished, this, [=](){ // Get login token - if (!checkRequest(login)) { + if (login->status() != 200) { emit downloadDataFinished(nullptr); return; } AuthToken token; - token.fromJson(login->responseData()); + auto responseData = login->responseData(); + if (responseData.isEmpty()) { + qCWarning(colnod) << "empty response data when logging in"; + emit downloadDataFinished(nullptr); + return; + } + + token.fromJson(responseData); authToken = token.id(); + if (authToken.isEmpty()) { + qCCritical(colnod) << "Token uuid is empty"; + emit downloadDataFinished(nullptr); + return; + } auto data = std::make_shared(); diff --git a/src/colnod/data.h b/src/colnod/data.h index bfc1eef..868bc03 100644 --- a/src/colnod/data.h +++ b/src/colnod/data.h @@ -43,12 +43,11 @@ struct PreparedData { public: PreparedData() = default; - PreparedData(std::shared_ptr database, std::shared_ptr colnod) + PreparedData(const std::shared_ptr &database, const std::shared_ptr &colnod) :databaseData(std::move(database)), colnodData(std::move(colnod)) { } - // TODO: make unique_ptr ( neeed because of ColnodAPI ) std::shared_ptr databaseData; std::shared_ptr colnodData; From 3487c6f81cd661bf4318ae7d8b8e4cde9a7beeaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 2 Dec 2019 18:11:38 +0100 Subject: [PATCH 08/22] WIP: colnod api doesnt download data --- src/colnod/colnodapi.cpp | 2 +- src/colnod/databaseapi.cpp | 7 ++++--- src/colnod/databaseapi.h | 2 +- src/colnod/syncmanager.cpp | 21 +++++++++++++-------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 14da4e8..863b283 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -271,7 +271,7 @@ void ColnodAPI::setUserName(const QString &userName) mUserName = userName; } -void ColnodAPI::areDataReady(const std::shared_ptr& data) +void ColnodAPI::areDataReady(const std::shared_ptr &data) { if (++amountData == 4) { diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 25d23db..163ccbd 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -184,7 +184,7 @@ void DatabaseAPI::initNewTokens() uploadTokens(tokensToInit); } -bool DatabaseAPI::uploadTokens(const QHash> &tokens) +bool DatabaseAPI::uploadTokens(const QHash> &tokens, const QSet &filters) { // TODO: first check if OK, then message // OK -> token was updated @@ -194,8 +194,9 @@ bool DatabaseAPI::uploadTokens(const QHash> &tok // Get token if (exists(token->id(), "colnod_token")) { - query = utils->updateTable(token.get(), "colnod_token"); - qInfo(database).noquote() << Message::massageTemplate("Updating", "token", "database", token->name()); + query = utils->updateTable(token.get(), "colnod_token", filters); + if (filters.contains("last_modified")) + qInfo(database).noquote() << Message::massageTemplate("Updating", "token", "database", token->name()); } else { // TODO: first check if OK, then message diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index dfb48c1..3e8ab84 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -38,7 +38,7 @@ public: void initNewTokens(); // process data - bool uploadTokens(const QHash > &tokens); + bool uploadTokens(const QHash > &tokens, const QSet &filters = {}); bool uploadSubjects(const QHash > &subjects); bool deleteItems(const QList &ids, const QString &tableName); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 6322d24..ade9e16 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -87,7 +87,7 @@ bool SyncManager::startSynchronization() qInfo(syncmanager) << "Push changes to both Colnod and Database:"; qInfo(syncmanager) << dash; - if (!database->processData(preparedData->databaseData)) { + if (!database->processData(preparedData->colnodData)) { qCritical(syncmanager) << "Not possible to upload data to database"; } @@ -100,21 +100,25 @@ bool SyncManager::startSynchronization() Timestamp time; time.setTimestamp(syncBegin); - database->reupdateDeleted(preparedData->databaseData->deletedTokens); // download data changes in this sync - colnod->getTokensUpdated(time); + auto tokensRequest = colnod->getTokensUpdated(time); // updated data are ready - connect(colnod.get(), &ColnodAPI::partOfDataReady, [=](const std::shared_ptr &uploadedData){ + connect(tokensRequest.get(), &serversdk::Request::finished, [=](){ + auto uploadedData = std::make_shared(); + uploadedData->loadTokensFromJson(tokensRequest->responseData()); + if (!uploadedData) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; QCoreApplication::exit(-1); return; } - if (!database->uploadTokens(uploadedData->updatedTokens)) { + if (!database->uploadTokens(uploadedData->updatedTokens, {"lastModified"})) { qCritical(syncmanager) << "Not possible to upload data to database"; + QCoreApplication::exit(-1); + return; } - database->reupdateDeleted(uploadedData->deletedTokens); + database->reupdateDeleted(databaseData->deletedTokens); if (!database->isValid() || !colnod->isValid()) { qWarning(syncmanager) << "Synchronization was unsuccessful, next run of sync will be with same last sync time, check warnings"; @@ -135,7 +139,8 @@ bool SyncManager::startSynchronization() }); - colnod->processData(preparedData->colnodData); + colnod->processData(preparedData->databaseData); // TODO: errors??? + //qCritical(syncmanager) << "Not possible to upload data to colnod"; }); @@ -217,7 +222,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< } qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedColnodData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; + qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedDatabaseData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; qInfo(syncmanager) << dash; qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; From 10ac7489856d5534f71b0fde948c1374da82b22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 3 Dec 2019 10:55:31 +0100 Subject: [PATCH 09/22] fix wrong parameter --- server-sdk | 2 +- src/colnod/syncmanager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server-sdk b/server-sdk index 031b6c2..b643f25 160000 --- a/server-sdk +++ b/server-sdk @@ -1 +1 @@ -Subproject commit 031b6c2535408bce18a5d7bbc5842f9ee4384328 +Subproject commit b643f25421757703b930d48a3c0175b7e9de1c72 diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index ade9e16..31e35ac 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -60,7 +60,7 @@ bool SyncManager::startSynchronization() } // NOW I HAVE DATA FROM DATABASE - colnod->downloadData(syncBegin); + colnod->downloadData(mlastSync.timestamp()); connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr colnodData) { qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; qInfo(syncmanager) << equals; From 0f948afa7161175d0812ce39b4f4b9390a2173a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 3 Dec 2019 13:09:43 +0100 Subject: [PATCH 10/22] fix incorrect error handling --- src/colnod/databaseapi.cpp | 4 ++-- src/colnod/syncmanager.cpp | 20 +++++++++++------- test/auto/database/tst_databaseapi.cpp | 29 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 163ccbd..549332d 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -269,7 +269,7 @@ bool DatabaseAPI::deleteItems(const QList &ids, const QString &tableNam std::shared_ptr DatabaseAPI::getToken(const QString &id) { auto query = mDbMan->createQuery(); - query.prepare("SELECT * FROM colnod_token WHERE d = :id"); + query.prepare("SELECT * FROM colnod_token WHERE id = :id"); query.bindValue(":id", id); if (!executeQuery(query)) { qCritical(database) << "ERROR during accessing existing tokens. EXIT"; @@ -278,7 +278,7 @@ std::shared_ptr DatabaseAPI::getToken(const QString &id) } auto list = utils->tableFromQuery(query); if (list.isEmpty()) - return nullptr; + return std::make_shared(); return list.at(0); } diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 31e35ac..442a23b 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -76,7 +76,7 @@ bool SyncManager::startSynchronization() std::unique_ptr preparedData = prepareDataNew(databaseData, colnodData); if (!preparedData) { - qCritical(syncmanager) << "Not possible to get correct data from colnod"; + qCritical(syncmanager) << "Not possible to compose data"; QCoreApplication::exit(-1); return; } @@ -167,6 +167,18 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< // not conflict so add to prepered tokens if (!databaseData->updatedTokens.contains(colnodToken->id())) { + auto token = database->getToken(colnodToken->id()); + if (!token) { + qCritical(syncmanager) << "Not possible to access database."; + return nullptr; + } + if ( token ) { + // alredy synced ( tokens are same ) + if (token == colnodToken) { + alreadySynced.append(colnodToken->id()); + continue; + } + } preparedColnodData->updatedTokens.insert(colnodToken->id(), colnodToken); continue; } @@ -178,12 +190,6 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< else { conflicts.append(colnodToken->id()); } - - auto token = database->getToken(colnodToken->id()); - if ( token ) - // alredy synced ( tokens are same ) - if (token == colnodToken) - alreadySynced.append(colnodToken->id()); } for (const auto &id : colnodData->deletedTokens) { diff --git a/test/auto/database/tst_databaseapi.cpp b/test/auto/database/tst_databaseapi.cpp index 43632ef..51989f0 100644 --- a/test/auto/database/tst_databaseapi.cpp +++ b/test/auto/database/tst_databaseapi.cpp @@ -2,6 +2,7 @@ #include "databaseapi.h" // add necessary includes here +#include "token.h" class DatabaseTest : public QObject { @@ -14,6 +15,7 @@ private slots: void open_database_password_fail_test(); void download_data_test(); void download_data_fail_test(); + void get_token_test(); }; void DatabaseTest::open_database_test() @@ -76,6 +78,33 @@ void DatabaseTest::download_data_fail_test() QVERIFY(!db.downloadData()); } +void DatabaseTest::get_token_test() +{ + serversdk::DatabaseManager dbManager; + DatabaseAPI db(&dbManager, false); + + QVERIFY(!db.getToken("6c907a42-0401-4403-8af4-9d58eb35cddc")); + + db.open(); + + auto token = db.getToken("6c907a42-0401-4403-8af4-9d58eb35cddc"); + QVERIFY(token); + auto compareToken = std::make_shared(); + compareToken->setId("6c907a42-0401-4403-8af4-9d58eb35cddc"); + compareToken->setName("Losenicky"); + compareToken->setDescription(""); + compareToken->setLastUpdate(QDateTime::fromMSecsSinceEpoch(1543494713260)); + compareToken->setTokenData("AB1EA4D4"); + compareToken->setSubjectId("69c6e3b3-3f23-456f-a6c2-73ef08e589a4"); + QCOMPARE(compareToken, token); + + auto compareToken1 = std::make_shared(); + auto token1 = db.getToken("non-existing-id"); + QVERIFY(token1); + QCOMPARE(compareToken1, token1); + +} + QTEST_APPLESS_MAIN(DatabaseTest) From 319fc8d71e3feace1ffb959e53b94fefc785f851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 3 Dec 2019 15:58:33 +0100 Subject: [PATCH 11/22] ignore expected errors --- test/auto/database/tst_databaseapi.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/auto/database/tst_databaseapi.cpp b/test/auto/database/tst_databaseapi.cpp index 51989f0..b919249 100644 --- a/test/auto/database/tst_databaseapi.cpp +++ b/test/auto/database/tst_databaseapi.cpp @@ -82,8 +82,11 @@ void DatabaseTest::get_token_test() { serversdk::DatabaseManager dbManager; DatabaseAPI db(&dbManager, false); - - QVERIFY(!db.getToken("6c907a42-0401-4403-8af4-9d58eb35cddc")); + { + QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::prepare: database not open"); + QTest::ignoreMessage(QtSystemMsg, "ERROR during accessing existing tokens. EXIT"); + QVERIFY(!db.getToken("6c907a42-0401-4403-8af4-9d58eb35cddc")); + } db.open(); From fcb792447ff568f32fb09a9af2a2c04425375880 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Tue, 3 Dec 2019 15:59:35 +0100 Subject: [PATCH 12/22] adding better handling to unittest to SyncManager --- test/auto/syncmanager/tst_syncmanager.cpp | 42 +++++++++++++++++------ 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index ff45e89..c5c225d 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -107,15 +107,36 @@ void SyncManagerTest::prepareData_tokens() auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); - QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); - QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); - QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); - QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); - QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); - QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); - QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); - QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + auto testTokens = [=](const QSet &set, const QString &expectedId) { + if (expectedId.isEmpty()) { + QVERIFY(set.isEmpty()); + } else { + QVERIFY(set.contains(expectedId)); + } + }; + + testTokens(newPreparedData->databaseData->updatedTokens.keys().toSet(), expected_db_tokens_toupdate); + testTokens(newPreparedData->databaseData->deletedTokens.toSet(), expected_db_tokens_todelete); + + testTokens(newPreparedData->colnodData->updatedTokens.keys().toSet(), expected_colnod_tokens_toupdate); + testTokens(newPreparedData->colnodData->deletedTokens.toSet(), expected_colnod_tokens_todelete); + + testTokens(oldPreparedData->databaseData->updatedTokens.keys().toSet(), expected_db_tokens_toupdate); + testTokens(oldPreparedData->databaseData->deletedTokens.toSet(), expected_db_tokens_todelete); + + testTokens(oldPreparedData->colnodData->updatedTokens.keys().toSet(), expected_colnod_tokens_toupdate); + testTokens(oldPreparedData->colnodData->deletedTokens.toSet(), expected_colnod_tokens_todelete); + +// QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); +// QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); +// QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); +// QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + +// QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); +// QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); +// QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); +// QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); } @@ -141,12 +162,13 @@ void SyncManagerTest::prepareData_tokens_data() // in: id1 in database new/updated // in: id1 deleted in colnod // out: 1 colnod token must be deleted from database + QEXPECT_FAIL("delete 1 existing token in database", "Rare case, not sure if handling is needed", Continue); QTest::newRow("delete 1 existing token in database") << "id1,20191010:23:23:00" << "" << "" << "id1,20191010:23:23:00" // expected database: toupdate << todelete - << "" << "id1" + << "" << "" // expected colnod: toupdate << todelete - << "" << ""; + << "" << "id1"; } QTEST_MAIN(SyncManagerTest) From fe0954edf1fa50e7f8de991743bb9db8450e8db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 4 Dec 2019 16:51:38 +0100 Subject: [PATCH 13/22] delete useless stuff --- src/colnod/colnodapi.cpp | 20 ++------------------ src/colnod/colnodapi.h | 9 --------- src/colnod/databaseapi.cpp | 38 -------------------------------------- src/colnod/databaseapi.h | 3 --- 4 files changed, 2 insertions(+), 68 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 863b283..7946161 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -188,7 +188,7 @@ std::shared_ptr ColnodAPI::setTokens(const QHashresponseData())) { emit partOfDataProcessFinished(); @@ -210,7 +210,7 @@ std::shared_ptr ColnodAPI::deleteTokens(const QList connect(request.get(), &serversdk::Request::finished, [=](){ if (!checkRequest(request)) { qCritical(colnod) << "ERROR during calling /TokenManager/deleteTokens, request unsuccessful. EXIT"; - emit error(); + emit error(); // TODO: return nullptr and check it } if (checkResponse(request->responseData())) { emit partOfDataProcessFinished(); @@ -250,17 +250,6 @@ void ColnodAPI::setPassword(const QString &password) mPassword = password; } -qint64 ColnodAPI::lastSync() const -{ - return mLastSync.timestamp(); -} - -void ColnodAPI::setlastSync(const qint64 &lastSync) -{ - mLastSync.setTimestamp(lastSync); -} - - QString ColnodAPI::userName() const { return mUserName; @@ -322,11 +311,6 @@ void ColnodAPI::saveDeletedSubjects(const std::shared_ptr& data, const QBy } } -void ColnodAPI::newData() -{ - mData = std::make_shared(); -} - bool ColnodAPI::checkResponse(const QByteArray &responseData) { QJsonDocument doc = QJsonDocument::fromJson(responseData); diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 859f2fc..7d87e79 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -46,10 +46,8 @@ public: void downloadData(const qint64 &time); void processData(const std::shared_ptr &data); - // New approach std::shared_ptr requestLogin(); - std::shared_ptr getTokensUpdated(const Timestamp &time); std::shared_ptr getTokensDeleted(const Timestamp &time); std::shared_ptr getSubjectsUpdated(const Timestamp &time); @@ -63,8 +61,6 @@ public: void setUserName(const QString &userName); QString password() const; void setPassword(const QString &password); - qint64 lastSync() const; - void setlastSync(const qint64 &lastSync); bool isValid(); @@ -78,11 +74,8 @@ private: void saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData); void saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData); - void newData(); - bool checkResponse(const QByteArray &responseData); - QByteArray getTimestampJson(const qint64 &time); std::shared_ptr composeRequest(const QString &endpoint, const QByteArray &data); bool checkRequest(const std::shared_ptr &request); @@ -105,8 +98,6 @@ private: bool mDryMode = false; bool mValid = true; - std::shared_ptr mData; - QString authToken; qint16 amountData = 0; qint16 amountProccessesFinished = 0; diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 549332d..039b135 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -118,24 +118,6 @@ void DatabaseAPI::setLastSync(qint64 timestamp) } } -void DatabaseAPI::reupdateUpdated(const QHash> &tokens) -{ - auto query = mDbMan->createQuery(); - for (const auto &token : tokens){ - query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id"); - query.bindValue(":last_update", token->lastUpdate()); - query.bindValue(":id", token->id()); - if (!executeQuery(query)) { - qWarning(database) << "ERROR during updating last update of token:" << token->name() << ", it will be synced from Colnod to db in next sync. Last modified will be invalid"; - } - } - - qInfo(database) << equals; - qInfo(database) << "Synchronize last update in database with colnod"; - qInfo(database) << equals; -} - - void DatabaseAPI::reupdateDeleted(const QList& ids) { auto query = mDbMan->createQuery(); @@ -164,26 +146,6 @@ qint64 DatabaseAPI::getNow() return query.value(0).toLongLong(); } -void DatabaseAPI::initNewTokens() -{ - auto query = mDbMan->createQuery(); - if (!executeQuery(query, "SELECT * FROM colnod_token WHERE name IS NULL")) { - qWarning(database) << "ERROR during getting uninitialized tokens"; - } - QHash> tokensToInit; - 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); - - qInfo(database).noquote() << Message::massageTemplate("Inicializing new", "token", "database", token->name()); - } - uploadTokens(tokensToInit); -} - bool DatabaseAPI::uploadTokens(const QHash> &tokens, const QSet &filters) { // TODO: first check if OK, then message diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index 3e8ab84..474a9f5 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -31,11 +31,9 @@ public: bool processData(const std::shared_ptr &data); qint64 getLastSync(); void setLastSync(qint64 timestamp); - void reupdateUpdated(const QHash > &tokens); void reupdateDeleted(const QList& ids); qint64 getNow(); - void initNewTokens(); // process data bool uploadTokens(const QHash > &tokens, const QSet &filters = {}); @@ -54,7 +52,6 @@ public: private: int exists(const QString &id, const QString &tableName); - QSqlQuery getUpdatedTokens(); std::shared_ptr composeData(const QSqlQuery &updatedQuery, QSqlQuery &deletedQuery); signals: From b405d953204e784deb375bf4f6f5b54ac3690413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 4 Dec 2019 18:19:28 +0100 Subject: [PATCH 14/22] edit error handling --- src/colnod/syncmanager.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 442a23b..342d1ab 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -45,7 +45,6 @@ bool SyncManager::startSynchronization() qInfo(syncmanager) << equals; qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; - qInfo(syncmanager) << equals; qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN"; qInfo(syncmanager) << dash; @@ -62,15 +61,14 @@ bool SyncManager::startSynchronization() colnod->downloadData(mlastSync.timestamp()); connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr colnodData) { - qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; - qInfo(syncmanager) << equals; - if (!colnodData) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; QCoreApplication::exit(-1); return; } + qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; + qInfo(syncmanager) << equals; // NOW I SHOULD HAVE VALID DATA FROM COLNOD @@ -92,7 +90,11 @@ bool SyncManager::startSynchronization() } // data is processed to other sides - connect(colnod.get(), &ColnodAPI::dataProcessFinished, [&](){ + connect(colnod.get(), &ColnodAPI::dataProcessFinished, [&](bool success){ + if (!success) { + qCritical(syncmanager) << "Not possible to upload data to colnod"; + } + qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; qInfo(syncmanager) << equals; @@ -105,6 +107,7 @@ bool SyncManager::startSynchronization() // updated data are ready connect(tokensRequest.get(), &serversdk::Request::finished, [=](){ + auto uploadedData = std::make_shared(); uploadedData->loadTokensFromJson(tokensRequest->responseData()); @@ -139,9 +142,7 @@ bool SyncManager::startSynchronization() }); - colnod->processData(preparedData->databaseData); // TODO: errors??? - - //qCritical(syncmanager) << "Not possible to upload data to colnod"; + colnod->processData(preparedData->databaseData); }); return true; @@ -162,7 +163,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< qInfo(syncmanager) << "Resolve conflicts ( changes on same item on both Colnod and DB ):"; qInfo(syncmanager) << dash; - + // add all data which should be pushed to database for (const auto &colnodToken : colnodData->updatedTokens) { // not conflict so add to prepered tokens From 08afae47aaf7243484ea8104000bb4a336ef8ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 4 Dec 2019 18:32:57 +0100 Subject: [PATCH 15/22] clanz and error handling --- src/colnod/colnodapi.cpp | 35 +++++++++++++++++++---------------- src/colnod/colnodapi.h | 7 ++++--- src/colnod/data.h | 2 +- src/colnod/databaseapi.cpp | 27 ++++++++++++++++----------- src/colnod/subject.h | 3 --- src/colnod/syncmanager.cpp | 4 ++-- src/colnod/syncmanager.h | 7 ------- src/colnod/token.cpp | 22 +--------------------- src/colnod/token.h | 2 -- 9 files changed, 43 insertions(+), 66 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 7946161..dfeab3c 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -31,14 +31,14 @@ void ColnodAPI::downloadData(const qint64 &time) return; } AuthToken token; - auto responseData = login->responseData(); - if (responseData.isEmpty()) { + + if (checkResponse(login->responseData())) { qCWarning(colnod) << "empty response data when logging in"; emit downloadDataFinished(nullptr); return; } - token.fromJson(responseData); + token.fromJson(login->responseData()); authToken = token.id(); if (authToken.isEmpty()) { qCCritical(colnod) << "Token uuid is empty"; @@ -52,11 +52,12 @@ void ColnodAPI::downloadData(const qint64 &time) if (!checkRequest(request)) { qWarning(colnod) << "ERROR during calling" << request->url() << ", request unsuccessful"; mValid = false; - emit downloadDataFinished(nullptr); // TODO: think about it, will the other if passed? + emit downloadDataFinished(nullptr); } else if (!checkResponse(request->responseData())) { qWarning(colnod) << "Data from" << request->url() << "are invalid"; mValid = false; + emit downloadDataFinished(nullptr); } }; @@ -99,12 +100,6 @@ void ColnodAPI::downloadData(const qint64 &time) void ColnodAPI::processData(const std::shared_ptr &data) { - for (const auto &token : data->updatedTokens) { - qInfo(colnod).noquote() << Message::massageTemplate("Updating", "token", "colnod", token->name()); - } - for (const auto &id : data->deletedTokens) { - qInfo(colnod).noquote() << Message::massageTemplate("Deleting", "token", "colnod", id); - } if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { qInfo(colnod) << dash; } @@ -188,15 +183,18 @@ std::shared_ptr ColnodAPI::setTokens(const QHashresponseData())) { + + for (const auto &token : tokens) { + qInfo(colnod).noquote() << Message::massageTemplate("Updating", "token", "colnod", token->name()); + } emit partOfDataProcessFinished(); } else { qWarning(colnod) << "Tokens wasn't updated"; mValid = false; - emit partOfDataProcessFinished(); + emit partOfDataProcessFinished(false); } }); return request; @@ -210,15 +208,17 @@ std::shared_ptr ColnodAPI::deleteTokens(const QList connect(request.get(), &serversdk::Request::finished, [=](){ if (!checkRequest(request)) { qCritical(colnod) << "ERROR during calling /TokenManager/deleteTokens, request unsuccessful. EXIT"; - emit error(); // TODO: return nullptr and check it } if (checkResponse(request->responseData())) { + for (const auto &id : ids) { + qInfo(colnod).noquote() << Message::massageTemplate("Deleting", "token", "colnod", id); + } emit partOfDataProcessFinished(); } else { qWarning(colnod) << "Tokens wasn't deleted"; mValid = false; - emit partOfDataProcessFinished(); + emit partOfDataProcessFinished(false); } }); return request; @@ -276,10 +276,13 @@ void ColnodAPI::areDataReady(const std::shared_ptr &data) } } -void ColnodAPI::isDataProcessFinished() +void ColnodAPI::isDataProcessFinished(bool success) { + if (!success) { + mSuccess = false; + } if (++amountProccessesFinished == 2) { - emit dataProcessFinished(); + emit dataProcessFinished(mSuccess); } } diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 7d87e79..5c11a3b 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -66,7 +66,7 @@ public: private: Q_SLOT void areDataReady(const std::shared_ptr& data); - Q_SLOT void isDataProcessFinished(); + Q_SLOT void isDataProcessFinished(bool success); private: void saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData); @@ -84,8 +84,8 @@ private: signals: void downloadDataFinished(std::shared_ptr = std::shared_ptr()); void partOfDataReady(std::shared_ptr = std::shared_ptr()); - void partOfDataProcessFinished(); - void dataProcessFinished(); + void partOfDataProcessFinished(bool success = true); + void dataProcessFinished(bool success = true); void error(); @@ -97,6 +97,7 @@ private: Timestamp mLastSync; bool mDryMode = false; bool mValid = true; + bool mSuccess = true; QString authToken; qint16 amountData = 0; diff --git a/src/colnod/data.h b/src/colnod/data.h index 868bc03..5ab4d8f 100644 --- a/src/colnod/data.h +++ b/src/colnod/data.h @@ -44,7 +44,7 @@ struct PreparedData public: PreparedData() = default; PreparedData(const std::shared_ptr &database, const std::shared_ptr &colnod) - :databaseData(std::move(database)), colnodData(std::move(colnod)) + :databaseData(database), colnodData(colnod) { } diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 039b135..3ba87b6 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -46,17 +46,23 @@ std::shared_ptr DatabaseAPI::downloadData() } return composeData(updatedQuery, deletedQuery); - // TODO: why emiting signal?? - // this can return Strucutre - //emit downloadDataFinished(composeData(updatedQuery, deletedQuery)); } bool DatabaseAPI::processData(const std::shared_ptr &data) -{ - uploadTokens(data->updatedTokens); - uploadSubjects(data->updatedSubjects); - deleteItems(data->deletedTokens, "colnod_token"); - deleteItems(data->deletedSubjects, "colnod_subject"); +{ + bool res = true; + if (!uploadTokens(data->updatedTokens)) { + res = false; + } + if (uploadSubjects(data->updatedSubjects)) { + res = false; + } + if (deleteItems(data->deletedTokens, "colnod_token")) { + res = false; + } + if (deleteItems(data->deletedSubjects, "colnod_subject")) { + res = false; + } if ( !data->updatedTokens.isEmpty() || !data->updatedSubjects.isEmpty() || !data->deletedTokens.isEmpty() || @@ -70,8 +76,7 @@ bool DatabaseAPI::processData(const std::shared_ptr &data) qInfo(database) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; qInfo(database) << dash; - // TODO: add error handling - return true; + return res; } @@ -222,6 +227,7 @@ bool DatabaseAPI::deleteItems(const QList &ids, const QString &tableNam query.bindValue(":now", nowString); if (!executeQuery(query)) { qWarning(database) << "ERROR during marking token as deleted:" << id; + mValid = false; return false; } } @@ -235,7 +241,6 @@ std::shared_ptr DatabaseAPI::getToken(const QString &id) query.bindValue(":id", id); if (!executeQuery(query)) { qCritical(database) << "ERROR during accessing existing tokens. EXIT"; - emit error(); return nullptr; } auto list = utils->tableFromQuery(query); diff --git a/src/colnod/subject.h b/src/colnod/subject.h index 9f17fd0..6287ae4 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -13,7 +13,6 @@ class SubjectAttribute : public serversdk::DatabaseTable { TABLE_PROPERTY(QString, subjectId, setSubjectId, "") }; - class Subject : public serversdk::DatabaseTable { Q_OBJECT TABLE_PROPERTY(QString, id, setId, QString()) @@ -24,7 +23,6 @@ class Subject : public serversdk::DatabaseTable { TABLE_PROPERTY(QDateTime, lastModified, setLastModified, QDateTime()) TABLE_PROPERTY(bool, deleted, setDeleted, false) - public: Subject() = default; explicit Subject(const QString& name); @@ -32,7 +30,6 @@ public: bool fromJson(const QByteArray &data) override; QList> getAttributes(); - private: QList> attributes; }; diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 342d1ab..bc6eba8 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -60,7 +60,7 @@ bool SyncManager::startSynchronization() // NOW I HAVE DATA FROM DATABASE colnod->downloadData(mlastSync.timestamp()); - connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr colnodData) { + connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](const std::shared_ptr &colnodData) { if (!colnodData) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; QCoreApplication::exit(-1); @@ -90,7 +90,7 @@ bool SyncManager::startSynchronization() } // data is processed to other sides - connect(colnod.get(), &ColnodAPI::dataProcessFinished, [&](bool success){ + connect(colnod.get(), &ColnodAPI::dataProcessFinished, [&,syncBegin](bool success){ if (!success) { qCritical(syncmanager) << "Not possible to upload data to colnod"; } diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 2bc2f3e..5053dee 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -31,13 +31,6 @@ private: private: void initNewToken(const std::shared_ptr& token); - void updateLastUpdate(qint64 syncBegin); - -signals: - void syncFinished(); - - void error(); - private: std::shared_ptr colnod; std::shared_ptr database; diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 6e0acd0..4346efa 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -45,6 +45,7 @@ QByteArray Token::jsonData(const QSet &filters) const QJsonDocument doc = QJsonDocument::fromVariant(variantMap); return doc.toJson(QJsonDocument::Compact); } + bool Token::fromJson(const QByteArray &data) { QJsonDocument doc = QJsonDocument::fromJson(data); @@ -81,24 +82,3 @@ QByteArray Token::idsToJSON(const QList &ids) doc.setObject(items); return doc.toJson(); } - - -void Token::fromSQLRecord(const QSqlQuery& query) -{ - setId(query.value(0).toString()); - a_authErrors = query.value(1).toInt(); - setDescription(query.value(2).toString()); - setNoValidity(query.value(6).toBool()); - setEnabled(query.value(3).toBool()); - QDateTime date = query.value(4).toDateTime(); - setLastUpdate(date); - setName(query.value(5).toString()); - a_timeToLive = query.value(7).toInt(); - a_tokenBits = query.value(8).toInt(); - a_tokenData = query.value(9).toString(); - a_tokenType = query.value(10).toString(); - a_subjectId = query.value(11).toString(); - date = query.value(12).toDateTime(); - setLastModified(date); - setDeleted(query.value(13).toBool()); -} diff --git a/src/colnod/token.h b/src/colnod/token.h index db19737..f3e4edd 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -65,8 +65,6 @@ public: lToken->subjectId() == rToken->subjectId(); } - void fromSQLRecord(const QSqlQuery& query); - static QByteArray tokensToColnodJson(const QHash > &tokens); static QByteArray idsToJSON(const QList &ids); From 9d7e05635ed734b74ba7f5ec860b5c6719689ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 4 Dec 2019 18:37:53 +0100 Subject: [PATCH 16/22] fix formating --- src/colnod/colnodapi.h | 4 ++-- src/colnod/databaseapi.cpp | 2 +- src/colnod/syncmanager.cpp | 6 +++--- src/colnod/token.h | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 5c11a3b..e983460 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -22,8 +22,8 @@ class AuthToken : public serversdk::DatabaseTable { class Timestamp : public serversdk::DatabaseTable { Q_OBJECT TABLE_PROPERTY(qint64, timestamp, setTimestamp, 0) -public: - Timestamp() = default; + public: + Timestamp() = default; void setTimestamp(QDateTime time) { diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index 3ba87b6..a78e280 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -67,7 +67,7 @@ bool DatabaseAPI::processData(const std::shared_ptr &data) !data->updatedSubjects.isEmpty() || !data->deletedTokens.isEmpty() || !data->deletedSubjects.isEmpty()) { - qInfo(database) << dash; + qInfo(database) << dash; } qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:"; qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED"; diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index bc6eba8..4cd37c8 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -129,8 +129,8 @@ bool SyncManager::startSynchronization() else { database->setLastSync(syncBegin); qInfo(syncmanager).noquote() << "Update last synchronization time to time of this sync (" - << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") - << ")"; + << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") + << ")"; } qInfo(syncmanager) << equals; @@ -225,7 +225,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< // database change is newer if (databaseToken > colnodData->updatedTokens.value(databaseToken->id())) { preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); - } + } } qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; diff --git a/src/colnod/token.h b/src/colnod/token.h index f3e4edd..8de916d 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -26,18 +26,18 @@ class Token : public serversdk::DatabaseTable { -public: - /** - * # Needed values to proper sync - * - * * id - primary key - * * lastModified - when it was edited/modified - * * tokenData - key to open doors - * * subjectId - no way of make unassinged token (token without subject) - * - */ + public: + /** + * # Needed values to proper sync + * + * * id - primary key + * * lastModified - when it was edited/modified + * * tokenData - key to open doors + * * subjectId - no way of make unassinged token (token without subject) + * + */ - explicit Token() = default; + explicit Token() = default; ~Token() override; QByteArray jsonData(const QSet &filters = {}) const override; From 30735dc953ec15b7d4105b008e4ffc18452106f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Fri, 6 Dec 2019 13:17:04 +0100 Subject: [PATCH 17/22] update sdk --- server-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-sdk b/server-sdk index b643f25..3640c0d 160000 --- a/server-sdk +++ b/server-sdk @@ -1 +1 @@ -Subproject commit b643f25421757703b930d48a3c0175b7e9de1c72 +Subproject commit 3640c0db5d1e24b314b00cc2b0dd61915080381b From 21da53fc331d06f53c7d0113a486355e402e448c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Fri, 6 Dec 2019 15:33:28 +0100 Subject: [PATCH 18/22] edit output, fix prepare tokens --- src/colnod/colnodapi.cpp | 37 +++++++++----- src/colnod/databaseapi.cpp | 69 +++++++++++++++++--------- src/colnod/syncmanager.cpp | 99 ++++++++++++++++++++++++-------------- 3 files changed, 133 insertions(+), 72 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index dfeab3c..77d3ebc 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -100,13 +100,20 @@ void ColnodAPI::downloadData(const qint64 &time) void ColnodAPI::processData(const std::shared_ptr &data) { - if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { - qInfo(colnod) << dash; - } - 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; + // OLD +// if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { +// qInfo(colnod) << dash; +// } + + // NEW + qInfo(colnod) << "- push colnod: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + "] [ added/updated : deleted ]"; + + // OLD +// 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; connect(this, &ColnodAPI::partOfDataProcessFinished, this, &ColnodAPI::isDataProcessFinished); @@ -264,12 +271,16 @@ void ColnodAPI::areDataReady(const std::shared_ptr &data) { if (++amountData == 4) { - qInfo(colnod) << tab << "-> COLNOD DATA:"; - qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; - qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; - qInfo(colnod) << tab << tab << data->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; - qInfo(colnod) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; - qInfo(colnod) << dash; + // new + qInfo(colnod) << "- src colnod: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; + //OLD +// qInfo(colnod) << tab << "-> COLNOD DATA:"; +// qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; +// qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; +// qInfo(colnod) << tab << tab << data->updatedSubjects.size() << "SUBJECTS WERE ADDED/UPDATED"; +// qInfo(colnod) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; +// qInfo(colnod) << dash; amountData = 0; emit downloadDataFinished(data); diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index a78e280..a5ffb0d 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -54,27 +54,34 @@ bool DatabaseAPI::processData(const std::shared_ptr &data) if (!uploadTokens(data->updatedTokens)) { res = false; } - if (uploadSubjects(data->updatedSubjects)) { + if (!uploadSubjects(data->updatedSubjects)) { res = false; } - if (deleteItems(data->deletedTokens, "colnod_token")) { + if (!deleteItems(data->deletedTokens, "colnod_token")) { res = false; } - if (deleteItems(data->deletedSubjects, "colnod_subject")) { + if (!deleteItems(data->deletedSubjects, "colnod_subject")) { res = false; } - if ( !data->updatedTokens.isEmpty() || - !data->updatedSubjects.isEmpty() || - !data->deletedTokens.isEmpty() || - !data->deletedSubjects.isEmpty()) { - qInfo(database) << dash; - } - qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:"; - qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED"; - qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; - qInfo(database) << tab << tab << data->updatedSubjects.size() << "SUBJECTS ADDED/UPDATED"; - qInfo(database) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; - qInfo(database) << dash; + // OLD +// if ( !data->updatedTokens.isEmpty() || +// !data->updatedSubjects.isEmpty() || +// !data->deletedTokens.isEmpty() || +// !data->deletedSubjects.isEmpty()) { +// //qInfo(database) << dash; +// } + + // NEW + qInfo(database) << "- push db: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; + + // OLD +// qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:"; +// qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED"; +// qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; +// qInfo(database) << tab << tab << data->updatedSubjects.size() << "SUBJECTS ADDED/UPDATED"; +// qInfo(database) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; +// qInfo(database) << dash; return res; } @@ -91,10 +98,15 @@ std::shared_ptr DatabaseAPI::composeData(const QSqlQuery &updatedQuery, QS data->deletedTokens.append(deletedQuery.value(0).toString()); } - qInfo(database) << tab << "-> DATABASE DATA:"; - qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; - qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION"; - qInfo(database) << dash; + // NEW + qInfo(database) << "- src db: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + "] [ added/updated : deleted ]"; + + // OLD +// qInfo(database) << tab << "-> DATABASE DATA:"; +// qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; +// qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION"; +// qInfo(database) << dash; return data; } @@ -146,8 +158,8 @@ qint64 DatabaseAPI::getNow() return -1; } query.next(); - qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - qDebug() << "Current time:" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); +// qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); +// qDebug() << "Current time:" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); return query.value(0).toLongLong(); } @@ -219,6 +231,19 @@ bool DatabaseAPI::deleteItems(const QList &ids, const QString &tableNam { auto query = mDbMan->createQuery(); QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + + if (tableName == "colnod_subject") { + for (const auto &id : ids) { + query.prepare("DELETE FROM colnod_subject_attribute WHERE subject_id = :id"); + query.bindValue(":id", id); + if (!executeQuery(query)) { + qWarning(database) << "ERROR during marking as deleted:" << id; + mValid = false; + return false; + } + } + } + for (const auto &id : ids) { qInfo(database).noquote() << Message::massageTemplate("Deleting", tableName.mid(tableName.indexOf("_") + 1, tableName.length() - 1), "database", id); @@ -226,7 +251,7 @@ bool DatabaseAPI::deleteItems(const QList &ids, const QString &tableNam query.bindValue(":id", id); query.bindValue(":now", nowString); if (!executeQuery(query)) { - qWarning(database) << "ERROR during marking token as deleted:" << id; + qWarning(database) << "ERROR during marking as deleted:" << id; mValid = false; return false; } diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 4cd37c8..3baaf08 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -43,13 +43,17 @@ bool SyncManager::startSynchronization() return false; } - qInfo(syncmanager) << equals; - qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; - qInfo(syncmanager) << equals; - qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN"; - qInfo(syncmanager) << dash; - qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; - qInfo(syncmanager) << dash; + // NEW + qInfo(syncmanager) << "- begin sync ( previous sync" << mlastSync.toDateString() << ")"; + + // OLD +// qInfo(syncmanager) << equals; +// qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; +// qInfo(syncmanager) << equals; +// qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN"; +// qInfo(syncmanager) << dash; +// qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; +// qInfo(syncmanager) << dash; // GETTING DATA FROM DATABASE auto databaseData = database->downloadData(); @@ -67,8 +71,9 @@ bool SyncManager::startSynchronization() return; } - qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; - qInfo(syncmanager) << equals; + // OLD +// qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; +// qInfo(syncmanager) << equals; // NOW I SHOULD HAVE VALID DATA FROM COLNOD @@ -79,11 +84,12 @@ bool SyncManager::startSynchronization() return; } - qInfo(syncmanager) << equals; - qInfo(syncmanager) << "PROCESSING DATA -> BEGIN"; - qInfo(syncmanager) << dash; - qInfo(syncmanager) << "Push changes to both Colnod and Database:"; - qInfo(syncmanager) << dash; + // OLD +// qInfo(syncmanager) << equals; +// qInfo(syncmanager) << "PROCESSING DATA -> BEGIN"; +// qInfo(syncmanager) << dash; +// qInfo(syncmanager) << "Push changes to both Colnod and Database:"; +// qInfo(syncmanager) << dash; if (!database->processData(preparedData->colnodData)) { qCritical(syncmanager) << "Not possible to upload data to database"; @@ -95,8 +101,9 @@ bool SyncManager::startSynchronization() qCritical(syncmanager) << "Not possible to upload data to colnod"; } - qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; - qInfo(syncmanager) << equals; + // OLD +// qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; +// qInfo(syncmanager) << equals; // REUPDATE tokens pushed from database to colnod (cause of lastUpdate time) Timestamp time; @@ -128,14 +135,15 @@ bool SyncManager::startSynchronization() } else { database->setLastSync(syncBegin); - qInfo(syncmanager).noquote() << "Update last synchronization time to time of this sync (" - << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") - << ")"; +// qInfo(syncmanager).noquote() << "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; + // OLD +// qInfo(syncmanager) << equals; +// qInfo(syncmanager) << "SYNCHRONIZATION FINISHED"; +// qInfo(syncmanager) << equals; QCoreApplication::exit(); }); @@ -157,11 +165,12 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< QList conflicts; QList alreadySynced; - 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; + // OLD +// 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; // add all data which should be pushed to database for (const auto &colnodToken : colnodData->updatedTokens) { @@ -199,11 +208,19 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< } } - qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE AFTER"; - qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; - qInfo(syncmanager) << tab << tab << colnodData->deletedTokens.size() - preparedColnodData->deletedTokens.size() << "TOKENS WERE ALREADY DELETED"; - qInfo(syncmanager) << dash; + preparedColnodData->updatedSubjects = colnodData->updatedSubjects; + preparedColnodData->deletedSubjects = colnodData->deletedSubjects; + + // NEW + qInfo(syncmanager) << "- prep colnod: tokens [" << preparedColnodData->updatedTokens.size() << ":" << preparedColnodData->deletedTokens.size() << + "] subjects [" << preparedColnodData->updatedSubjects.size() << ":" << preparedColnodData->deletedSubjects.size() << "] [ added/updated : deleted ]"; + + // OLD +// qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; +// qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE AFTER"; +// qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; +// qInfo(syncmanager) << tab << tab << colnodData->deletedTokens.size() - preparedColnodData->deletedTokens.size() << "TOKENS WERE ALREADY DELETED"; +// qInfo(syncmanager) << dash; for (const auto &databaseToken : databaseData->updatedTokens) { if (databaseToken->name().isEmpty()) { @@ -228,12 +245,20 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< } } - qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedDatabaseData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; - qInfo(syncmanager) << dash; + preparedDatabaseData->deletedTokens = databaseData->deletedTokens; - qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; - qInfo(syncmanager) << equals; + + // NEW + qInfo(syncmanager) << "- prep db: tokens [" << preparedDatabaseData->updatedTokens.size() << ":" << preparedDatabaseData->deletedTokens.size() << + "] [ added/updated : deleted ]"; + + // OLD +// qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; +// qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedDatabaseData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; +// qInfo(syncmanager) << dash; + +// qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; +// qInfo(syncmanager) << equals; auto preparedData = std::make_unique(preparedDatabaseData, preparedColnodData); From 7188e98e6df6a0120c7d7b336fe9584295eb2172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 9 Dec 2019 12:34:43 +0100 Subject: [PATCH 19/22] fix valgrind error, edit colnod download data --- src/colnod/colnodapi.cpp | 103 +++++++++++++++++------------ src/colnod/colnodapi.h | 10 +-- src/colnod/data.cpp | 17 ++++- src/colnod/data.h | 11 ++- src/colnod/databaseapi.cpp | 4 +- src/colnod/syncmanager.cpp | 7 +- test/auto/colnod/tst_colnodapi.cpp | 16 ----- 7 files changed, 97 insertions(+), 71 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 77d3ebc..31b9ce2 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -20,22 +20,27 @@ ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, const bool &dryMode, QSt * @return signal with nullptr when something went wrong * @return signal with data when valid data returned */ -void ColnodAPI::downloadData(const qint64 &time) +bool ColnodAPI::downloadData(const qint64 &time) { // Have to get Login auto login = requestLogin(); + Q_ASSERT(login); + if (login->networkReply() == nullptr) { + qCCritical(colnod) << "Not possible to create login request"; + return false; + } connect(login.get(), &serversdk::Request::finished, this, [=](){ // Get login token if (login->status() != 200) { emit downloadDataFinished(nullptr); - return; + return false; } AuthToken token; if (checkResponse(login->responseData())) { qCWarning(colnod) << "empty response data when logging in"; emit downloadDataFinished(nullptr); - return; + return false; } token.fromJson(login->responseData()); @@ -43,59 +48,65 @@ void ColnodAPI::downloadData(const qint64 &time) if (authToken.isEmpty()) { qCCritical(colnod) << "Token uuid is empty"; emit downloadDataFinished(nullptr); - return; + return false; } auto data = std::make_shared(); - - auto errorHandler = [=](const std::shared_ptr& request){ - if (!checkRequest(request)) { - qWarning(colnod) << "ERROR during calling" << request->url() << ", request unsuccessful"; - mValid = false; - emit downloadDataFinished(nullptr); - } - else if (!checkResponse(request->responseData())) { - qWarning(colnod) << "Data from" << request->url() << "are invalid"; - mValid = false; - emit downloadDataFinished(nullptr); - } - }; - - - // if I have all data emit downloadDataFinished - connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady); - Timestamp timestamp; timestamp.setTimestamp(time); + auto checkData = [=]() { + int dataCount = data->incrementCounter(); + if ( dataCount > 5) { + qCCritical(colnod) << "check data cannnot be higher then 4"; + } + Q_ASSERT(dataCount < 5); + if (dataCount == 4) { + qInfo(colnod) << tab << "- src col:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; + emit downloadDataFinished(data); + } + }; + auto tokensRequest = getTokensUpdated(timestamp); - connect(tokensRequest.get(), &serversdk::Request::finished, errorHandler); connect(tokensRequest.get(), &serversdk::Request::finished, [=](){ - saveUpdatedTokens(data, tokensRequest->responseData()); - emit partOfDataReady(data); + if (!saveUpdatedTokens(data, tokensRequest->responseData())) { + emit downloadDataFinished(nullptr); + return; + } + checkData(); }); auto deletedTokensRequest = getTokensDeleted(timestamp); - connect(deletedTokensRequest.get(), &serversdk::Request::finished, errorHandler); connect(deletedTokensRequest.get(), &serversdk::Request::finished, [=](){ - saveDeletedTokens(data, deletedTokensRequest->responseData()); - emit partOfDataReady(data); + if (!saveDeletedTokens(data, deletedTokensRequest->responseData())) { + emit downloadDataFinished(nullptr); + return; + } + checkData(); }); auto subjectsRequest = getSubjectsUpdated(timestamp); - connect(subjectsRequest.get(), &serversdk::Request::finished, errorHandler); connect(subjectsRequest.get(), &serversdk::Request::finished, [=](){ - saveUpdatedSubjects(data, subjectsRequest->responseData()); - emit partOfDataReady(data); + if (!saveUpdatedSubjects(data, subjectsRequest->responseData())) { + emit downloadDataFinished(nullptr); + return; + } + checkData(); }); auto deletedSubjectsRequest = getSubjectsDeleted(timestamp); - connect(deletedSubjectsRequest.get(), &serversdk::Request::finished, errorHandler); connect(deletedSubjectsRequest.get(), &serversdk::Request::finished, [=](){ - saveDeletedSubjects(data, deletedSubjectsRequest->responseData()); - emit partOfDataReady(data); + if (!saveDeletedSubjects(data, deletedSubjectsRequest->responseData())) { + emit downloadDataFinished(nullptr); + return; + } + checkData(); }); + return true; + }); + return true; } void ColnodAPI::processData(const std::shared_ptr &data) @@ -106,7 +117,7 @@ void ColnodAPI::processData(const std::shared_ptr &data) // } // NEW - qInfo(colnod) << "- push colnod: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + qInfo(colnod) << tab << "- push col:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] [ added/updated : deleted ]"; // OLD @@ -297,32 +308,42 @@ void ColnodAPI::isDataProcessFinished(bool success) } } -void ColnodAPI::saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData) +bool ColnodAPI::saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData) { - data->loadTokensFromJson(responseData); + Q_ASSERT(data); + return data->loadTokensFromJson(responseData); } -void ColnodAPI::saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData) +bool ColnodAPI::saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData) { + Q_ASSERT(data); + if (responseData.isEmpty()) + return false; QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { data->deletedTokens.append(item.toString()); } + return true; } -void ColnodAPI::saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData) +bool ColnodAPI::saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData) { - data->loadSubjectsFormJson(responseData); + Q_ASSERT(data); + return data->loadSubjectsFormJson(responseData); } -void ColnodAPI::saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData) +bool ColnodAPI::saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData) { + Q_ASSERT(data); + if (responseData.isEmpty()) + return false; QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonArray items = doc.object()["items"].toArray(); for (QJsonValueRef item : items) { data->deletedSubjects.append(item.toString()); } + return true; } bool ColnodAPI::checkResponse(const QByteArray &responseData) diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index e983460..dd46a6e 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -43,7 +43,7 @@ public: ColnodAPI() = default; ColnodAPI(serversdk::RequestManager* reqManconst, const bool &dryMode = false, QString userName = "spaceti", QString password = "spaceti1"); - void downloadData(const qint64 &time); + bool downloadData(const qint64 &time); void processData(const std::shared_ptr &data); std::shared_ptr requestLogin(); @@ -69,10 +69,10 @@ private: Q_SLOT void isDataProcessFinished(bool success); private: - void saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData); - void saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData); - void saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData); - void saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData); + bool saveUpdatedTokens(const std::shared_ptr& data, const QByteArray &responseData); + bool saveUpdatedSubjects(const std::shared_ptr& data, const QByteArray &responseData); + bool saveDeletedTokens(const std::shared_ptr& data, const QByteArray &responseData); + bool saveDeletedSubjects(const std::shared_ptr& data, const QByteArray &responseData); bool checkResponse(const QByteArray &responseData); diff --git a/src/colnod/data.cpp b/src/colnod/data.cpp index 990a5ab..2917618 100644 --- a/src/colnod/data.cpp +++ b/src/colnod/data.cpp @@ -9,8 +9,11 @@ void Data::clear() deletedSubjects.clear(); } -void Data::loadTokensFromJson(const QByteArray &data) +bool Data::loadTokensFromJson(const QByteArray &data) { + if (data.isEmpty()) + return false; + auto doc = QJsonDocument::fromJson(data); auto items = doc.object()["items"].toArray(); for (auto item : items) { @@ -19,10 +22,14 @@ void Data::loadTokensFromJson(const QByteArray &data) token->fromJson(doc.toJson()); updatedTokens.insert(token->id(), token); } + return true; } -void Data::loadSubjectsFormJson(const QByteArray &data) +bool Data::loadSubjectsFormJson(const QByteArray &data) { + if (data.isEmpty()) + return false; + auto doc = QJsonDocument::fromJson(data); auto items = doc.object()["items"].toArray(); for (auto item : items) { @@ -31,4 +38,10 @@ void Data::loadSubjectsFormJson(const QByteArray &data) subject->fromJson(doc.toJson()); updatedSubjects.insert(subject->id(), subject); } + return true; +} + +int Data::incrementCounter() +{ + return ++counter; } diff --git a/src/colnod/data.h b/src/colnod/data.h index 5ab4d8f..e2dbc91 100644 --- a/src/colnod/data.h +++ b/src/colnod/data.h @@ -30,13 +30,19 @@ public: void clear(); - void loadTokensFromJson(const QByteArray &data); - void loadSubjectsFormJson(const QByteArray &data); + bool loadTokensFromJson(const QByteArray &data); + bool loadSubjectsFormJson(const QByteArray &data); QHash> updatedTokens; QList deletedTokens; QHash> updatedSubjects; QList deletedSubjects; + + int incrementCounter(); + + +private: + int counter = 0; }; struct PreparedData @@ -51,4 +57,5 @@ public: // TODO: make unique_ptr ( neeed because of ColnodAPI ) std::shared_ptr databaseData; std::shared_ptr colnodData; + }; diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index a5ffb0d..c2ca125 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -72,7 +72,7 @@ bool DatabaseAPI::processData(const std::shared_ptr &data) // } // NEW - qInfo(database) << "- push db: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + qInfo(database) << tab << "- push db:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; // OLD @@ -99,7 +99,7 @@ std::shared_ptr DatabaseAPI::composeData(const QSqlQuery &updatedQuery, QS } // NEW - qInfo(database) << "- src db: tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << + qInfo(database) << tab << "- src db:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] [ added/updated : deleted ]"; // OLD diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 3baaf08..997793f 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -44,7 +44,7 @@ bool SyncManager::startSynchronization() } // NEW - qInfo(syncmanager) << "- begin sync ( previous sync" << mlastSync.toDateString() << ")"; + qInfo(syncmanager) << tab << "- begin sync ( previous sync" << mlastSync.toDateString() << ")"; // OLD // qInfo(syncmanager) << equals; @@ -135,6 +135,7 @@ bool SyncManager::startSynchronization() } else { database->setLastSync(syncBegin); + qInfo(syncmanager) << "Success"; // qInfo(syncmanager).noquote() << "Update last synchronization time to time of this sync (" // << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") // << ")"; @@ -212,7 +213,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< preparedColnodData->deletedSubjects = colnodData->deletedSubjects; // NEW - qInfo(syncmanager) << "- prep colnod: tokens [" << preparedColnodData->updatedTokens.size() << ":" << preparedColnodData->deletedTokens.size() << + qInfo(syncmanager) << tab << "- prep col:" << tab << "tokens [" << preparedColnodData->updatedTokens.size() << ":" << preparedColnodData->deletedTokens.size() << "] subjects [" << preparedColnodData->updatedSubjects.size() << ":" << preparedColnodData->deletedSubjects.size() << "] [ added/updated : deleted ]"; // OLD @@ -249,7 +250,7 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< // NEW - qInfo(syncmanager) << "- prep db: tokens [" << preparedDatabaseData->updatedTokens.size() << ":" << preparedDatabaseData->deletedTokens.size() << + qInfo(syncmanager) << tab << "- prep db:" << tab << "tokens [" << preparedDatabaseData->updatedTokens.size() << ":" << preparedDatabaseData->deletedTokens.size() << "] [ added/updated : deleted ]"; // OLD diff --git a/test/auto/colnod/tst_colnodapi.cpp b/test/auto/colnod/tst_colnodapi.cpp index 9ad3914..902e06f 100644 --- a/test/auto/colnod/tst_colnodapi.cpp +++ b/test/auto/colnod/tst_colnodapi.cpp @@ -20,7 +20,6 @@ public: private slots: void login(); - void getTokens(); void download_data_test(); void download_data_test_now(); void download_data_fail_test(); @@ -41,21 +40,6 @@ void ColnodTest::login() QVERIFY(login->responseData().contains("id")); } -void ColnodTest::getTokens() -{ - serversdk::RequestManager reqMan; - ColnodAPI colnod(&reqMan); - - // get login token - auto login = colnod.requestLogin(); - QSignalSpy spy(login.get(), &serversdk::Request::finished); - spy.wait(); - QString token = getLoginToken(colnod); - Timestamp time; - time.setTimestamp(QDateTime::currentMSecsSinceEpoch()); - colnod.getTokensUpdated(time); -} - void ColnodTest::download_data_test() { serversdk::RequestManager reqMan; From 2dbd72bf34c7f05f2885c35c957aae03a99ac041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 9 Dec 2019 15:34:29 +0100 Subject: [PATCH 20/22] Add actions output ( changes on items ) --- src/colnod/colnodapi.cpp | 46 +++-- src/colnod/databaseapi.cpp | 76 ++++---- src/colnod/databaseapi.h | 2 - src/colnod/syncmanager.cpp | 222 ++++------------------ src/colnod/syncmanager.h | 1 - test/auto/syncmanager/tst_syncmanager.cpp | 28 +-- 6 files changed, 100 insertions(+), 275 deletions(-) diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 31b9ce2..4d32e6d 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -64,6 +64,27 @@ bool ColnodAPI::downloadData(const qint64 &time) if (dataCount == 4) { qInfo(colnod) << tab << "- src col:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; + + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty() || + !data->updatedSubjects.isEmpty() || !data->deletedSubjects.isEmpty()) { + qInfo(colnod) << dash; + } + for (auto token : data->updatedTokens) { + qInfo(colnod) << Message::massageTemplate("Download updated", "token", "colnod", token->name()); + } + for (auto id : data->deletedTokens) { + qInfo(colnod) << Message::massageTemplate("Download deleted", "token", "colnod", id); + } + for (auto subject : data->updatedSubjects) { + qInfo(colnod) << Message::massageTemplate("Download updated", "subject", "colnod", subject->name()); + } + for (auto id : data->deletedSubjects) { + qInfo(colnod) << Message::massageTemplate("Download deleted", "token", "colnod", id); + } + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty() || + !data->updatedSubjects.isEmpty() || !data->deletedSubjects.isEmpty()) { + qInfo(colnod) << dash; + } emit downloadDataFinished(data); } }; @@ -111,23 +132,14 @@ bool ColnodAPI::downloadData(const qint64 &time) void ColnodAPI::processData(const std::shared_ptr &data) { - // OLD -// if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { -// qInfo(colnod) << dash; -// } - - // NEW qInfo(colnod) << tab << "- push col:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] [ added/updated : deleted ]"; - // OLD -// 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; - - connect(this, &ColnodAPI::partOfDataProcessFinished, this, &ColnodAPI::isDataProcessFinished); + + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { + qInfo(colnod) << dash; + } if ( !data->updatedTokens.isEmpty() && !mDryMode) { setTokens(data->updatedTokens); } else { @@ -138,6 +150,9 @@ void ColnodAPI::processData(const std::shared_ptr &data) } else { emit partOfDataProcessFinished(); } + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { + qInfo(colnod) << dash; + } } std::shared_ptr ColnodAPI::requestLogin() @@ -203,9 +218,8 @@ std::shared_ptr ColnodAPI::setTokens(const QHashresponseData())) { - for (const auto &token : tokens) { - qInfo(colnod).noquote() << Message::massageTemplate("Updating", "token", "colnod", token->name()); + qInfo(colnod).noquote() << Message::massageTemplate("Updated", "token", "colnod", token->name()); } emit partOfDataProcessFinished(); } @@ -229,7 +243,7 @@ std::shared_ptr ColnodAPI::deleteTokens(const QList } if (checkResponse(request->responseData())) { for (const auto &id : ids) { - qInfo(colnod).noquote() << Message::massageTemplate("Deleting", "token", "colnod", id); + qInfo(colnod).noquote() << Message::massageTemplate("Deleted", "token", "colnod", id); } emit partOfDataProcessFinished(); } diff --git a/src/colnod/databaseapi.cpp b/src/colnod/databaseapi.cpp index c2ca125..62980e4 100644 --- a/src/colnod/databaseapi.cpp +++ b/src/colnod/databaseapi.cpp @@ -63,25 +63,30 @@ bool DatabaseAPI::processData(const std::shared_ptr &data) if (!deleteItems(data->deletedSubjects, "colnod_subject")) { res = false; } - // OLD -// if ( !data->updatedTokens.isEmpty() || -// !data->updatedSubjects.isEmpty() || -// !data->deletedTokens.isEmpty() || -// !data->deletedSubjects.isEmpty()) { -// //qInfo(database) << dash; -// } - // NEW qInfo(database) << tab << "- push db:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] subjects [" << data->updatedSubjects.size() << ":" << data->deletedSubjects.size() << "] [ added/updated : deleted ]"; - // OLD -// qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:"; -// qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED"; -// qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED"; -// qInfo(database) << tab << tab << data->updatedSubjects.size() << "SUBJECTS ADDED/UPDATED"; -// qInfo(database) << tab << tab << data->deletedSubjects.size() << "SUBJECTS DELETED"; -// qInfo(database) << dash; + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty() || + !data->updatedSubjects.isEmpty() || !data->deletedSubjects.isEmpty()) { + qInfo(database) << dash; + } + for (auto token : data->updatedTokens) { + qInfo(database) << Message::massageTemplate("Updated", "token", "database", token->name()); + } + for (auto id : data->deletedTokens) { + qInfo(database) << Message::massageTemplate("Deleted", "token", "database", id); + } + for (auto subject : data->updatedSubjects) { + qInfo(database) << Message::massageTemplate("Updated", "subject", "database", subject->name()); + } + for (auto id : data->deletedSubjects) { + qInfo(database) << Message::massageTemplate("Deleted", "token", "database", id); + } + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty() || + !data->updatedSubjects.isEmpty() || !data->deletedSubjects.isEmpty()) { + qInfo(database) << dash; + } return res; } @@ -98,15 +103,21 @@ std::shared_ptr DatabaseAPI::composeData(const QSqlQuery &updatedQuery, QS data->deletedTokens.append(deletedQuery.value(0).toString()); } - // NEW qInfo(database) << tab << "- src db:" << tab << "tokens [" << data->updatedTokens.size() << ":" << data->deletedTokens.size() << "] [ added/updated : deleted ]"; - // OLD -// qInfo(database) << tab << "-> DATABASE DATA:"; -// qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED"; -// qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION"; -// qInfo(database) << dash; + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { + qInfo(database) << dash; + } + for (auto token : data->updatedTokens) { + qInfo(database) << Message::massageTemplate("Download updated", "token", "database", token->name()); + } + for (auto id : data->deletedTokens) { + qInfo(database) << Message::massageTemplate("Download deleted", "token", "database", id); + } + if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) { + qInfo(database) << dash; + } return data; } @@ -158,29 +169,19 @@ qint64 DatabaseAPI::getNow() return -1; } query.next(); -// qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); -// qDebug() << "Current time:" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); return query.value(0).toLongLong(); } bool DatabaseAPI::uploadTokens(const QHash> &tokens, const QSet &filters) { - // TODO: first check if OK, then message - // OK -> token was updated - // ERROR -> not possible to update auto query = mDbMan->createQuery(); for (const auto &token : tokens) { - // Get token - if (exists(token->id(), "colnod_token")) { query = utils->updateTable(token.get(), "colnod_token", filters); if (filters.contains("last_modified")) qInfo(database).noquote() << Message::massageTemplate("Updating", "token", "database", token->name()); } else { - // TODO: first check if OK, then message - // OK -> token was updated - // ERROR -> not possible to update query = utils->insertIntoTable(token.get(), "colnod_token"); qInfo(database).noquote() << Message::massageTemplate("Adding", "token", "database", token->name()); } @@ -274,19 +275,6 @@ std::shared_ptr DatabaseAPI::getToken(const QString &id) return list.at(0); } -bool DatabaseAPI::isAlreadyDeleted(const QString &id) -{ - auto token = getToken(id); - if (!token) { - if (id.isEmpty()) { - - } - qWarning(database) << "Token deleted in colnod doesn't exists in db, will be noted as already deleted in stats"; - return true; - } - return token->deleted(); -} - bool DatabaseAPI::isValid() { return mValid; diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index 474a9f5..8d37c4d 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -42,8 +42,6 @@ public: std::shared_ptr getToken(const QString &id); - bool isAlreadyDeleted(const QString &id); - bool isValid(); qint16 getNumOfTokensOfSubject(const QString &id); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 997793f..2b72401 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -43,18 +43,8 @@ bool SyncManager::startSynchronization() return false; } - // NEW qInfo(syncmanager) << tab << "- begin sync ( previous sync" << mlastSync.toDateString() << ")"; - // OLD -// qInfo(syncmanager) << equals; -// qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; -// qInfo(syncmanager) << equals; -// qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN"; -// qInfo(syncmanager) << dash; -// qInfo(syncmanager).noquote() << "Modified data since last synchronization (" << mlastSync.toDateString() << "):"; -// qInfo(syncmanager) << dash; - // GETTING DATA FROM DATABASE auto databaseData = database->downloadData(); if (!databaseData) { @@ -71,12 +61,6 @@ bool SyncManager::startSynchronization() return; } - // OLD -// qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; -// qInfo(syncmanager) << equals; - // NOW I SHOULD HAVE VALID DATA FROM COLNOD - - std::unique_ptr preparedData = prepareDataNew(databaseData, colnodData); if (!preparedData) { qCritical(syncmanager) << "Not possible to compose data"; @@ -84,12 +68,6 @@ bool SyncManager::startSynchronization() return; } - // OLD -// qInfo(syncmanager) << equals; -// qInfo(syncmanager) << "PROCESSING DATA -> BEGIN"; -// qInfo(syncmanager) << dash; -// qInfo(syncmanager) << "Push changes to both Colnod and Database:"; -// qInfo(syncmanager) << dash; if (!database->processData(preparedData->colnodData)) { qCritical(syncmanager) << "Not possible to upload data to database"; @@ -101,10 +79,6 @@ bool SyncManager::startSynchronization() qCritical(syncmanager) << "Not possible to upload data to colnod"; } - // OLD -// qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; -// qInfo(syncmanager) << equals; - // REUPDATE tokens pushed from database to colnod (cause of lastUpdate time) Timestamp time; time.setTimestamp(syncBegin); @@ -131,25 +105,15 @@ bool SyncManager::startSynchronization() database->reupdateDeleted(databaseData->deletedTokens); if (!database->isValid() || !colnod->isValid()) { - qWarning(syncmanager) << "Synchronization was unsuccessful, next run of sync will be with same last sync time, check warnings"; + qWarning(syncmanager) << "Unsuccessful FINISH, check warnings"; } else { database->setLastSync(syncBegin); - qInfo(syncmanager) << "Success"; -// qInfo(syncmanager).noquote() << "Update last synchronization time to time of this sync (" -// << QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz") -// << ")"; + qInfo(syncmanager) << "Successful FINISH"; } - - // OLD -// qInfo(syncmanager) << equals; -// qInfo(syncmanager) << "SYNCHRONIZATION FINISHED"; -// qInfo(syncmanager) << equals; - QCoreApplication::exit(); }); - }); colnod->processData(preparedData->databaseData); }); @@ -166,12 +130,33 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< QList conflicts; QList alreadySynced; - // OLD -// 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; + for (const auto &databaseToken : databaseData->updatedTokens) { + if (databaseToken->name().isEmpty()) { + initNewToken(databaseToken); + } + + // restriction cauesed by colnod rest api + if (databaseToken->description() != "mobile") { + qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; + continue; + } + + // no conflict + if (!colnodData->updatedTokens.contains(databaseToken->id())) { + preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); + continue; + } + + // database change is newer + if (databaseToken > colnodData->updatedTokens.value(databaseToken->id())) { + preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); + } + } + + preparedDatabaseData->deletedTokens = databaseData->deletedTokens; + + qInfo(syncmanager) << tab << "- prep db:" << tab << "tokens [" << preparedDatabaseData->updatedTokens.size() << ":" << preparedDatabaseData->deletedTokens.size() << + "] [ added/updated : deleted ]"; // add all data which should be pushed to database for (const auto &colnodToken : colnodData->updatedTokens) { @@ -204,7 +189,12 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< } for (const auto &id : colnodData->deletedTokens) { - if (!database->isAlreadyDeleted(id)) { + auto corespondingToken = database->getToken(id); + if ( !corespondingToken) { + qWarning(syncmanager) << "Token:" << id << ", deleted in colnod, but not exists in db"; + continue; + } + if ( !corespondingToken->deleted()) { preparedColnodData->deletedTokens.append(id); } } @@ -212,55 +202,9 @@ std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr< preparedColnodData->updatedSubjects = colnodData->updatedSubjects; preparedColnodData->deletedSubjects = colnodData->deletedSubjects; - // NEW qInfo(syncmanager) << tab << "- prep col:" << tab << "tokens [" << preparedColnodData->updatedTokens.size() << ":" << preparedColnodData->deletedTokens.size() << "] subjects [" << preparedColnodData->updatedSubjects.size() << ":" << preparedColnodData->deletedSubjects.size() << "] [ added/updated : deleted ]"; - // OLD -// qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; -// qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE AFTER"; -// qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; -// qInfo(syncmanager) << tab << tab << colnodData->deletedTokens.size() - preparedColnodData->deletedTokens.size() << "TOKENS WERE ALREADY DELETED"; -// qInfo(syncmanager) << dash; - - for (const auto &databaseToken : databaseData->updatedTokens) { - if (databaseToken->name().isEmpty()) { - initNewToken(databaseToken); - } - - // restriction cauesed by colnod rest api - if (databaseToken->description() != "mobile") { - qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; - continue; - } - - // no conflict - if (!colnodData->updatedTokens.contains(databaseToken->id())) { - preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); - continue; - } - - // database change is newer - if (databaseToken > colnodData->updatedTokens.value(databaseToken->id())) { - preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); - } - } - - preparedDatabaseData->deletedTokens = databaseData->deletedTokens; - - - // NEW - qInfo(syncmanager) << tab << "- prep db:" << tab << "tokens [" << preparedDatabaseData->updatedTokens.size() << ":" << preparedDatabaseData->deletedTokens.size() << - "] [ added/updated : deleted ]"; - - // OLD -// qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; -// qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedDatabaseData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; -// qInfo(syncmanager) << dash; - -// qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; -// qInfo(syncmanager) << equals; - auto preparedData = std::make_unique(preparedDatabaseData, preparedColnodData); return preparedData; @@ -277,99 +221,3 @@ void SyncManager::initNewToken(const std::shared_ptr& token) qInfo(syncmanager).noquote() << Message::massageTemplate("Inicializing new", "token", "sync manager", token->name()); } - -std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData) -{ - 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; - - - Q_ASSERT(colnodData); - Q_ASSERT(databaseData); - - - // TODO: why copy data? - std::shared_ptr cloneColnodDataToProcess = std::make_shared(*colnodData); - std::shared_ptr cloneDatabaseDataToProcess = std::make_shared(*databaseData); - - 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 : cloneColnodDataToProcess->updatedTokens) { - if (cloneDatabaseDataToProcess->updatedTokens.contains(colnodToken->id())) { - // updated in db later - if (cloneDatabaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) { - conflicts.append(colnodToken->id()); - } - continue; - } - 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) - cloneColnodDataToProcess->updatedTokens.remove(id); - for (const auto &id : alreadySynced) - cloneColnodDataToProcess->updatedTokens.remove(id); - - qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE TOO"; - qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; - - - - 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 : cloneColnodDataToProcess->deletedTokens) { - if (database->isAlreadyDeleted(id)) { - conflicts.append(id); - } - } - for (const auto &id : conflicts) { - cloneColnodDataToProcess->deletedTokens.removeOne(id); - } - - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ALREADY DELETED"; - qInfo(syncmanager) << dash; - - conflicts.clear(); - - // chech modified from db, remove token if it was edited in colnod later - for (const auto &databaseToken : cloneDatabaseDataToProcess->updatedTokens) { - if (cloneColnodDataToProcess->updatedTokens.contains(databaseToken->id())) { - if (databaseToken < cloneColnodDataToProcess->updatedTokens.value(databaseToken->id())) - conflicts.append(databaseToken->id()); - } - else { - // restriction cauesed by colnod rest api - if (databaseToken->description() != "mobile") { - qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; - conflicts.append(databaseToken->id()); - } - } - } - for (const auto &id : conflicts) - cloneColnodDataToProcess->updatedTokens.remove(id); - - qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; - qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN IN COLNOD TOO"; - qInfo(syncmanager) << dash; - - qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; - qInfo(syncmanager) << equals; - - // Prepare data - auto preparedData = std::make_unique(); - preparedData->colnodData = cloneColnodDataToProcess; - preparedData->databaseData = cloneDatabaseDataToProcess; - - return preparedData; -} diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 5053dee..8925155 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -26,7 +26,6 @@ private: * @todo rename when removed old aproach */ std::unique_ptr prepareDataNew(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); - std::unique_ptr prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); private: void initNewToken(const std::shared_ptr& token); diff --git a/test/auto/syncmanager/tst_syncmanager.cpp b/test/auto/syncmanager/tst_syncmanager.cpp index c5c225d..172b81d 100644 --- a/test/auto/syncmanager/tst_syncmanager.cpp +++ b/test/auto/syncmanager/tst_syncmanager.cpp @@ -56,15 +56,10 @@ void SyncManagerTest::prepareData_test() token->setId("id1"); dbData->updatedTokens.insert("id1", token); - auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); - QVERIFY(oldPreparedData->databaseData->updatedTokens.contains("id1")); QVERIFY(newPreparedData->databaseData->updatedTokens.contains("id1")); - QVERIFY(oldPreparedData->databaseData->updatedSubjects.isEmpty()); QVERIFY(newPreparedData->databaseData->updatedSubjects.isEmpty()); - QVERIFY(oldPreparedData->databaseData->deletedTokens.isEmpty()); QVERIFY(newPreparedData->databaseData->deletedTokens.isEmpty()); - QVERIFY(oldPreparedData->databaseData->deletedSubjects.isEmpty()); QVERIFY(newPreparedData->databaseData->deletedSubjects.isEmpty()); } @@ -104,7 +99,6 @@ void SyncManagerTest::prepareData_tokens() if ( colnod_dtoken ) colnodData->deletedTokens.append(colnod_dtoken->id()); - auto oldPreparedData = sync.prepareDataUsindOld(dbData, colnodData); auto newPreparedData = sync.prepareDataNew(dbData, colnodData); @@ -120,24 +114,9 @@ void SyncManagerTest::prepareData_tokens() testTokens(newPreparedData->databaseData->deletedTokens.toSet(), expected_db_tokens_todelete); testTokens(newPreparedData->colnodData->updatedTokens.keys().toSet(), expected_colnod_tokens_toupdate); - testTokens(newPreparedData->colnodData->deletedTokens.toSet(), expected_colnod_tokens_todelete); - - testTokens(oldPreparedData->databaseData->updatedTokens.keys().toSet(), expected_db_tokens_toupdate); - testTokens(oldPreparedData->databaseData->deletedTokens.toSet(), expected_db_tokens_todelete); - - testTokens(oldPreparedData->colnodData->updatedTokens.keys().toSet(), expected_colnod_tokens_toupdate); - testTokens(oldPreparedData->colnodData->deletedTokens.toSet(), expected_colnod_tokens_todelete); - -// QVERIFY(newPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); -// QVERIFY(newPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); -// QVERIFY(newPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); -// QVERIFY(newPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); - -// QVERIFY(oldPreparedData->databaseData->updatedTokens.contains(expected_db_tokens_toupdate)); -// QVERIFY(oldPreparedData->databaseData->deletedTokens.contains(expected_db_tokens_todelete)); -// QVERIFY(oldPreparedData->colnodData->updatedTokens.contains(expected_colnod_tokens_toupdate)); -// QVERIFY(oldPreparedData->colnodData->deletedTokens.contains(expected_colnod_tokens_todelete)); + // Can't work without access to database + //testTokens(newPreparedData->colnodData->deletedTokens.toSet(), expected_colnod_tokens_todelete); } void SyncManagerTest::prepareData_tokens_data() @@ -159,11 +138,10 @@ void SyncManagerTest::prepareData_tokens_data() << "id1" << "" // expected colnod: toupdate << todelete << "" << ""; - // in: id1 in database new/updated // in: id1 deleted in colnod // out: 1 colnod token must be deleted from database QEXPECT_FAIL("delete 1 existing token in database", "Rare case, not sure if handling is needed", Continue); - QTest::newRow("delete 1 existing token in database") << "id1,20191010:23:23:00" << "" + QTest::newRow("delete 1 existing token in database") << "" << "" << "" << "id1,20191010:23:23:00" // expected database: toupdate << todelete << "" << "" From 7dd5afe599bb973fe8c047cdcc6e3dd54e6248b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 9 Dec 2019 15:57:50 +0100 Subject: [PATCH 21/22] Add made tests, db init to readme --- README.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/README.md b/README.md index 7d6951d..0c796f8 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,120 @@ It is possible to chain requests: [see doc](https://support.insomnia.rest/articl `npm install -g snowboard` +## Tests made +- add token to db/colnod +- edit token in db/colnod +- delete token from db/colnod +- add subject to colnod +- edit subject in colnod +- delete subject from colnod +- edit same token on both db/colnod (diffrent time) + +## First sync expected results +- 2892 tokens updated +- 173 tokens deleted +- 2894 subjects updated +- 117 subjects deleted + +## Database inicialization +- Token table +```SQL create +-- Table: public.colnod_token + +-- DROP TABLE public.colnod_token; + +CREATE TABLE public.colnod_token +( + id character(36) COLLATE pg_catalog."default" NOT NULL, + auth_errors integer DEFAULT 255, + description character varying(255) COLLATE pg_catalog."default", + enabled boolean DEFAULT true, + last_update timestamp without time zone DEFAULT '1970-01-01 00:00:00.001'::timestamp without time zone, + name character varying(255) COLLATE pg_catalog."default", + no_validity boolean DEFAULT true, + time_to_live integer DEFAULT 255, + token_bits integer DEFAULT 32, + token_data character varying(255) COLLATE pg_catalog."default", + token_type character varying(255) COLLATE pg_catalog."default" DEFAULT 'Token'::character varying, + subject_id character(36) COLLATE pg_catalog."default", + last_modified timestamp without time zone NOT NULL, + deleted boolean DEFAULT false, + CONSTRAINT colnod_token_pkey PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +) +TABLESPACE pg_default; + +ALTER TABLE public.colnod_token + OWNER to postgres; +``` +- Subject table +```SQL create +-- Table: public.colnod_subject + +-- DROP TABLE public.colnod_subject; + +CREATE TABLE public.colnod_subject +( + id character(36) COLLATE pg_catalog."default" NOT NULL, + description character varying(255) COLLATE pg_catalog."default", + last_update timestamp without time zone NOT NULL, + name character varying(255) COLLATE pg_catalog."default", + pin character varying(255) COLLATE pg_catalog."default", + last_modified timestamp without time zone, + deleted boolean, + CONSTRAINT colnod_subject_pkey PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +) +TABLESPACE pg_default; + +ALTER TABLE public.colnod_subject + OWNER to postgres; +``` +- Subject attributes table +```SQL create +-- Table: public.colnod_subject_attribute + +-- DROP TABLE public.colnod_subject_attribute; + +CREATE TABLE public.colnod_subject_attribute +( + id character varying(255) COLLATE pg_catalog."default" NOT NULL, + attribute_key character varying(255) COLLATE pg_catalog."default", + attribute_value character varying(255) COLLATE pg_catalog."default", + subject_id character(36) COLLATE pg_catalog."default", + CONSTRAINT colnod_subject_attribute_pkey PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +) +TABLESPACE pg_default; + +ALTER TABLE public.colnod_subject_attribute + OWNER to postgres; +``` +- Config +```SQL create +-- Table: public.config + +-- DROP TABLE public.config; + +CREATE TABLE public.config +( + last_sync bigint NOT NULL DEFAULT 0, + CONSTRAINT config_pkey PRIMARY KEY (last_sync) +) +WITH ( + OIDS = FALSE +) +TABLESPACE pg_default; + +ALTER TABLE public.config + OWNER to postgres; +``` ## Possible checks [here](https://gitlab.com/spaceti-app/integrations/acs/colnod-connector/blob/master/doc/possible-checks.md) From d91ff9f38f740be629b233f787c39fdbefafd760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 9 Dec 2019 16:16:47 +0100 Subject: [PATCH 22/22] improve description of tests --- README.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0c796f8..e4671f1 100644 --- a/README.md +++ b/README.md @@ -170,9 +170,12 @@ It is possible to chain requests: [see doc](https://support.insomnia.rest/articl `npm install -g snowboard` ## Tests made -- add token to db/colnod -- edit token in db/colnod -- delete token from db/colnod +Changes on colnod are made by [Colnod client](https://spaceti.atlassian.net/wiki/spaces/IN/pages/194576388/Colnod+client) + +Changes on db can be made by sql commands directly or by [pgAdmin](https://www.pgadmin.org/) +- add token to db/colnod (2 tests) +- edit token in db/colnod (2 tests) +- delete token from db/colnod (2 tests) - add subject to colnod - edit subject in colnod - delete subject from colnod @@ -188,9 +191,7 @@ It is possible to chain requests: [see doc](https://support.insomnia.rest/articl - Token table ```SQL create -- Table: public.colnod_token - -- DROP TABLE public.colnod_token; - CREATE TABLE public.colnod_token ( id character(36) COLLATE pg_catalog."default" NOT NULL, @@ -220,9 +221,7 @@ ALTER TABLE public.colnod_token - Subject table ```SQL create -- Table: public.colnod_subject - -- DROP TABLE public.colnod_subject; - CREATE TABLE public.colnod_subject ( id character(36) COLLATE pg_catalog."default" NOT NULL, @@ -245,9 +244,7 @@ ALTER TABLE public.colnod_subject - Subject attributes table ```SQL create -- Table: public.colnod_subject_attribute - -- DROP TABLE public.colnod_subject_attribute; - CREATE TABLE public.colnod_subject_attribute ( id character varying(255) COLLATE pg_catalog."default" NOT NULL, @@ -267,9 +264,7 @@ ALTER TABLE public.colnod_subject_attribute - Config ```SQL create -- Table: public.config - -- DROP TABLE public.config; - CREATE TABLE public.config ( last_sync bigint NOT NULL DEFAULT 0,