From ab6a200551251e21bd2340dde4fa91a41ad6c777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 21 Oct 2019 10:06:49 +0200 Subject: [PATCH 01/23] Changing stuff for one table sync --- src/app/main.cpp | 19 +++- src/colnod/colnodapi.cpp | 127 +++++++++++++------------ src/colnod/colnodapi.h | 30 +++--- src/colnod/databasemanager.cpp | 8 +- src/colnod/databasemanager.h | 4 +- src/colnod/datamanager.cpp | 165 ++++++++++++++++++++------------- src/colnod/datamanager.h | 41 +++++--- src/colnod/requestmanager.cpp | 4 +- src/colnod/requestmanager.h | 4 +- src/colnod/subject.cpp | 5 + src/colnod/subject.h | 2 + test/unitTests/UnitTest.cpp | 4 +- test/unitTests/complextest.cpp | 12 ++- 13 files changed, 264 insertions(+), 161 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 70c5e9e..30d341b 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -8,12 +8,27 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); ColnodAPI *api = new ColnodAPI(); - api->downloadData(); // this will start downloading data + /*api->downloadData(); // this will start downloading data QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ qDebug() << "now I have all data"; api->syncDataToColnod(); QCoreApplication::quit(); - }); + });*/ +// bool syncChanged = false; +// api->downloadChangedDataFromColnod(); +// QObject::connect(api, &ColnodAPI::downloadData, [&](){ +// qDebug() << "Data ready."; +// api->syncChangedDataFromColnod(); +// if (!syncChanged) +// { +// api->syncChangedDataToColnod(); +// syncChanged = true; +// } +// }); + + api->loadDataFromColnod(); + api->loadDataFromDB(); + return a.exec(); } diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 7584be2..be42326 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -8,87 +8,103 @@ ColnodAPI::ColnodAPI() // PUBLIC FUNCTIONS -void ColnodAPI::downloadData() +//void ColnodAPI::downloadData() +//{ +// Response* resp0 = reqMan->getSubjects(); +// connect(resp0, &Response::ready, [=](){ +// dataMan->localSaveSubjects(resp0->getJson()); +// areDataReady(); +// resp0->deleteLater(); +// }); + +// Response* resp1 = reqMan->getTokens(); +// connect(resp1, &Response::ready, [=](){ +// dataMan->localSaveTokens(resp1->getJson()); +// areDataReady(); +// resp1->deleteLater(); +// }); + +// /* +// QNetworkReply* reply2 = reqMan->getTokens(); +// connect(reply2, &QNetworkReply::finished, [=](){ +// data->saveTokens(reply2->readAll()); +// }); +// */ +//} + + +void ColnodAPI::loadDataFromColnod() { - Response* resp0 = reqMan->getSubjects(); - connect(resp0, &Response::ready, [=](){ - dataMan->localSaveSubjects(resp0->getJson()); - areDataReady(); - resp0->deleteLater(); - }); - - Response* resp1 = reqMan->getTokens(); - connect(resp1, &Response::ready, [=](){ - dataMan->localSaveTokens(resp1->getJson()); - areDataReady(); - resp1->deleteLater(); - }); - - /* - QNetworkReply* reply2 = reqMan->getTokens(); - connect(reply2, &QNetworkReply::finished, [=](){ - data->saveTokens(reply2->readAll()); - }); - */ + loadTokensFromColnod(); + loadUpdatedDataFromColnod(); + loadDeletedDataFromColnod(); } -void ColnodAPI::downloadChangedDataFromColnod() +void ColnodAPI::loadTokensFromColnod() { - downloadUpdatedData(); - downloadDeletedData(); + Response* resp = reqMan->getTokens(); + connect(resp, &Response::ready, [=](){ + dataMan->fillFullTokensColnod(resp->getJson()); + + }); } -void ColnodAPI::downloadUpdatedData() +void ColnodAPI::loadUpdatedDataFromColnod() { - uint64_t lastUpdate = dataMan->getLastUpdate(); - qDebug() << lastUpdate; + uint64_t lastUpdate = dataMan->getLastSync(); Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate); connect(resp0, &Response::ready, [=](){ - dataMan->localSaveSubjects(resp0->getJson()); + dataMan->fillSubjectsColnod(resp0->getJson()); areChangedDataReady(); resp0->deleteLater(); }); Response* resp1 = reqMan->getTokensUpdated(lastUpdate); connect(resp1, &Response::ready, [=](){ - dataMan->localSaveTokens(resp1->getJson()); + dataMan->fillTokensColnod(resp1->getJson()); areChangedDataReady(); resp1->deleteLater(); }); } -void ColnodAPI::downloadDeletedData() +void ColnodAPI::loadDeletedDataFromColnod() { - uint64_t lastUpdate = dataMan->getLastUpdate(); + uint64_t lastUpdate = dataMan->getLastSync(); Response* resp2 = reqMan->getSubjectsDeleted(lastUpdate); connect(resp2, &Response::ready, [=](){ - dataMan->localSaveSubjectsToDelete(resp2->getJson()); + dataMan->fillSubjectsToDeleteColnod(resp2->getJson()); areChangedDataReady(); resp2->deleteLater(); }); Response* resp3 = reqMan->getTokensDeleted(lastUpdate); connect(resp3, &Response::ready, [=](){ - dataMan->localSaveTokensToDelete(resp3->getJson()); + dataMan->fillTokensToDeleteColnod(resp3->getJson()); areChangedDataReady(); resp3->deleteLater(); }); } -void ColnodAPI::syncDataFromColnod() +void ColnodAPI::loadDataFromDB() { - dataMan->pushTokensToDB(); - dataMan->pushSubjectsToDB(); - dataMan->updateLastSync(); - dataMan->clear(); + dataMan->fillTokensDB(); + dataMan->fillTokensToDeleteDB(); } -void ColnodAPI::syncChangedDataFromColnod() +//void ColnodAPI::syncDataFromColnod() +//{ +// dataMan->pushTokensToDB(); +// dataMan->pushSubjectsToDB(); +// dataMan->updateLastSync(); +// dataMan->clear(); +//} + +void ColnodAPI::syncDataFromColnod() { syncUpdatedDataFromColnod(); syncDeletedDataFromColnod(); - dataMan->updateLastSync(); + //dataMan->updateLastSync(); dataMan->clear(); } @@ -105,22 +121,12 @@ void ColnodAPI::syncDeletedDataFromColnod() dataMan->deleteTokensFromDB(); } - - - -void ColnodAPI::syncDataToColnod() -{ - // TODO -} - - -void ColnodAPI::syncChangedDataToColnod() +void ColnodAPI::syncDataFromDB() { // TODO dataMan->loadTokensToAdd(); dataMan->loadTokensToDelete(); processDataToColnod(); - dataMan->clear(); } @@ -129,22 +135,23 @@ void ColnodAPI::processDataToColnod() QList* tokensToDelete = dataMan->getTokensToDelete(); if ((*tokensToDelete)[0] != "empty") { - Response* resp0 = reqMan->deleteTokens(dataMan->getTokensToDelete()); + Response* resp0 = reqMan->deleteTokens(tokensToDelete); connect(resp0, &Response::ready, [=](){ - areProcessDataReady(); + isProcessDone(); resp0->deleteLater(); }); } - QList>* tokens = dataMan->getTokens(); - if ((*tokens)[0]->getName() != "empty") + QHash>* tokens = dataMan->getTokens(); + if (!tokens[0].contains("empty")) { - Response* resp1 = reqMan->setTokens(dataMan->getTokens()); + Response* resp1 = reqMan->setTokens(tokens); connect(resp1, &Response::ready, [=](){ - areProcessDataReady(); + isProcessDone(); resp1->deleteLater(); }); } - connect(this, &ColnodAPI::dataLoaded, this, &ColnodAPI::syncChangedDataFromColnod); + dataMan->clear(); + connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod); } void ColnodAPI::prepareDatabase() @@ -166,10 +173,10 @@ void ColnodAPI::areChangedDataReady() } -void ColnodAPI::areProcessDataReady() +void ColnodAPI::isProcessDone() { if (dataMan->haveProcessData()) { - emit dataLoaded(); + emit dataProcessed(); } } diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 31bbb2f..fea1cb1 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -14,14 +14,14 @@ class ColnodAPI : public QObject public: ColnodAPI(); - void downloadData(); + /// + //void downloadData(); + //void syncDataFromColnod(); + //void syncDataToColnod(); + /// + void syncDataFromColnod(); - void syncDataToColnod(); - - - - void syncChangedDataFromColnod(); - void syncChangedDataToColnod(); + void syncDataFromDB(); @@ -29,24 +29,30 @@ public: void prepareDatabase(); public slots: - void downloadChangedDataFromColnod(); + void loadDataFromColnod(); + void loadDataFromDB(); signals: void dataDownloaded(); - void dataLoaded(); + void dataProcessed(); private slots: private: - void downloadUpdatedData(); - void downloadDeletedData(); + void loadTokensFromColnod(); + void loadUpdatedDataFromColnod(); + void loadDeletedDataFromColnod(); + void loadUpdatedDataFromDB(); + void loadDeletedDataFromDB(); + + void syncUpdatedDataFromColnod(); void syncDeletedDataFromColnod(); void areDataReady(); void areChangedDataReady(); - void areProcessDataReady(); + void isProcessDone(); void processDataToColnod(); diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index f45ca8a..60e2aca 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -164,11 +164,13 @@ void DatabaseManager::createTables() "last_update timestamp)"); } -uint64_t DatabaseManager::getLastUpdate() +uint64_t DatabaseManager::getAndSetLastSync() { - query.exec("SELECT EXTRACT(EPOCH FROM (SELECT MIN(last_sync) FROM changes))*1000"); //MAX for using, MIN for testing + query.exec("SELECT EXTRACT(EPOCH FROM (SELECT last_sync FROM config))*1000"); query.next(); - return query.value(0).toULongLong(); + uint64_t temp = query.value(0).toULongLong(); + query.exec("UPDATE config SET last_sync = NOW()"); + return temp; } void DatabaseManager::makeTestingLast_sync() diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 0425ae5..9b597f0 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -18,6 +18,8 @@ class DatabaseManager : public QObject public: DatabaseManager(QString host, QString dbName, QString user, QString password); + + void saveSubject(Subject* subject, QString table); void saveToken(Token* token, QString table); void saveSubjectAttribute(Subject* subject, QString table); @@ -33,7 +35,7 @@ public: void createTables(); bool getOpened() {return opened;} - uint64_t getLastUpdate(); + uint64_t getAndSetLastSync(); void updateLastSync(); QSqlQuery* getTokensToAdd(); diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index f4d195d..095efaa 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -3,31 +3,11 @@ DataManager::DataManager() { db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12"); + lastSync = db->getAndSetLastSync(); //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); } -void DataManager::localSaveSubjects(QString response) -{ - QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); - QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) - { - for (QJsonValueRef item : items) - { - auto subject = new Subject(); - subject->fromJSON(item.toObject()); - subjects.append(subject); - } - } - else - { - Subject* subject = new Subject; - subject->setName("empty"); - subjects.append(subject); - } -} - -void DataManager::localSaveTokens(QString response) +void DataManager::fillFullTokensColnod(QString response) { QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); @@ -37,18 +17,68 @@ void DataManager::localSaveTokens(QString response) { auto token = new Token(); token->fromJSON(item.toObject()); - tokens.append(token); + fullTokensColnod.insert(token->idToStringWithoutBraces(), token); } } else { - Token* token = new Token; - token->setName("empty"); - tokens.append(token); + auto token = new Token("empty"); + fullTokensColnod.insert(token->idToStringWithoutBraces(), token); } } -void DataManager::localSaveSubjectsToDelete(QString json) +void DataManager::fillTokensColnod(QString response) +{ + QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); + QJsonArray items = doc.object()["items"].toArray(); + if (items.size() > 0) + { + for (QJsonValueRef item : items) + { + auto token = new Token(); + token->fromJSON(item.toObject()); + tokensColnod.insert(token->idToStringWithoutBraces(), token); + } + } + else + { + auto token = new Token("empty"); + tokensColnod.insert(token->idToStringWithoutBraces(), token); + } +} + +void DataManager::fillSubjectsColnod(QString response) +{ + QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); + QJsonArray items = doc.object()["items"].toArray(); + if (items.size() > 0) + { + for (QJsonValueRef item : items) + { + auto subject = new Subject(); + subject->fromJSON(item.toObject()); + subjectsColnod.insert(subject->idToStringWithoutBraces(), subject); + } + } + else + { + Subject* subject = new Subject("empty"); + subjectsColnod.insert(subject->idToStringWithoutBraces(), subject); + } +} + +void DataManager::fillTokensDB() +{ + QSqlQuery* query = db->getUpdatedTokens(lastSync); + // TODO +} + +void DataManager::fillSubjectsDB() +{ + // Not needed yet +} + +void DataManager::fillSubjectsToDeleteColnod(QString json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); @@ -56,16 +86,17 @@ void DataManager::localSaveSubjectsToDelete(QString json) { for (QJsonValueRef item : items) { - subjectsToDelete.append(item.toString()); + subjectsToDeleteColnod.append(item.toString()); } + } else { - subjectsToDelete.append("empty"); + subjectsToDeleteColnod.append("empty"); } } -void DataManager::localSaveTokensToDelete(QString json) +void DataManager::fillTokensToDeleteColnod(QString json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); @@ -73,111 +104,117 @@ void DataManager::localSaveTokensToDelete(QString json) { for (QJsonValueRef item : items) { - tokensToDelete.append(item.toString()); + tokensToDeleteColnod.append(item.toString()); } } else { - tokensToDelete.append("empty"); + tokensToDeleteColnod.append("empty"); } } +void DataManager::fillSubjectsToDeleteDB() +{ + // Not needed yet +} + +void DataManager::fillTokensToDeleteDB() +{ + // TODO + // get data from db, maybe it's better to get all tokens together then filter deleted +} + void DataManager::pushSubjectsToDB() { - if (subjects.size() == 1 && subjects[0]->getName() == "empty") + if (subjectsColnod.contains("empty")) { qDebug() << "All subjects are up to date"; return; } //QSqlDatabase::database().transaction(); qDebug() << "Subjects in progress..."; - for (auto subject : subjects) + for (auto subject : subjectsColnod) { db->saveSubject(subject, "colnod_subject"); db->saveSubjectAttribute(subject, "colnod_subject_attribute"); } //QSqlDatabase::database().commit(); - qDebug() << subjects.size() << " subjects has been updated"; + qDebug() << subjectsColnod.size() << " subjects has been updated"; } void DataManager::pushTokensToDB() { - if (tokens.size() == 1 && tokens[0]->getName() == "empty") + if (tokensColnod.contains("empty")) { qDebug() << "All tokens are up to date"; return; } //QSqlDatabase::database().transaction(); qDebug() << "Tokens in progress..."; - for (auto token : tokens) + for (auto token : tokensColnod) { db->saveToken(token, "colnod_token"); } //QSqlDatabase::database().commit(); - qDebug() << tokens.size() << " tokens has been updated"; + qDebug() << tokensColnod.size() << " tokens has been updated"; } void DataManager::deleteSubjectsFromDB() { - if (subjectsToDelete.size() == 1 && subjectsToDelete[0] == "empty") + if (subjectsToDeleteColnod[0] == "empty") { qDebug() << "No subjects to be deleted"; return; } qDebug() << "Deleted subjects in progress..."; //QSqlDatabase::database().transaction(); - for (auto subjectId : subjectsToDelete) + for (auto subjectId : subjectsToDeleteColnod) { db->deleteItem(subjectId, "colnod_subject"); } //QSqlDatabase::database().commit(); - qDebug() << subjectsToDelete.size() << "subject has beed deleted"; + qDebug() << subjectsToDeleteColnod.size() << "subject has beed deleted"; } void DataManager::deleteTokensFromDB() { - if (tokensToDelete.size() == 1 && tokensToDelete[0] == "empty") + if (tokensToDeleteColnod[0] == "empty") { qDebug() << "No tokens to be deleted"; return; } // QSqlDatabase::database().transaction(); qDebug() << "Deleted tokens in progress..."; - for (auto tokenId : tokensToDelete) + for (auto tokenId : tokensToDeleteColnod) { db->deleteItem(tokenId, "colnod_token"); } //QSqlDatabase::database().commit(); - qDebug() << tokensToDelete.size() << "tokens has beed deleted"; + qDebug() << tokensToDeleteColnod.size() << "tokens has beed deleted"; } bool DataManager::haveData() { - if ( !subjects.isEmpty() && !tokens.isEmpty() ) + if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() ) return true; return false; } bool DataManager::haveChangedData() { - if ( !subjects.isEmpty() && !tokens.isEmpty() && !subjectsToDelete.isEmpty() && !tokensToDelete.isEmpty() ) + if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() && !subjectsToDeleteColnod.isEmpty() && !tokensToDeleteColnod.isEmpty() ) return true; return false; } bool DataManager::haveProcessData() { - if ( !tokens.isEmpty() && !tokensToDelete.isEmpty()) + if ( !tokensColnod.isEmpty() && !tokensToDeleteColnod.isEmpty()) return true; return false; } -uint64_t DataManager::getLastUpdate() -{ - return db->getLastUpdate(); -} - void DataManager::emptyDatabase() { db->dropTables(); @@ -186,10 +223,14 @@ void DataManager::emptyDatabase() void DataManager::clear() { - subjects.clear(); - subjectsToDelete.clear(); - tokens.clear(); - tokensToDelete.clear(); + subjectsColnod.clear(); + subjectsToDeleteColnod.clear(); + tokensColnod.clear(); + tokensToDeleteColnod.clear(); + subjectsDB.clear(); + subjectsToDeleteDB.clear(); + tokensDB.clear(); + tokensToDeleteDB.clear(); } void DataManager::updateLastSync() @@ -204,10 +245,10 @@ void DataManager::loadTokensToAdd() { Token* token = new Token(query->value(0).toString(), query->value(1).toString()); token->setSubjectId(db->getId(token->getName())); - tokens.append(token); + tokensDB.insert(token->idToStringWithoutBraces(), token); } - if (tokens.isEmpty()) - tokens.append(new Token("empty")); + if (tokensDB.isEmpty()) + tokensDB.insert("empty", nullptr); } void DataManager::loadTokensToDelete() @@ -215,10 +256,10 @@ void DataManager::loadTokensToDelete() QSqlQuery* query = db->getTokensToDelete(); while (query->next()) { - tokensToDelete.append(query->value(0).toString()); + tokensToDeleteDB.append(query->value(0).toString()); } - if (tokensToDelete.isEmpty()) - tokensToDelete.append("empty"); + if (tokensToDeleteDB.isEmpty()) + tokensToDeleteDB.append("empty"); } diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 1f51db0..3d96681 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -17,10 +17,18 @@ class DataManager : public QObject public: DataManager(); - void localSaveSubjects(QString jsonResponse); - void localSaveTokens(QString jsonResponse); - void localSaveSubjectsToDelete(QString jsonResponse); - void localSaveTokensToDelete(QString jsonResponse); + void getAndSetLastSync(); + void fillFullTokensColnod(QString jsonResponse); + + void fillTokensColnod(QString jsonResponse); + void fillSubjectsColnod(QString jsonResponse); + void fillSubjectsToDeleteColnod(QString jsonResponse); + void fillTokensToDeleteColnod(QString jsonResponse); + + void fillTokensDB(); + void fillSubjectsDB(); + void fillSubjectsToDeleteDB(); + void fillTokensToDeleteDB(); void pushSubjectsToDB(); void pushTokensToDB(); @@ -28,7 +36,6 @@ public: void deleteTokensFromDB(); void updateLastSync(); - uint64_t getLastUpdate(); bool haveData(); bool haveChangedData(); @@ -40,16 +47,28 @@ public: void loadTokensToAdd(); void loadTokensToDelete(); - QList>* getTokens() {return &tokens;} - QList* getTokensToDelete() {return &tokensToDelete;} + QHash>* getTokens() {return &tokensColnod;} + QList* getTokensToDelete() {return &tokensToDeleteColnod;} + const uint64_t &getLastSync() {return lastSync;} private: DatabaseManager *db = nullptr; - QList> subjects; - QList> tokens; - QList subjectsToDelete; - QList tokensToDelete; + + uint64_t lastSync; + + QHash> subjectsColnod; + QHash> tokensColnod; + QHash> fullTokensColnod; + QHash> subjectsDB; // in future + QHash> tokensDB; + + + QList subjectsToDeleteColnod; + QList tokensToDeleteColnod; + QList subjectsToDeleteDB; + QList tokensToDeleteDB; + }; #endif // DATAMANAGER_H diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 3847358..0e57543 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -157,7 +157,7 @@ QByteArray RequestManager::makeTimeStampJson(uint64_t time) return doc.toJson(); } -QByteArray RequestManager::makeTokensJson(QList>* tokens) +QByteArray RequestManager::makeTokensJson(QHash > *tokens) { QJsonObject items; QJsonArray jsonTokens; @@ -265,7 +265,7 @@ Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time) return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimeStampJson(time)); } -Response* RequestManager::setTokens(QList>* tokens) +Response* RequestManager::setTokens(QHash > *tokens) { return postRequestReturnLogic("/TokenManager/setTokens", makeTokensJson(tokens)); } diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index b784535..f13fde4 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -49,7 +49,7 @@ public: Response* getAccessGroupMembershipUpdated(uint64_t time); Response* getAccessGroupMembershipDeleted(uint64_t time); - Response* setTokens(QList>* tokens); + Response* setTokens(QHash>* tokens); Response* deleteTokens(QList* ids); Response* login(); //I want it private, but unittest??? @@ -65,7 +65,7 @@ private: QString getLoginHeader(QString username, QString hash); QByteArray makeTimeStampJson(uint64_t time); - QByteArray makeTokensJson(QList>* tokens); + QByteArray makeTokensJson(QHash>* tokens); QByteArray makeIdsJson(QList* ids); Response* getLoginResponse(); diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index c2ae710..1cfb763 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -4,6 +4,11 @@ #include +Subject::Subject(QString namee) +{ + this->name = namee; +} + QString Subject::getEmail() const { return attributes["email"].toString(); } diff --git a/src/colnod/subject.h b/src/colnod/subject.h index 955f623..1377c50 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -13,6 +13,8 @@ class Subject : public Entity { public: using Entity::Entity; + Subject(QString name); + QString getEmail() const; const QJsonObject &getAttributes() const; diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index af27504..c531e0b 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -212,13 +212,13 @@ void UnitTest::setTokens() QJsonObject obj = doc.object(); QJsonArray arr = obj["items"].toArray(); qDebug() << arr; - QList> tokens; + QHash> tokens; for (auto object : arr) { auto token = new Token; token->fromJSON(object.toObject()); qDebug() << token; - tokens.append(token); + tokens.insert(token->idToStringWithoutBraces(), token); } RequestManager* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 7fc87e7..c3fe6eb 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -43,8 +43,9 @@ void ComplexTest::complexTest() // ADD_TOKENS_CHECK_BEGIN - QList> tokens; - tokens.append(getTestToken()); + QHash> tokens; + auto token = getTestToken(); + tokens.insert(token->idToStringWithoutBraces(), token); Response* setTokensResp = reqMan->setTokens(&tokens); QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); QCOMPARE(setTokensRespSpy.count(), 0); @@ -112,11 +113,14 @@ void ComplexTest::fullSync() void ComplexTest::syncLastUpdated() { - api->downloadChangedDataFromColnod(); + api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(10000); - api->syncChangedDataFromColnod(); + api->syncDataFromColnod(); // api->syncChangedDataToColnod(); + spy.wait(10000); + api->syncDataFromColnod(); + } From a60539cc76a385297327cb2f07a662252217b092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 22 Oct 2019 09:41:11 +0200 Subject: [PATCH 02/23] Add todo --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index d8f034d..376572e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ Acces Management System of Colsys: [Product info](http://produkty.colsys.cz/colnod/) +## TODO +- [ ] Debug Mode +- [ ] Logs + - Timestamp + - Destination + - Report + - Number of new records + - Number of updated records + - Number of deleted records + ## Requirements - QPSQL driver must be installed (PostgreSQL) From 78ff45f7fdcc3a7f0df2f2bbc600b815aaafdc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 22 Oct 2019 10:01:30 +0200 Subject: [PATCH 03/23] Readme - TODO update --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 376572e..ca289c0 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,18 @@ Acces Management System of Colsys: [Product info](http://produkty.colsys.cz/coln - [ ] Debug Mode - [ ] Logs - Timestamp + - Id of record - Destination - Report - - Number of new records - - Number of updated records - - Number of deleted records - + - Token `action` to `subject_id` + - Sbject `action` + - `action` - updated, deleted, added +- [ ] App output + - To Colnod + - Number of tokens added/deleted/updated + - To DB + - Number of subjects added/deleted/updated + - Number of tokens added/deleted/updated ## Requirements - QPSQL driver must be installed (PostgreSQL) From 6ad24c6c6e868dc68bed5bf18eb64168b7a1eb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 23 Oct 2019 09:55:18 +0200 Subject: [PATCH 04/23] first version - w/o dry run mode and logs --- src/app/main.cpp | 1 + src/colnod/colnodapi.cpp | 97 +++++++++++++++------- src/colnod/colnodapi.h | 21 ++--- src/colnod/databasemanager.cpp | 142 ++++++++++++++++++++++++--------- src/colnod/databasemanager.h | 14 +++- src/colnod/datamanager.cpp | 116 +++++++++++++++++---------- src/colnod/datamanager.h | 26 ++++-- src/colnod/entity.cpp | 6 +- src/colnod/entity.h | 4 +- src/colnod/requestmanager.cpp | 30 ++----- src/colnod/requestmanager.h | 8 +- src/colnod/token.cpp | 51 ++++++++++-- src/colnod/token.h | 30 +++++-- test/unitTests/UnitTest.cpp | 4 +- test/unitTests/complextest.cpp | 32 +++++--- 15 files changed, 398 insertions(+), 184 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 30d341b..f891c95 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -8,6 +8,7 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); ColnodAPI *api = new ColnodAPI(); + /*api->downloadData(); // this will start downloading data QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ qDebug() << "now I have all data"; diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index be42326..87b15c5 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -1,9 +1,10 @@ #include "colnodapi.h" -ColnodAPI::ColnodAPI() +ColnodAPI::ColnodAPI(bool debug) { reqMan = new RequestManager(); dataMan = new DataManager(); + debugMode = debug; } @@ -45,7 +46,8 @@ void ColnodAPI::loadTokensFromColnod() Response* resp = reqMan->getTokens(); connect(resp, &Response::ready, [=](){ dataMan->fillFullTokensColnod(resp->getJson()); - + areChangedDataReady(); + resp->deleteLater(); }); } @@ -89,7 +91,7 @@ void ColnodAPI::loadDeletedDataFromColnod() void ColnodAPI::loadDataFromDB() { dataMan->fillTokensDB(); - dataMan->fillTokensToDeleteDB(); + } //void ColnodAPI::syncDataFromColnod() @@ -102,10 +104,12 @@ void ColnodAPI::loadDataFromDB() void ColnodAPI::syncDataFromColnod() { + dataMan->filterTokensColnod(); syncUpdatedDataFromColnod(); - syncDeletedDataFromColnod(); + if (dataMan->getLastSync() != 0) + syncDeletedDataFromColnod(); //dataMan->updateLastSync(); - dataMan->clear(); + // dataMan->clear(); } void ColnodAPI::syncUpdatedDataFromColnod() @@ -124,36 +128,71 @@ void ColnodAPI::syncDeletedDataFromColnod() void ColnodAPI::syncDataFromDB() { // TODO - dataMan->loadTokensToAdd(); - dataMan->loadTokensToDelete(); + dataMan->filterTokensDB(); processDataToColnod(); - + connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::clear); + connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::setLastSync); + connect(this, &ColnodAPI::dataProcessed, [=](){ + auto resp = reqMan->getTokensUpdated(dataMan->getActualSync()); + connect(resp, &Response::ready, [=](){ + dataMan->fillTokensColnod(resp->getJson()); + dataMan->setLastUpdate(); + dataMan->clear(); + emit syncFinished(); + resp->deleteLater(); + }); + }); } void ColnodAPI::processDataToColnod() { - QList* tokensToDelete = dataMan->getTokensToDelete(); - if ((*tokensToDelete)[0] != "empty") - { - Response* resp0 = reqMan->deleteTokens(tokensToDelete); - connect(resp0, &Response::ready, [=](){ - isProcessDone(); - resp0->deleteLater(); - }); + auto tokensToUpdate = dataMan->getTokensToUpdateDB(); + + if (tokensToUpdate.contains("empty")){ + qDebug() << "No tokens to be modified."; + return; } - QHash>* tokens = dataMan->getTokens(); - if (!tokens[0].contains("empty")) - { - Response* resp1 = reqMan->setTokens(tokens); - connect(resp1, &Response::ready, [=](){ - isProcessDone(); - resp1->deleteLater(); - }); - } - dataMan->clear(); - connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod); + auto tokensToDelete = dataMan->getTokensToDeleteDB(); + auto resp0 = reqMan->setTokens(tokensToUpdate); + auto resp1 = reqMan->deleteTokens(tokensToDelete); + connect(resp0, &Response::ready, [=](){ + updateFinished = true; + areDataProcessed(); + resp0->deleteLater(); + }); + connect(resp1, &Response::ready, [=](){ + deleteFinished = true; + areDataProcessed(); + resp1->deleteLater(); + }); } +// old version +//void ColnodAPI::processDataToColnod() +//{ +// QList* tokensToDelete = dataMan->getTokensToDelete(); +// if ((*tokensToDelete)[0] != "empty") +// { +// Response* resp0 = reqMan->deleteTokens(tokensToDelete); +// connect(resp0, &Response::ready, [=](){ +// isProcessDone(); +// resp0->deleteLater(); +// }); +// } +// QHash>* tokens = dataMan->getTokens(); +// if (!tokens[0].contains("empty")) +// { +// Response* resp1 = reqMan->setTokens(tokens); +// connect(resp1, &Response::ready, [=](){ +// isProcessDone(); +// resp1->deleteLater(); +// }); +// } +// dataMan->clear(); +// connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod); +//} + +// For full sync void ColnodAPI::prepareDatabase() { dataMan->emptyDatabase(); @@ -173,9 +212,9 @@ void ColnodAPI::areChangedDataReady() } -void ColnodAPI::isProcessDone() +void ColnodAPI::areDataProcessed() { - if (dataMan->haveProcessData()) + if (deleteFinished && updateFinished) { emit dataProcessed(); } diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index fea1cb1..034e8ce 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -13,19 +13,11 @@ class ColnodAPI : public QObject public: - ColnodAPI(); - /// - //void downloadData(); - //void syncDataFromColnod(); - //void syncDataToColnod(); - /// + ColnodAPI(bool debugMode = false); void syncDataFromColnod(); void syncDataFromDB(); - - - void prepareDatabase(); public slots: @@ -36,6 +28,7 @@ public slots: signals: void dataDownloaded(); void dataProcessed(); + void syncFinished(); private slots: @@ -52,17 +45,17 @@ private: void syncDeletedDataFromColnod(); void areDataReady(); void areChangedDataReady(); - void isProcessDone(); + void areDataProcessed(); void processDataToColnod(); RequestManager* reqMan = nullptr; - // Data* data = nullptr; DataManager* dataMan = nullptr; - bool dataReady[2] = {false}; - int index = 0; - const int numOfMembers = 2; + bool debugMode = false; + bool updateFinished = false; + bool deleteFinished = false; + }; #endif // COLNODAPI_H diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 60e2aca..4874f79 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -25,20 +25,24 @@ void DatabaseManager::saveSubject(Subject* subject, QString table) QString id = subject->idToStringWithoutBraces(); if (checkIfExists(id, table)) { - query.prepare(QString("UPDATE %1 SET name = :name, last_update = :last_update " + query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = last_update:, name = :name, pin = :pin" "WHERE id = :id)").arg(table)); query.bindValue(":id", id); + query.bindValue(":description", subject->getDescription()); query.bindValue(":name", subject->getName()); query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":pin", subject->getPin()); query.exec(); } else { - query.prepare(QString("INSERT INTO %1 (id, name, last_update) " - "VALUES (:id, :name, :last_update)").arg(table)); + query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin) " + "VALUES (:id, :description, :last_update, :name, :pin)").arg(table)); query.bindValue(":id", id); - query.bindValue(":name", subject->getName()); + query.bindValue(":description", subject->getDescription()); query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":name", subject->getName()); + query.bindValue(":pin", subject->getPin()); query.exec(); } } @@ -48,22 +52,41 @@ void DatabaseManager::saveToken(Token* token, QString table) QString id = token->idToStringWithoutBraces(); if (checkIfExists(id, table)) { - query.prepare(QString("UPDATE %1 SET last_update = :last_update, token_data = :data, subject_id = :subject_id) " + query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified deleted = :deleted) " "WHERE id = :id").arg(table)); query.bindValue(":id", id); - query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":data", token->getTokenData()); + query.bindValue(":auth_errors", token->getAuthErrors()); + query.bindValue(":description", token->getDescription()); + query.bindValue(":enabled", token->getFlags().contains("Enabled")); + query.bindValue(":name", token->getName()); + query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); + query.bindValue(":time_to_live", token->getTimeToLive()); + query.bindValue(":token_bits", token->getTokenBits()); + query.bindValue(":token_data", token->getTokenData()); + query.bindValue(":token_type", token->getTokenType()); query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); + query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":deleted", token->getDeleted()); query.exec(); } else { - query.prepare(QString("INSERT INTO %1 (id, last_update, token_data, subject_id) " - "VALUES (:id, :last_update, :data, :subject_id)").arg(table)); + query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) " + "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table)); query.bindValue(":id", id); + query.bindValue(":auth_errors", token->getAuthErrors()); + query.bindValue(":description", token->getDescription()); + query.bindValue(":enabled", token->getFlags().contains("Enabled")); query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":data", token->getTokenData()); + query.bindValue(":name", token->getName()); + query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); + query.bindValue(":time_to_live", token->getTimeToLive()); + query.bindValue(":token_bits", token->getTokenBits()); + query.bindValue(":token_data", token->getTokenData()); + query.bindValue(":token_type", token->getTokenType()); query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); + query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":deleted", token->getDeleted()); query.exec(); } } @@ -96,10 +119,13 @@ void DatabaseManager::saveSubjectAttribute(Subject *subject, QString table) } } -void DatabaseManager::deleteItem(QString id, QString table) +void DatabaseManager::setDeleted(QString id, QString table) { - query.prepare(QString("DELETE FROM %1 WHERE id = :id").arg(table)); + quint64 now = getNow(); + QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz"); + query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table)); query.bindValue(":id", id); + query.bindValue(":now", nowString); query.exec(); } @@ -125,7 +151,6 @@ int DatabaseManager::createTestRecord(QString msg) return id; } - bool DatabaseManager::checkIfExists(QString id, QString table) { query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table)); @@ -143,36 +168,51 @@ void DatabaseManager::dropTables() void DatabaseManager::createTables() { query.exec("CREATE TABLE colnod_subject (" - "id CHAR(36) primary key," - "name VARCHAR(255)," - "last_update timestamp)"); + "id character(36) primary key NOT NULL," + //"access_pin smallint," + "description character varying(255)," + "last_update timestamp NOT NULL," + "name character varying(255)," + "pin character varying(255))"); query.exec("CREATE TABLE colnod_token (" - "id CHAR(36) primary key," + "id CHAR(36) primary key NOT NULL," + "auth_errors INTEGER NOT NULL," + "description VARCHAR(255)," + "enabled BOOLEAN NOT NULL," + "last_update timestamp NOT NULL," + "name VARCHAR(255)," + "no_validity BOOLEAN NOT NULL," + "time_to_live INTEGER NOT NULL," + "token_bits INTEGER," "token_data VARCHAR(255)," + "token_type VARCHAR(255)," "subject_id CHAR(36)," - "last_update timestamp)"); + "last_modified timestamp," + "deleted BOOLEAN)"); + query.exec("CREATE TABLE colnod_subject_attribute (" "id VARCHAR(255) primary key," "attribute_key VARCHAR(255)," "attribute_value VARCHAR(255)," "subject_id CHAR(36))"); - query.exec("CREATE TABLE users (" - "id VARCHAR(255) primary key," - "email VARCHAR(255)," - "token_data VARCHAR(255)," - "last_update timestamp)"); } -uint64_t DatabaseManager::getAndSetLastSync() +uint64_t DatabaseManager::getLastSync() { - query.exec("SELECT EXTRACT(EPOCH FROM (SELECT last_sync FROM config))*1000"); + query.exec("SELECT last_sync FROM config"); query.next(); - uint64_t temp = query.value(0).toULongLong(); - query.exec("UPDATE config SET last_sync = NOW()"); + quint64 temp = query.value(0).toULongLong(); return temp; } +void DatabaseManager::updateLastSync(quint64 lastSync) +{ + query.prepare("UPDATE config SET last_sync = :last_sync"); + query.bindValue(":last_sync", lastSync); + query.exec(); +} + void DatabaseManager::makeTestingLast_sync() { query.prepare("INSERT INTO last_changes (last_sync) " @@ -181,15 +221,6 @@ void DatabaseManager::makeTestingLast_sync() query.exec(); } -void DatabaseManager::updateLastSync() -{ - query.prepare("INSERT INTO changes (last_sync) " - "VALUES (:time)"); - query.bindValue(":time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.exec(); -} - - QSqlQuery* DatabaseManager::getTokensToAdd() { QSqlQuery* qry = new QSqlQuery; @@ -212,3 +243,42 @@ QUuid DatabaseManager::getId(QString name) query.next(); return query.value(0).toUuid(); } + +QSqlQuery* DatabaseManager::getUpdatedTokens() +{ + QSqlQuery* qry = new QSqlQuery; + qry->exec("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000"); + return qry; +} + +QSqlQuery* DatabaseManager::getToken(QString id) +{ + QSqlQuery* qry = new QSqlQuery; + qry->prepare("SELECT SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + "FROM colnod_token WHERE id = :id"); + qry->bindValue(":id", id); + qry->exec(); + if (qry->next()){ + return qry; + } + else { + return nullptr; + } +} + +quint64 DatabaseManager::getNow() +{ + query.exec("SELECT EXTRACT(EPOCH FROM NOW())*1000"); + query.next(); + return query.value(0).toULongLong(); +} + +void DatabaseManager::setLastUpdate(QString id, quint64 lastUpdate) +{ + query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id"); + query.bindValue(":id", id); + query.bindValue(":lastUpdate", lastUpdate); + query.exec(); +} + diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 9b597f0..cadc248 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -23,7 +23,8 @@ public: void saveSubject(Subject* subject, QString table); void saveToken(Token* token, QString table); void saveSubjectAttribute(Subject* subject, QString table); - void deleteItem(QString id, QString table); + void setDeleted(QString id, QString table); + QString getTestMessage(int id); int createTestRecord(QString msg); @@ -35,12 +36,19 @@ public: void createTables(); bool getOpened() {return opened;} - uint64_t getAndSetLastSync(); - void updateLastSync(); + quint64 getLastSync(); + void updateLastSync(quint64 lastSync); + quint64 getNow(); + QSqlQuery* getUpdatedTokens(); + QSqlQuery* getToken(QString id); + + // Old version QSqlQuery* getTokensToAdd(); QSqlQuery* getTokensToDelete(); + void setLastUpdate(QString id, quint64 lastUpdate); + QUuid getId(QString name); diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 095efaa..7606ddb 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -3,7 +3,9 @@ DataManager::DataManager() { db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12"); - lastSync = db->getAndSetLastSync(); + nextLastSync = db->getNow(); + lastSync = db->getLastSync(); + qDebug() << lastSync; //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); } @@ -37,13 +39,14 @@ void DataManager::fillTokensColnod(QString response) { auto token = new Token(); token->fromJSON(item.toObject()); - tokensColnod.insert(token->idToStringWithoutBraces(), token); + token->setDeleted(false); + tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token); } } else { auto token = new Token("empty"); - tokensColnod.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token); } } @@ -67,10 +70,18 @@ void DataManager::fillSubjectsColnod(QString response) } } +// fills tokensDB and tokensToDeleteDB void DataManager::fillTokensDB() { - QSqlQuery* query = db->getUpdatedTokens(lastSync); - // TODO + QSqlQuery* query = db->getUpdatedTokens(); + while (query->next()) + { + auto token = new Token; + token->fromSQLRecord(query); + tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token); + } + qDebug() << "Number of tokens to update from DB: "<< tokensToUpdateDB.size(); + qDebug() << "Number of tokens to delete from DB: "<< tokensToDeleteDB.size(); } void DataManager::fillSubjectsDB() @@ -84,14 +95,11 @@ void DataManager::fillSubjectsToDeleteColnod(QString json) QJsonArray items = doc.object()["items"].toArray(); if (items.size() > 0) { - for (QJsonValueRef item : items) - { + for (QJsonValueRef item : items) { subjectsToDeleteColnod.append(item.toString()); } - } - else - { + else { subjectsToDeleteColnod.append("empty"); } } @@ -102,13 +110,11 @@ void DataManager::fillTokensToDeleteColnod(QString json) QJsonArray items = doc.object()["items"].toArray(); if (items.size() > 0) { - for (QJsonValueRef item : items) - { + for (QJsonValueRef item : items) { tokensToDeleteColnod.append(item.toString()); } } - else - { + else { tokensToDeleteColnod.append("empty"); } } @@ -118,16 +124,9 @@ void DataManager::fillSubjectsToDeleteDB() // Not needed yet } -void DataManager::fillTokensToDeleteDB() -{ - // TODO - // get data from db, maybe it's better to get all tokens together then filter deleted -} - void DataManager::pushSubjectsToDB() { - if (subjectsColnod.contains("empty")) - { + if (subjectsColnod.contains("empty")) { qDebug() << "All subjects are up to date"; return; } @@ -145,19 +144,19 @@ void DataManager::pushSubjectsToDB() void DataManager::pushTokensToDB() { - if (tokensColnod.contains("empty")) + if (tokensToUpdateColnod.contains("empty")) { qDebug() << "All tokens are up to date"; return; } //QSqlDatabase::database().transaction(); qDebug() << "Tokens in progress..."; - for (auto token : tokensColnod) + for (auto token : tokensToUpdateColnod) { db->saveToken(token, "colnod_token"); } //QSqlDatabase::database().commit(); - qDebug() << tokensColnod.size() << " tokens has been updated"; + qDebug() << tokensToUpdateColnod.size() << " tokens has been updated"; } void DataManager::deleteSubjectsFromDB() @@ -168,12 +167,10 @@ void DataManager::deleteSubjectsFromDB() return; } qDebug() << "Deleted subjects in progress..."; - //QSqlDatabase::database().transaction(); for (auto subjectId : subjectsToDeleteColnod) { - db->deleteItem(subjectId, "colnod_subject"); + db->setDeleted(subjectId, "colnod_subject"); } - //QSqlDatabase::database().commit(); qDebug() << subjectsToDeleteColnod.size() << "subject has beed deleted"; } @@ -184,33 +181,35 @@ void DataManager::deleteTokensFromDB() qDebug() << "No tokens to be deleted"; return; } - // QSqlDatabase::database().transaction(); qDebug() << "Deleted tokens in progress..."; for (auto tokenId : tokensToDeleteColnod) { - db->deleteItem(tokenId, "colnod_token"); + db->setDeleted(tokenId, "colnod_token"); } - //QSqlDatabase::database().commit(); qDebug() << tokensToDeleteColnod.size() << "tokens has beed deleted"; } bool DataManager::haveData() { - if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() ) + if ( !subjectsColnod.isEmpty() && !tokensToUpdateColnod.isEmpty() ) return true; return false; } bool DataManager::haveChangedData() { - if ( !subjectsColnod.isEmpty() && !tokensColnod.isEmpty() && !subjectsToDeleteColnod.isEmpty() && !tokensToDeleteColnod.isEmpty() ) + if ( !subjectsColnod.isEmpty() && + !tokensToUpdateColnod.isEmpty() && + !subjectsToDeleteColnod.isEmpty() && + !tokensToDeleteColnod.isEmpty() && + !fullTokensColnod.isEmpty() ) return true; return false; } bool DataManager::haveProcessData() { - if ( !tokensColnod.isEmpty() && !tokensToDeleteColnod.isEmpty()) + if ( !tokensToUpdateColnod.isEmpty() && !tokensToDeleteColnod.isEmpty()) return true; return false; } @@ -225,19 +224,48 @@ void DataManager::clear() { subjectsColnod.clear(); subjectsToDeleteColnod.clear(); - tokensColnod.clear(); + tokensToUpdateColnod.clear(); tokensToDeleteColnod.clear(); subjectsDB.clear(); subjectsToDeleteDB.clear(); - tokensDB.clear(); + tokensToUpdateDB.clear(); tokensToDeleteDB.clear(); + fullTokensColnod.clear(); } void DataManager::updateLastSync() { - db->updateLastSync(); + db->updateLastSync(nextLastSync); } +void DataManager::filterTokensDB() +{ + for (auto token : tokensToUpdateDB) + { + QString id = token->idToStringWithoutBraces(); + Q_ASSERT(token = fullTokensColnod.value(id)); + if (fullTokensColnod.contains(id) && token < fullTokensColnod.value(id)) + tokensToUpdateDB.remove(id); + } +} + +void DataManager::filterTokensColnod() +{ + for (auto token : tokensToUpdateColnod) + { + QString id = token->idToStringWithoutBraces(); + auto record = db->getToken(id); + if (!record) + continue; + auto tokenDB = new Token; + tokenDB->fromSQLRecord(record); + Q_ASSERT(tokenDB != token); + if (tokenDB > token) + tokensToUpdateColnod.remove(id); + } +} + +// old version void DataManager::loadTokensToAdd() { QSqlQuery* query = db->getTokensToAdd(); @@ -245,10 +273,10 @@ void DataManager::loadTokensToAdd() { Token* token = new Token(query->value(0).toString(), query->value(1).toString()); token->setSubjectId(db->getId(token->getName())); - tokensDB.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token); } - if (tokensDB.isEmpty()) - tokensDB.insert("empty", nullptr); + if (tokensToUpdateDB.isEmpty()) + tokensToUpdateDB.insert("empty", nullptr); } void DataManager::loadTokensToDelete() @@ -263,4 +291,12 @@ void DataManager::loadTokensToDelete() } +void DataManager::setLastUpdate() +{ + for (auto token : tokensToUpdateColnod){ + db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate()); + } +} + + diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 3d96681..7a14373 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -28,7 +28,9 @@ public: void fillTokensDB(); void fillSubjectsDB(); void fillSubjectsToDeleteDB(); - void fillTokensToDeleteDB(); + + void filterTokensDB(); + void filterTokensColnod(); void pushSubjectsToDB(); void pushTokensToDB(); @@ -42,26 +44,34 @@ public: bool haveProcessData(); void emptyDatabase(); - void clear(); void loadTokensToAdd(); void loadTokensToDelete(); - QHash>* getTokens() {return &tokensColnod;} - QList* getTokensToDelete() {return &tokensToDeleteColnod;} + QHash> getTokensToUpdateColnod() {return tokensToUpdateColnod;} + QList getTokensToDeleteColnod() {return tokensToDeleteColnod;} + QHash> getTokensToUpdateDB() {return tokensToUpdateDB;} + QList getTokensToDeleteDB() {return tokensToDeleteDB;} - const uint64_t &getLastSync() {return lastSync;} + const quint64 &getLastSync() {return lastSync;} + const quint64 &getActualSync() {return nextLastSync;} + +public slots: + void clear(); + void setLastSync() {db->updateLastSync(nextLastSync);} + void setLastUpdate(); private: DatabaseManager *db = nullptr; - uint64_t lastSync; + quint64 lastSync; + quint64 nextLastSync; QHash> subjectsColnod; - QHash> tokensColnod; + QHash> tokensToUpdateColnod; QHash> fullTokensColnod; QHash> subjectsDB; // in future - QHash> tokensDB; + QHash> tokensToUpdateDB; QList subjectsToDeleteColnod; diff --git a/src/colnod/entity.cpp b/src/colnod/entity.cpp index da6f98f..932e3ca 100644 --- a/src/colnod/entity.cpp +++ b/src/colnod/entity.cpp @@ -25,11 +25,11 @@ void Entity::setDescription(const QString &description) { Entity::description = description; } -uint64_t Entity::getLastUpdate() const { +quint64 Entity::getLastUpdate() const { return lastUpdate; } -void Entity::setLastUpdate(uint64_t lastUpdate) { +void Entity::setLastUpdate(quint64 lastUpdate) { this->lastUpdate = lastUpdate; } @@ -48,7 +48,7 @@ void Entity::fromJSON(const QJsonObject &json) { QJsonObject Entity::toJSON() const { QJsonObject json; - json.value("id") = id.toString(); + json.value("id") = id.toString().mid(1,36); json.value("name") = name; json.value("description") = description; json.value("lastUpdate") = lastUpdate; diff --git a/src/colnod/entity.h b/src/colnod/entity.h index d1b2aa6..de44ca0 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -20,8 +20,8 @@ public: const QString &getDescription() const; void setDescription(const QString &description); - uint64_t getLastUpdate() const; - void setLastUpdate(uint64_t lastUpdate); + quint64 getLastUpdate() const; + void setLastUpdate(quint64 lastUpdate); QString idToStringWithoutBraces(); diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 0e57543..45733bf 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -18,6 +18,7 @@ RequestManager::RequestManager() Response* RequestManager::login() { + Q_ASSERT(!loginResponse); loginResponse = new Response; QNetworkRequest request; QString hash = encryptedPassword(this->password); @@ -157,28 +158,13 @@ QByteArray RequestManager::makeTimeStampJson(uint64_t time) return doc.toJson(); } -QByteArray RequestManager::makeTokensJson(QHash > *tokens) +QByteArray RequestManager::makeTokensJson(const QHash > &tokens) { QJsonObject items; QJsonArray jsonTokens; - for (auto token : *tokens) + for (auto token : tokens) { - QJsonObject jsonToken; - jsonToken.insert("id",token->idToStringWithoutBraces()); - jsonToken.insert("name",token->getName()); - jsonToken.insert("description", token->getDescription()); - jsonToken.insert("tokenType", token->getTokenType()); - jsonToken.insert("tokenBits", token->getTokenBits()); - jsonToken.insert("tokenData", token->getTokenData()); - jsonToken.insert("timeToLive", token->getTimeToLive()); - jsonToken.insert("authErrors", token->getAuthErrors()); - QJsonArray flags; - auto flagStructure = token->getFlags(); - for (auto flag : flagStructure) - flags.push_back(flag); - jsonToken.insert("flags", flags); - jsonToken.insert("subjectId", token->subjectIdToStringWithoutBraces()); - jsonTokens.push_back(jsonToken); + jsonTokens.push_back(token->toJSON()); } items.insert("items", jsonTokens); QJsonDocument doc; @@ -186,10 +172,10 @@ QByteArray RequestManager::makeTokensJson(QHash > *toke return doc.toJson(); } -QByteArray RequestManager::makeIdsJson(QList* ids) +QByteArray RequestManager::makeIdsJson(const QList &ids) { QJsonArray jsonIds; - for (auto id : *ids) + for (auto id : ids) { jsonIds.push_back(id); } @@ -265,12 +251,12 @@ Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time) return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimeStampJson(time)); } -Response* RequestManager::setTokens(QHash > *tokens) +Response* RequestManager::setTokens(const QHash > &tokens) { return postRequestReturnLogic("/TokenManager/setTokens", makeTokensJson(tokens)); } -Response* RequestManager::deleteTokens(QList* ids) +Response* RequestManager::deleteTokens(const QList &ids) { return postRequestReturnLogic("/TokenManager/deleteTokens", makeIdsJson(ids)); } diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index f13fde4..e169b58 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -49,8 +49,8 @@ public: Response* getAccessGroupMembershipUpdated(uint64_t time); Response* getAccessGroupMembershipDeleted(uint64_t time); - Response* setTokens(QHash>* tokens); - Response* deleteTokens(QList* ids); + Response* setTokens(const QHash> &tokens); + Response* deleteTokens(const QList &ids); Response* login(); //I want it private, but unittest??? @@ -65,8 +65,8 @@ private: QString getLoginHeader(QString username, QString hash); QByteArray makeTimeStampJson(uint64_t time); - QByteArray makeTokensJson(QHash>* tokens); - QByteArray makeIdsJson(QList* ids); + QByteArray makeTokensJson(const QHash> &tokens); + QByteArray makeIdsJson(const QList &ids); Response* getLoginResponse(); private slots: diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 941f1fc..2b48e1e 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -21,6 +21,7 @@ Token::Token(QString namee) this->name = namee; } + void Token::fromJSON(const QJsonObject &json) { Entity::fromJSON(json); @@ -49,11 +50,33 @@ QJsonObject Token::toJSON() const { json.value("timeToLive") = timeToLive; json.value("authErrors") = authErrors; json.value("flags") = QJsonArray::fromStringList(flags.toList()); - json.value("subjectId") = subjectId.toString(); + json.value("subjectId") = subjectId.toString().mid(1,36); return json; } +void Token::fromSQLRecord(QSqlQuery *query) +{ + id = query->value(0).toUuid(); + authErrors = query->value(1).toInt(); + description = query->value(2).toString(); + QSet flags; + if (query->value(6).toBool()) + flags.insert("NoValidity"); + if (query->value(3).toBool()) + flags.insert("Enabled"); + this->flags = flags; + lastUpdate = query->value(4).toUInt(); + name = query->value(5).toString(); + timeToLive = query->value(7).toInt(); + tokenBits = query->value(8).toInt(); + tokenData = query->value(9).toString(); + tokenType = query->value(10).toString(); + subjectId = query->value(11).toUuid(); + lastModified = query->value(12).toUInt(); + deleted = query->value(13).toBool(); +} + const QString &Token::getTokenType() const { return tokenType; } @@ -78,19 +101,19 @@ void Token::setTokenData(const QString &tokenData) { Token::tokenData = tokenData; } -qint64 Token::getValidFrom() const { +quint64 Token::getValidFrom() const { return validFrom; } -void Token::setValidFrom(qint64 validFrom) { +void Token::setValidFrom(quint64 validFrom) { Token::validFrom = validFrom; } -qint64 Token::getValidTo() const { +quint64 Token::getValidTo() const { return validTo; } -void Token::setValidTo(qint64 validTo) { +void Token::setValidTo(quint64 validTo) { Token::validTo = validTo; } @@ -129,3 +152,21 @@ void Token::setSubjectId(const QUuid &subjectId) { QString Token::subjectIdToStringWithoutBraces(){ return subjectId.toString().mid(1,36); } + +quint64 Token::getLastModified() const { + return lastModified; +} + +void Token::setLastModified(const quint64 &lastModified) { + Token::lastModified = lastModified; +} + +bool Token::getDeleted() const +{ + return deleted; +} + +void Token::setDeleted(const bool &deleted) +{ + this->deleted = deleted; +} diff --git a/src/colnod/token.h b/src/colnod/token.h index 1ffc80f..c06dcdc 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -4,6 +4,8 @@ #include "entity.h" #include +#include +#include class Token : public Entity { @@ -13,16 +15,24 @@ public: Token() = default; Token(QString name, QString tokenData, QString decription = "mobile"); Token(QString name); + + friend bool operator<(const Token &rToken, const Token &lToken){ + return rToken.getLastModified() < lToken.getLastUpdate(); + } + friend bool operator>(const Token &rToken, const Token &lToken){ + return rToken.getLastModified() > lToken.getLastUpdate(); + } + const QString &getTokenType() const; void setTokenType(const QString &tokenType); int getTokenBits() const; void setTokenBits(int tokenBits); const QString &getTokenData() const; void setTokenData(const QString &tokenData); - qint64 getValidFrom() const; - void setValidFrom(qint64 validFrom); - qint64 getValidTo() const; - void setValidTo(qint64 validTo); + quint64 getValidFrom() const; + void setValidFrom(quint64 validFrom); + quint64 getValidTo() const; + void setValidTo(quint64 validTo); int getTimeToLive() const; void setTimeToLive(int timeToLive); int getAuthErrors() const; @@ -31,22 +41,28 @@ public: void setFlags(const QSet &flags); const QUuid &getSubjectId() const; void setSubjectId(const QUuid &subjectId); + quint64 getLastModified() const; + void setLastModified(const quint64 &lastModified); + bool getDeleted() const; + void setDeleted(const bool &deleted); QString subjectIdToStringWithoutBraces(); - + void fromSQLRecord(QSqlQuery* query); void fromJSON(const QJsonObject &json) override; QJsonObject toJSON() const override; protected: QString tokenType; int tokenBits; QString tokenData; - qint64 validFrom; - qint64 validTo; + quint64 validFrom; + quint64 validTo; int timeToLive; int authErrors; QSet flags; QUuid subjectId; + quint64 lastModified; + bool deleted; }; diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index c531e0b..d907b5e 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -222,7 +222,7 @@ void UnitTest::setTokens() } RequestManager* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->setTokens(&tokens); + Response* response = testAccess->setTokens(tokens); QCOMPARE(spy.count(), 0); spy.wait(15000); QVERIFY(spy.isValid()); @@ -238,7 +238,7 @@ void UnitTest::deleteTokens() QList ids; ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); - Response* response = testAccess->deleteTokens(&ids); + Response* response = testAccess->deleteTokens(ids); QCOMPARE(spy.count(), 0); spy.wait(15000); QVERIFY(spy.isValid()); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index c3fe6eb..cbe31d5 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -2,25 +2,38 @@ void ComplexTest::initTestCase() { - reqMan = new RequestManager; + auto reqMan1 = new RequestManager; + QList ids; + ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); + ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); + Response* deleteTokensResp = reqMan1->deleteTokens(ids); + QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); + QCOMPARE(deleteTokensRespSpy.count(), 0); + deleteTokensRespSpy.wait(10000); + QTest::qWait(2500); start = QDateTime::currentMSecsSinceEpoch()-2000; api = new ColnodAPI; qDebug() << start; } + void ComplexTest::cleanupTestCase() { QList ids; ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - Response* deleteTokensResp = reqMan->deleteTokens(&ids); + ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); + auto reqMan = new RequestManager; + Response* deleteTokensResp = reqMan->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); deleteTokensRespSpy.wait(10000); + QCOMPARE(deleteTokensRespSpy.count(), 1); } void ComplexTest::complexTest() { // LOGIN_BEGIN + reqMan = new RequestManager; QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); Response* loginResp = reqMan->login(); QSignalSpy loginRespSpy(loginResp, &Response::ready); @@ -46,7 +59,7 @@ void ComplexTest::complexTest() QHash> tokens; auto token = getTestToken(); tokens.insert(token->idToStringWithoutBraces(), token); - Response* setTokensResp = reqMan->setTokens(&tokens); + Response* setTokensResp = reqMan->setTokens(tokens); QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); QCOMPARE(setTokensRespSpy.count(), 0); setTokensRespSpy.wait(10000); @@ -70,7 +83,7 @@ void ComplexTest::complexTest() // DELETE_TOKENS_CHECK_BEGIN QList ids; ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - Response* deleteTokensResp = reqMan->deleteTokens(&ids); + Response* deleteTokensResp = reqMan->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); deleteTokensRespSpy.wait(10000); @@ -104,7 +117,7 @@ void ComplexTest::complexTest() void ComplexTest::fullSync() { api->prepareDatabase(); - api->downloadData(); + api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(10000); api->syncDataFromColnod(); @@ -116,11 +129,12 @@ void ComplexTest::syncLastUpdated() api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(10000); + api->loadDataFromDB(); api->syncDataFromColnod(); - // api->syncChangedDataToColnod(); - spy.wait(10000); - api->syncDataFromColnod(); - + api->syncDataFromDB(); + QSignalSpy processSpy(api, &ColnodAPI::dataProcessed); + processSpy.wait(10000); + qDebug() << "All right, at least should be."; } From 4d30dcc9f4ee8b448f4223b57fa8ae32f868651c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 23 Oct 2019 15:05:27 +0200 Subject: [PATCH 05/23] Add comments to code, also make changes according to Clang-Tidy and Clazy analyze --- src/app/main.cpp | 4 +- src/colnod/colnodapi.cpp | 150 +++++++++------------------ src/colnod/colnodapi.h | 20 ++-- src/colnod/databasemanager.cpp | 101 ++++++------------ src/colnod/databasemanager.h | 39 ++----- src/colnod/datamanager.cpp | 183 ++++++++++++++------------------- src/colnod/datamanager.h | 49 ++++----- src/colnod/entity.h | 4 +- src/colnod/requestmanager.cpp | 54 ++++------ src/colnod/requestmanager.h | 12 +-- src/colnod/subject.cpp | 10 +- src/colnod/subject.h | 6 +- src/colnod/token.cpp | 23 +++-- src/colnod/token.h | 17 +-- test/unitTests/UnitTest.cpp | 107 ++++++++++--------- test/unitTests/complextest.cpp | 36 ++++--- test/unitTests/complextest.h | 6 +- test/unitTests/unittest.h | 7 +- 18 files changed, 337 insertions(+), 491 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index f891c95..41eeeab 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -6,7 +6,7 @@ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); - ColnodAPI *api = new ColnodAPI(); + auto *api = new ColnodAPI(); /*api->downloadData(); // this will start downloading data @@ -31,5 +31,5 @@ int main(int argc, char *argv[]) api->loadDataFromDB(); - return a.exec(); + return QCoreApplication::exec(); } diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 87b15c5..739f925 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -7,33 +7,6 @@ ColnodAPI::ColnodAPI(bool debug) debugMode = debug; } - -// PUBLIC FUNCTIONS -//void ColnodAPI::downloadData() -//{ -// Response* resp0 = reqMan->getSubjects(); -// connect(resp0, &Response::ready, [=](){ -// dataMan->localSaveSubjects(resp0->getJson()); -// areDataReady(); -// resp0->deleteLater(); -// }); - -// Response* resp1 = reqMan->getTokens(); -// connect(resp1, &Response::ready, [=](){ -// dataMan->localSaveTokens(resp1->getJson()); -// areDataReady(); -// resp1->deleteLater(); -// }); - -// /* -// QNetworkReply* reply2 = reqMan->getTokens(); -// connect(reply2, &QNetworkReply::finished, [=](){ -// data->saveTokens(reply2->readAll()); -// }); -// */ -//} - - void ColnodAPI::loadDataFromColnod() { loadTokensFromColnod(); @@ -41,6 +14,7 @@ void ColnodAPI::loadDataFromColnod() loadDeletedDataFromColnod(); } +// download all tokens form colnod for comparing with tokens to update from DB void ColnodAPI::loadTokensFromColnod() { Response* resp = reqMan->getTokens(); @@ -51,24 +25,26 @@ void ColnodAPI::loadTokensFromColnod() }); } +// fill tokens/subjects to update in data manager void ColnodAPI::loadUpdatedDataFromColnod() { uint64_t lastUpdate = dataMan->getLastSync(); Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate); connect(resp0, &Response::ready, [=](){ - dataMan->fillSubjectsColnod(resp0->getJson()); + dataMan->fillSubjectsToUpdateColnod(resp0->getJson()); areChangedDataReady(); resp0->deleteLater(); }); Response* resp1 = reqMan->getTokensUpdated(lastUpdate); connect(resp1, &Response::ready, [=](){ - dataMan->fillTokensColnod(resp1->getJson()); + dataMan->fillTokensToUpdateColnod(resp1->getJson()); areChangedDataReady(); resp1->deleteLater(); }); } +// fill tokens/subjects to delete in data manager void ColnodAPI::loadDeletedDataFromColnod() { uint64_t lastUpdate = dataMan->getLastSync(); @@ -88,109 +64,82 @@ void ColnodAPI::loadDeletedDataFromColnod() } +// fill structures in data manager (tokens to updata/to delte) void ColnodAPI::loadDataFromDB() { - dataMan->fillTokensDB(); - + dataMan->fillTokensToUpdateDB(); } -//void ColnodAPI::syncDataFromColnod() -//{ -// dataMan->pushTokensToDB(); -// dataMan->pushSubjectsToDB(); -// dataMan->updateLastSync(); -// dataMan->clear(); -//} - void ColnodAPI::syncDataFromColnod() { dataMan->filterTokensColnod(); - syncUpdatedDataFromColnod(); + syncUpdatedDataFromColnodToDB(); if (dataMan->getLastSync() != 0) - syncDeletedDataFromColnod(); - //dataMan->updateLastSync(); - // dataMan->clear(); + syncDeletedDataFromColnodToDB(); } -void ColnodAPI::syncUpdatedDataFromColnod() +// push data from colnod to DB +void ColnodAPI::syncUpdatedDataFromColnodToDB() { dataMan->pushSubjectsToDB(); dataMan->pushTokensToDB(); } - -void ColnodAPI::syncDeletedDataFromColnod() +// set deleted tokens from Colnod, delete subject +void ColnodAPI::syncDeletedDataFromColnodToDB() { dataMan->deleteSubjectsFromDB(); - dataMan->deleteTokensFromDB(); + dataMan->setDeletedToTokensFromDB(); } -void ColnodAPI::syncDataFromDB() +// push changes form DB to Colnod +void ColnodAPI::syncDataFromDBToColnod() { - // TODO dataMan->filterTokensDB(); - processDataToColnod(); - connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::clear); - connect(this, &ColnodAPI::dataProcessed, dataMan, &DataManager::setLastSync); - connect(this, &ColnodAPI::dataProcessed, [=](){ + if (!dataMan->getTokensToUpdateDB().contains("empty")){ + syncDeletedDataFromDBToColnod(); + } + if (!dataMan->getTokensToDeleteDB().contains("empty")){ + syncUpdatedDataFromDBToColnod(); + } + connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::clear); + connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::setLastSync); + connect(this, &ColnodAPI::dataUpdatedToColnod, [=](){ auto resp = reqMan->getTokensUpdated(dataMan->getActualSync()); connect(resp, &Response::ready, [=](){ - dataMan->fillTokensColnod(resp->getJson()); + dataMan->fillTokensToUpdateColnod(resp->getJson()); dataMan->setLastUpdate(); dataMan->clear(); + dataMan->updateLastSync(); emit syncFinished(); resp->deleteLater(); }); }); } -void ColnodAPI::processDataToColnod() +// add or update tokens to Colnod +void ColnodAPI::syncUpdatedDataFromDBToColnod() { auto tokensToUpdate = dataMan->getTokensToUpdateDB(); - - if (tokensToUpdate.contains("empty")){ - qDebug() << "No tokens to be modified."; - return; - } - auto tokensToDelete = dataMan->getTokensToDeleteDB(); - auto resp0 = reqMan->setTokens(tokensToUpdate); - auto resp1 = reqMan->deleteTokens(tokensToDelete); + Response* resp0 = reqMan->setTokens(tokensToUpdate); connect(resp0, &Response::ready, [=](){ updateFinished = true; - areDataProcessed(); + areDataUpdatedToColnod(); resp0->deleteLater(); }); - connect(resp1, &Response::ready, [=](){ - deleteFinished = true; - areDataProcessed(); - resp1->deleteLater(); - }); } -// old version -//void ColnodAPI::processDataToColnod() -//{ -// QList* tokensToDelete = dataMan->getTokensToDelete(); -// if ((*tokensToDelete)[0] != "empty") -// { -// Response* resp0 = reqMan->deleteTokens(tokensToDelete); -// connect(resp0, &Response::ready, [=](){ -// isProcessDone(); -// resp0->deleteLater(); -// }); -// } -// QHash>* tokens = dataMan->getTokens(); -// if (!tokens[0].contains("empty")) -// { -// Response* resp1 = reqMan->setTokens(tokens); -// connect(resp1, &Response::ready, [=](){ -// isProcessDone(); -// resp1->deleteLater(); -// }); -// } -// dataMan->clear(); -// connect(this, &ColnodAPI::dataProcessed, this, &ColnodAPI::loadDataFromColnod); -//} +// delete tokens in Colnod +void ColnodAPI::syncDeletedDataFromDBToColnod() +{ + auto tokensToDelete = dataMan->getTokensToDeleteDB(); + Response* resp1 = reqMan->deleteTokens(tokensToDelete); + connect(resp1, &Response::ready, [=](){ + deleteFinished = true; + areDataUpdatedToColnod(); + resp1->deleteLater(); + }); +} // For full sync void ColnodAPI::prepareDatabase() @@ -198,24 +147,19 @@ void ColnodAPI::prepareDatabase() dataMan->emptyDatabase(); } -// PRIVATE FUNCTIONS -void ColnodAPI::areDataReady() -{ - if (dataMan->haveData()) - emit dataDownloaded(); -} - +// emit signal when all data is downloaded from Colnod void ColnodAPI::areChangedDataReady() { if (dataMan->haveChangedData()) emit dataDownloaded(); } - -void ColnodAPI::areDataProcessed() +// emit signal when writing to Colnod is finised +void ColnodAPI::areDataUpdatedToColnod() { if (deleteFinished && updateFinished) { - emit dataProcessed(); + emit dataUpdatedToColnod(); } } + diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 034e8ce..b5353d8 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -16,7 +16,7 @@ public: ColnodAPI(bool debugMode = false); void syncDataFromColnod(); - void syncDataFromDB(); + void syncDataFromDBToColnod(); void prepareDatabase(); @@ -24,10 +24,9 @@ public slots: void loadDataFromColnod(); void loadDataFromDB(); - signals: void dataDownloaded(); - void dataProcessed(); + void dataUpdatedToColnod(); void syncFinished(); private slots: @@ -40,22 +39,21 @@ private: void loadUpdatedDataFromDB(); void loadDeletedDataFromDB(); + void syncUpdatedDataFromColnodToDB(); + void syncDeletedDataFromColnodToDB(); + + void syncUpdatedDataFromDBToColnod(); + void syncDeletedDataFromDBToColnod(); - void syncUpdatedDataFromColnod(); - void syncDeletedDataFromColnod(); - void areDataReady(); void areChangedDataReady(); - void areDataProcessed(); - void processDataToColnod(); - - + void areDataUpdatedToColnod(); +private: RequestManager* reqMan = nullptr; DataManager* dataMan = nullptr; bool debugMode = false; bool updateFinished = false; bool deleteFinished = false; - }; #endif // COLNODAPI_H diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 4874f79..aabd7c7 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -1,6 +1,6 @@ #include "databasemanager.h" -DatabaseManager::DatabaseManager(QString host, QString dbName, QString user, QString password) +DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password) { db = QSqlDatabase::addDatabase("QPSQL"); @@ -12,15 +12,16 @@ DatabaseManager::DatabaseManager(QString host, QString dbName, QString user, QSt //db.setPort(80); // db.setPassword(password); - opened = db.open(); - if (!opened) + + if (!db.open()) { qDebug() << "Opening error" + db.lastError().text(); } query = QSqlQuery("query", db); } -void DatabaseManager::saveSubject(Subject* subject, QString table) +// add or update subject to db +void DatabaseManager::saveSubject(Subject* subject, const QString& table) { QString id = subject->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -47,7 +48,8 @@ void DatabaseManager::saveSubject(Subject* subject, QString table) } } -void DatabaseManager::saveToken(Token* token, QString table) +// add or update token to DB +void DatabaseManager::saveToken(Token* token, const QString& table) { QString id = token->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -91,13 +93,13 @@ void DatabaseManager::saveToken(Token* token, QString table) } } -void DatabaseManager::saveSubjectAttribute(Subject *subject, QString table) +// add of update subject attributes +void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& table) { auto attributes = subject->getAtr(); - for (auto attribute : attributes){ + for (const auto& attribute : attributes){ QString id = subject->idToStringWithoutBraces() + " " + attribute.first; - if (checkIfExists(id, table)) - { + if (checkIfExists(id, table)){ query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) " "WHERE id = :id").arg(table)); query.bindValue(":id", id); @@ -106,8 +108,7 @@ void DatabaseManager::saveSubjectAttribute(Subject *subject, QString table) query.bindValue(":subject_id", subject->idToStringWithoutBraces()); query.exec(); } - else - { + else{ query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)" "VALUES (:id, :key, :value, :subject_id)").arg(table)); query.bindValue(":id", id); @@ -119,7 +120,8 @@ void DatabaseManager::saveSubjectAttribute(Subject *subject, QString table) } } -void DatabaseManager::setDeleted(QString id, QString table) +// "delete" tokens from DB -> set deleted true +void DatabaseManager::setDeleted(const QString& id, const QString& table) { quint64 now = getNow(); QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz"); @@ -129,29 +131,7 @@ void DatabaseManager::setDeleted(QString id, QString table) query.exec(); } -QString DatabaseManager::getTestMessage(int id) -{ - query.prepare("SELECT message FROM test WHERE id = :id"); - query.bindValue(":id", id); - query.exec(); - query.next(); - return query.value(0).toString(); -} - -int DatabaseManager::createTestRecord(QString msg) -{ - query.exec("SELECT MAX(id) FROM test"); - query.next(); - int id = query.value(0).toInt() + 1; - query.prepare("INSERT INTO test (id, message) VALUES (:id, :msg)"); - query.bindValue(":id", id); - query.bindValue(":msg", msg); - query.exec(); - qDebug() << "U inserted new row, id: " << id << "msg: " << getTestMessage(id); - return id; -} - -bool DatabaseManager::checkIfExists(QString id, QString table) +bool DatabaseManager::checkIfExists(const QString& id, const QString& table) { query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table)); query.bindValue(":id", id); @@ -160,16 +140,23 @@ bool DatabaseManager::checkIfExists(QString id, QString table) return query.value(0).toBool(); } +bool DatabaseManager::executeQuery(QSqlQuery &query) const +{ + bool res = query.exec(); + return res; + +} + void DatabaseManager::dropTables() { query.exec("DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute"); } +// create table after deleting, it is used for full sync void DatabaseManager::createTables() { query.exec("CREATE TABLE colnod_subject (" "id character(36) primary key NOT NULL," - //"access_pin smallint," "description character varying(255)," "last_update timestamp NOT NULL," "name character varying(255)," @@ -198,6 +185,7 @@ void DatabaseManager::createTables() "subject_id CHAR(36))"); } +// return last_sync time uint64_t DatabaseManager::getLastSync() { query.exec("SELECT last_sync FROM config"); @@ -206,6 +194,7 @@ uint64_t DatabaseManager::getLastSync() return temp; } +// on the very end of sync set new Last_sync time (begin of this sync) void DatabaseManager::updateLastSync(quint64 lastSync) { query.prepare("UPDATE config SET last_sync = :last_sync"); @@ -213,37 +202,8 @@ void DatabaseManager::updateLastSync(quint64 lastSync) query.exec(); } -void DatabaseManager::makeTestingLast_sync() -{ - query.prepare("INSERT INTO last_changes (last_sync) " - "VALUES (:time)"); - query.bindValue(":time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.exec(); -} - -QSqlQuery* DatabaseManager::getTokensToAdd() -{ - QSqlQuery* qry = new QSqlQuery; - qry->exec("SELECT name, token_data FROM changes WHERE status = 'toBeAdd'"); - return qry; -} - -QSqlQuery* DatabaseManager::getTokensToDelete() -{ - QSqlQuery* qry = new QSqlQuery; - qry->exec("SELECT id FROM changes WHERE status = 'toBeDeleted'"); - return qry; -} - -QUuid DatabaseManager::getId(QString name) -{ - query.prepare("SELECT id FROM colnod_subject WHERE name = :name"); - query.bindValue(":name", name); - query.exec(); - query.next(); - return query.value(0).toUuid(); -} +// return set of tokens to update form DB QSqlQuery* DatabaseManager::getUpdatedTokens() { QSqlQuery* qry = new QSqlQuery; @@ -252,7 +212,7 @@ QSqlQuery* DatabaseManager::getUpdatedTokens() return qry; } -QSqlQuery* DatabaseManager::getToken(QString id) +QSqlQuery* DatabaseManager::getToken(const QString& id) { QSqlQuery* qry = new QSqlQuery; qry->prepare("SELECT SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " @@ -262,9 +222,7 @@ QSqlQuery* DatabaseManager::getToken(QString id) if (qry->next()){ return qry; } - else { - return nullptr; - } + return nullptr; } quint64 DatabaseManager::getNow() @@ -274,7 +232,8 @@ quint64 DatabaseManager::getNow() return query.value(0).toULongLong(); } -void DatabaseManager::setLastUpdate(QString id, quint64 lastUpdate) +// sync last update back to DB from Colnod after changes made to Colnod +void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) { query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id"); query.bindValue(":id", id); diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index cadc248..971f1ca 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -16,53 +16,32 @@ class DatabaseManager : public QObject { Q_OBJECT public: - DatabaseManager(QString host, QString dbName, QString user, QString password); + DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password); - - - void saveSubject(Subject* subject, QString table); - void saveToken(Token* token, QString table); - void saveSubjectAttribute(Subject* subject, QString table); - void setDeleted(QString id, QString table); - - - QString getTestMessage(int id); - int createTestRecord(QString msg); - // - void makeTestingLast_sync(); - // + void saveSubject(Subject* subject, const QString& table); + void saveToken(Token* token, const QString& table); + void saveSubjectAttributes(Subject* subject, const QString& table); + void setDeleted(const QString& id, const QString& table); void dropTables(); void createTables(); - bool getOpened() {return opened;} quint64 getLastSync(); void updateLastSync(quint64 lastSync); quint64 getNow(); QSqlQuery* getUpdatedTokens(); - QSqlQuery* getToken(QString id); - - // Old version - QSqlQuery* getTokensToAdd(); - QSqlQuery* getTokensToDelete(); - - void setLastUpdate(QString id, quint64 lastUpdate); - - QUuid getId(QString name); + QSqlQuery* getToken(const QString& id); + void setLastUpdate(const QString& id, quint64 lastUpdate); private: - bool checkIfExists(QString id, QString table); - + bool checkIfExists(const QString& id, const QString& table); + bool executeQuery(QSqlQuery &query) const; private: QSqlDatabase db; QSqlQuery query; - - bool opened; - - }; #endif // DATABASEMANAGER_H diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 7606ddb..66995c9 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -9,113 +9,123 @@ DataManager::DataManager() //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); } -void DataManager::fillFullTokensColnod(QString response) +// load all tokens from colnod to comparing with working set from DB +void DataManager::fillFullTokensColnod(const QString& response) { QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) + if (!items.empty()) { for (QJsonValueRef item : items) { auto token = new Token(); token->fromJSON(item.toObject()); - fullTokensColnod.insert(token->idToStringWithoutBraces(), token); + allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } else { auto token = new Token("empty"); - fullTokensColnod.insert(token->idToStringWithoutBraces(), token); + allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } -void DataManager::fillTokensColnod(QString response) +// load working set with updated tokens from Colnod +void DataManager::fillTokensToUpdateColnod(const QString& response) { QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) + if (!items.empty()) { for (QJsonValueRef item : items) { auto token = new Token(); token->fromJSON(item.toObject()); token->setDeleted(false); - tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); } } else { auto token = new Token("empty"); - tokensToUpdateColnod.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); } } -void DataManager::fillSubjectsColnod(QString response) +// load working set with updated subjects from Colnod +void DataManager::fillSubjectsToUpdateColnod(const QString& response) { QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) + if (!items.empty()) { for (QJsonValueRef item : items) { auto subject = new Subject(); subject->fromJSON(item.toObject()); - subjectsColnod.insert(subject->idToStringWithoutBraces(), subject); + subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } } else { Subject* subject = new Subject("empty"); - subjectsColnod.insert(subject->idToStringWithoutBraces(), subject); + subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } } -// fills tokensDB and tokensToDeleteDB -void DataManager::fillTokensDB() +// load working sets with updated/deleted tokens from DB +void DataManager::fillTokensToUpdateDB() { QSqlQuery* query = db->getUpdatedTokens(); while (query->next()) { auto token = new Token; token->fromSQLRecord(query); - tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token); + if (token->getDeleted()){ // sort to delete and to update + tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces()); + } + else{ + tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); + } } - qDebug() << "Number of tokens to update from DB: "<< tokensToUpdateDB.size(); - qDebug() << "Number of tokens to delete from DB: "<< tokensToDeleteDB.size(); + qDebug() << "Number of tokens to update from DB: "<< tokensToUpdateFromDBToColnod.size(); + qDebug() << "Number of tokens to delete from DB: "<< tokensFromDBToDeleteFromColnod.size(); } -void DataManager::fillSubjectsDB() +void DataManager::fillSubjectsToUpdateDB() { // Not needed yet } -void DataManager::fillSubjectsToDeleteColnod(QString json) +// load working set with subjest to delete from Colnod +void DataManager::fillSubjectsToDeleteColnod(const QString& json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) + if (!items.empty()) { for (QJsonValueRef item : items) { - subjectsToDeleteColnod.append(item.toString()); + subjectsFromColnodToDeleteFromDB.append(item.toString()); } } else { - subjectsToDeleteColnod.append("empty"); + subjectsFromColnodToDeleteFromDB.append("empty"); } } -void DataManager::fillTokensToDeleteColnod(QString json) +// load working set with tokenst to delete from colnod +void DataManager::fillTokensToDeleteColnod(const QString& json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); - if (items.size() > 0) + if (!items.empty()) { for (QJsonValueRef item : items) { - tokensToDeleteColnod.append(item.toString()); + tokensFromColnodToDeleteFromDB.append(item.toString()); } } else { - tokensToDeleteColnod.append("empty"); + tokensFromColnodToDeleteFromDB.append("empty"); } } @@ -124,134 +134,126 @@ void DataManager::fillSubjectsToDeleteDB() // Not needed yet } +// update subjects from colnod to DB void DataManager::pushSubjectsToDB() { - if (subjectsColnod.contains("empty")) { + if (subjectsToUpdateFromColnodToDB.contains("empty")) { qDebug() << "All subjects are up to date"; return; } //QSqlDatabase::database().transaction(); qDebug() << "Subjects in progress..."; - for (auto subject : subjectsColnod) + for (const auto& subject : subjectsToUpdateFromColnodToDB) { db->saveSubject(subject, "colnod_subject"); - db->saveSubjectAttribute(subject, "colnod_subject_attribute"); + db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } //QSqlDatabase::database().commit(); - qDebug() << subjectsColnod.size() << " subjects has been updated"; + qDebug() << subjectsToUpdateFromColnodToDB.size() << " subjects has been updated"; } +// update tokens from colnod to DB void DataManager::pushTokensToDB() { - if (tokensToUpdateColnod.contains("empty")) + if (tokensToUpdateFromColnodToDB.contains("empty")) { qDebug() << "All tokens are up to date"; return; } //QSqlDatabase::database().transaction(); qDebug() << "Tokens in progress..."; - for (auto token : tokensToUpdateColnod) + for (const auto& token : tokensToUpdateFromColnodToDB) { db->saveToken(token, "colnod_token"); } //QSqlDatabase::database().commit(); - qDebug() << tokensToUpdateColnod.size() << " tokens has been updated"; + qDebug() << tokensToUpdateFromColnodToDB.size() << " tokens has been updated"; } void DataManager::deleteSubjectsFromDB() { - if (subjectsToDeleteColnod[0] == "empty") + if (subjectsFromColnodToDeleteFromDB[0] == "empty") { qDebug() << "No subjects to be deleted"; return; } qDebug() << "Deleted subjects in progress..."; - for (auto subjectId : subjectsToDeleteColnod) + for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { db->setDeleted(subjectId, "colnod_subject"); } - qDebug() << subjectsToDeleteColnod.size() << "subject has beed deleted"; + qDebug() << subjectsFromColnodToDeleteFromDB.size() << "subject has beed deleted"; } -void DataManager::deleteTokensFromDB() +// "delete" (set deleted true) tokens in DB depends on Colnod +void DataManager::setDeletedToTokensFromDB() { - if (tokensToDeleteColnod[0] == "empty") + if (tokensFromColnodToDeleteFromDB[0] == "empty") { qDebug() << "No tokens to be deleted"; return; } qDebug() << "Deleted tokens in progress..."; - for (auto tokenId : tokensToDeleteColnod) + for (const auto& tokenId : tokensFromColnodToDeleteFromDB) { db->setDeleted(tokenId, "colnod_token"); } - qDebug() << tokensToDeleteColnod.size() << "tokens has beed deleted"; -} - -bool DataManager::haveData() -{ - if ( !subjectsColnod.isEmpty() && !tokensToUpdateColnod.isEmpty() ) - return true; - return false; + qDebug() << tokensFromColnodToDeleteFromDB.size() << "tokens has beed deleted"; } +// do I have loaded all data bool DataManager::haveChangedData() { - if ( !subjectsColnod.isEmpty() && - !tokensToUpdateColnod.isEmpty() && - !subjectsToDeleteColnod.isEmpty() && - !tokensToDeleteColnod.isEmpty() && - !fullTokensColnod.isEmpty() ) - return true; - return false; -} - -bool DataManager::haveProcessData() -{ - if ( !tokensToUpdateColnod.isEmpty() && !tokensToDeleteColnod.isEmpty()) - return true; - return false; + return !subjectsToUpdateFromColnodToDB.isEmpty() && + !tokensToUpdateFromColnodToDB.isEmpty() && + !subjectsFromColnodToDeleteFromDB.isEmpty() && + !tokensFromColnodToDeleteFromDB.isEmpty() && + !allTokensFromColnod.isEmpty(); } +// recreate working tables void DataManager::emptyDatabase() { db->dropTables(); db->createTables(); } +//clear all structures void DataManager::clear() { - subjectsColnod.clear(); - subjectsToDeleteColnod.clear(); - tokensToUpdateColnod.clear(); - tokensToDeleteColnod.clear(); - subjectsDB.clear(); - subjectsToDeleteDB.clear(); - tokensToUpdateDB.clear(); - tokensToDeleteDB.clear(); - fullTokensColnod.clear(); + subjectsToUpdateFromColnodToDB.clear(); + subjectsFromColnodToDeleteFromDB.clear(); + tokensToUpdateFromColnodToDB.clear(); + tokensFromColnodToDeleteFromDB.clear(); + //subjectsDB.clear(); // not need yet + // subjectsToDeleteDB.clear(); // not need yet + tokensToUpdateFromDBToColnod.clear(); + tokensFromDBToDeleteFromColnod.clear(); + allTokensFromColnod.clear(); } +// on the very end of sync update last sync time to begin time of this sync void DataManager::updateLastSync() { db->updateLastSync(nextLastSync); } +// these to filter functions solve colision tokens -> remove when change on this token is earlier then change on the same token on the other side (Colnod/DB) void DataManager::filterTokensDB() { - for (auto token : tokensToUpdateDB) + for (auto token : tokensToUpdateFromDBToColnod) { QString id = token->idToStringWithoutBraces(); - Q_ASSERT(token = fullTokensColnod.value(id)); - if (fullTokensColnod.contains(id) && token < fullTokensColnod.value(id)) - tokensToUpdateDB.remove(id); + Q_ASSERT(token = allTokensFromColnod.value(id)); // if working sets are loading correctly equels should never happend + if (allTokensFromColnod.contains(id) && token < allTokensFromColnod.value(id)) + tokensToUpdateFromDBToColnod.remove(id); } } void DataManager::filterTokensColnod() { - for (auto token : tokensToUpdateColnod) + for (const auto &token : tokensToUpdateFromColnodToDB) { QString id = token->idToStringWithoutBraces(); auto record = db->getToken(id); @@ -261,39 +263,14 @@ void DataManager::filterTokensColnod() tokenDB->fromSQLRecord(record); Q_ASSERT(tokenDB != token); if (tokenDB > token) - tokensToUpdateColnod.remove(id); + tokensToUpdateFromColnodToDB.remove(id); } } -// old version -void DataManager::loadTokensToAdd() -{ - QSqlQuery* query = db->getTokensToAdd(); - while (query->next()) - { - Token* token = new Token(query->value(0).toString(), query->value(1).toString()); - token->setSubjectId(db->getId(token->getName())); - tokensToUpdateDB.insert(token->idToStringWithoutBraces(), token); - } - if (tokensToUpdateDB.isEmpty()) - tokensToUpdateDB.insert("empty", nullptr); -} - -void DataManager::loadTokensToDelete() -{ - QSqlQuery* query = db->getTokensToDelete(); - while (query->next()) - { - tokensToDeleteDB.append(query->value(0).toString()); - } - if (tokensToDeleteDB.isEmpty()) - tokensToDeleteDB.append("empty"); -} - - +// sync last update in colnod and DB void DataManager::setLastUpdate() { - for (auto token : tokensToUpdateColnod){ + for (const auto &token : tokensToUpdateFromColnodToDB){ db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate()); } } diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 7a14373..ebe5eff 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -17,16 +17,15 @@ class DataManager : public QObject public: DataManager(); - void getAndSetLastSync(); - void fillFullTokensColnod(QString jsonResponse); + void fillFullTokensColnod(const QString& jsonResponse); - void fillTokensColnod(QString jsonResponse); - void fillSubjectsColnod(QString jsonResponse); - void fillSubjectsToDeleteColnod(QString jsonResponse); - void fillTokensToDeleteColnod(QString jsonResponse); + void fillTokensToUpdateColnod(const QString& jsonResponse); + void fillSubjectsToUpdateColnod(const QString& jsonResponse); + void fillSubjectsToDeleteColnod(const QString& jsonResponse); + void fillTokensToDeleteColnod(const QString& jsonResponse); - void fillTokensDB(); - void fillSubjectsDB(); + void fillTokensToUpdateDB(); + void fillSubjectsToUpdateDB(); void fillSubjectsToDeleteDB(); void filterTokensDB(); @@ -35,23 +34,18 @@ public: void pushSubjectsToDB(); void pushTokensToDB(); void deleteSubjectsFromDB(); - void deleteTokensFromDB(); + void setDeletedToTokensFromDB(); void updateLastSync(); - bool haveData(); bool haveChangedData(); - bool haveProcessData(); void emptyDatabase(); - void loadTokensToAdd(); - void loadTokensToDelete(); - - QHash> getTokensToUpdateColnod() {return tokensToUpdateColnod;} - QList getTokensToDeleteColnod() {return tokensToDeleteColnod;} - QHash> getTokensToUpdateDB() {return tokensToUpdateDB;} - QList getTokensToDeleteDB() {return tokensToDeleteDB;} + QHash> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;} + QList getTokensToDeleteColnod() {return tokensFromColnodToDeleteFromDB;} + QHash> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;} + QList getTokensToDeleteDB() {return tokensFromDBToDeleteFromColnod;} const quint64 &getLastSync() {return lastSync;} const quint64 &getActualSync() {return nextLastSync;} @@ -64,20 +58,19 @@ public slots: private: DatabaseManager *db = nullptr; - quint64 lastSync; - quint64 nextLastSync; + quint64 lastSync; // time of last run + quint64 nextLastSync; // time of begin of this run - QHash> subjectsColnod; - QHash> tokensToUpdateColnod; - QHash> fullTokensColnod; + QHash> subjectsToUpdateFromColnodToDB; + QHash> tokensToUpdateFromColnodToDB; + QHash> allTokensFromColnod; QHash> subjectsDB; // in future - QHash> tokensToUpdateDB; + QHash> tokensToUpdateFromDBToColnod; - - QList subjectsToDeleteColnod; - QList tokensToDeleteColnod; + QList subjectsFromColnodToDeleteFromDB; + QList tokensFromColnodToDeleteFromDB; QList subjectsToDeleteDB; - QList tokensToDeleteDB; + QList tokensFromDBToDeleteFromColnod; }; diff --git a/src/colnod/entity.h b/src/colnod/entity.h index de44ca0..97925c2 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -27,11 +27,11 @@ public: virtual void fromJSON(const QJsonObject &json); virtual QJsonObject toJSON() const; -protected: +private: QUuid id; QString name; QString description; - qint64 lastUpdate; + qint64 lastUpdate{}; }; diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 45733bf..39f9b48 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -4,15 +4,7 @@ RequestManager::RequestManager() { manager = new QNetworkAccessManager(); token = ""; - loginStatus = false; //should be false, true for testing request header -/* - QFile configFile(QDir::current().filePath("config.json")); - if (!configFile.open(QIODevice::ReadOnly)) { - qCritical() << "Couldn't open config file config.json" << QDir::current().filePath("config.json"); - QCoreApplication::exit(-1); - return; - } - this->config = QJsonDocument::fromJson(configFile.readAll());*/ + loginStatus = false; QObject::connect(manager, &QNetworkAccessManager::sslErrors, this, &RequestManager::onSSLError); } @@ -53,7 +45,7 @@ Response* RequestManager::login() return loginResponse; } -QNetworkReply* RequestManager::postRequest(QString endpoint, QByteArray json) +QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteArray& json) { QNetworkRequest request; request.setUrl(host + endpoint); @@ -75,26 +67,21 @@ QNetworkReply* RequestManager::postRequest(QString endpoint, QByteArray json) return reply; } - +// This will ensure login is called only once Response* RequestManager::getLoginResponse() { if (!loginResponse){ loginResponse = login(); - - } return loginResponse; } -Response* RequestManager::postRequestReturnLogic(QString endpoint, QByteArray data) +Response* RequestManager::postRequestReturnLogic(const QString& endpoint, const QByteArray& data) { auto loginResponse = getLoginResponse(); - // This will ensure login is called only once - Q_ASSERT(loginResponse); - Response* response = new Response; + auto* response = new Response; if (!loginStatus){ - connect(this, &RequestManager::successLogin, [=](){ response->setReply(postRequest(endpoint, data)); connect(response->getReply(), &QNetworkReply::finished, response, &Response::ready); @@ -108,9 +95,10 @@ Response* RequestManager::postRequestReturnLogic(QString endpoint, QByteArray da return response; } -QString RequestManager::getFromJson(QString json, const QString &member) +// get value of member in json +QString RequestManager::getFromJson(const QString& json, const QString &member) { - QJsonParseError err; + QJsonParseError err{}; QJsonDocument document = QJsonDocument::fromJson(json.toUtf8(),&err); if (err.error != 0) { @@ -119,12 +107,12 @@ QString RequestManager::getFromJson(QString json, const QString &member) return document.object().value(member).toString(); } -QString RequestManager::encryptedPassword(QString password) +QString RequestManager::encryptedPassword(const QString& password) { return QCryptographicHash::hash(password.toLocal8Bit(), QCryptographicHash::Sha512).toHex().toUpper(); } -QString RequestManager::getLoginHeader(QString username, QString hash) +QString RequestManager::getLoginHeader(const QString& username, const QString& hash) { QString authValue = username + ":" + hash; return "Basic " + authValue.toLocal8Bit().toBase64(); @@ -150,7 +138,7 @@ void RequestManager::onSSLError(QNetworkReply *reply, const QList &er } -QByteArray RequestManager::makeTimeStampJson(uint64_t time) +QByteArray RequestManager::makeTimestampJson(uint64_t time) { QJsonObject reqBody = {{"timestamp",QJsonValue(static_cast(time)) }}; QJsonDocument doc; @@ -162,7 +150,7 @@ QByteArray RequestManager::makeTokensJson(const QHash > { QJsonObject items; QJsonArray jsonTokens; - for (auto token : tokens) + for (const auto& token : tokens) { jsonTokens.push_back(token->toJSON()); } @@ -175,7 +163,7 @@ QByteArray RequestManager::makeTokensJson(const QHash > QByteArray RequestManager::makeIdsJson(const QList &ids) { QJsonArray jsonIds; - for (auto id : ids) + for (const auto& id : ids) { jsonIds.push_back(id); } @@ -203,22 +191,22 @@ Response* RequestManager::getTokenSubject() Response* RequestManager::getSubjectsUpdated(uint64_t time) { - return postRequestReturnLogic("/SubjectManager/getSubjectsUpdated", makeTimeStampJson(time)); + return postRequestReturnLogic("/SubjectManager/getSubjectsUpdated", makeTimestampJson(time)); } Response* RequestManager::getSubjectsDeleted(uint64_t time) { - return postRequestReturnLogic("/SubjectManager/getSubjectsDeleted", makeTimeStampJson(time)); + return postRequestReturnLogic("/SubjectManager/getSubjectsDeleted", makeTimestampJson(time)); } Response* RequestManager::getTokensUpdated(uint64_t time) { - return postRequestReturnLogic("/TokenManager/getTokensUpdated", makeTimeStampJson(time)); + return postRequestReturnLogic("/TokenManager/getTokensUpdated", makeTimestampJson(time)); } Response* RequestManager::getTokensDeleted(uint64_t time) { - return postRequestReturnLogic("/TokenManager/getTokensDeleted", makeTimeStampJson(time)); + return postRequestReturnLogic("/TokenManager/getTokensDeleted", makeTimestampJson(time)); } Response* RequestManager::getAccessGroups() @@ -228,12 +216,12 @@ Response* RequestManager::getAccessGroups() Response* RequestManager::getAccessGroupsUpdated(uint64_t time) { - return postRequestReturnLogic("/AccessManager/getAccessGroupsUpdated", makeTimeStampJson(time)); + return postRequestReturnLogic("/AccessManager/getAccessGroupsUpdated", makeTimestampJson(time)); } Response* RequestManager::getAccessGroupsDeleted(uint64_t time) { - return postRequestReturnLogic("/AccessManager/getAccessGroupsDeleted", makeTimeStampJson(time)); + return postRequestReturnLogic("/AccessManager/getAccessGroupsDeleted", makeTimestampJson(time)); } Response* RequestManager::getAccessGroupMembership() @@ -243,12 +231,12 @@ Response* RequestManager::getAccessGroupMembership() Response* RequestManager::getAccessGroupMembershipUpdated(uint64_t time) { - return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipUpdated", makeTimeStampJson(time)); + return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipUpdated", makeTimestampJson(time)); } Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time) { - return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimeStampJson(time)); + return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimestampJson(time)); } Response* RequestManager::setTokens(const QHash > &tokens) diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index e169b58..375499e 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -58,13 +58,13 @@ public: const QString &getResponse() const {return jsonResponse;} private: - QNetworkReply* postRequest(QString endpoint, QByteArray json = QByteArray()); - Response* postRequestReturnLogic(QString endpoint, QByteArray data = QByteArray()); - QString getFromJson(QString json, const QString &member); - QString encryptedPassword(QString password); - QString getLoginHeader(QString username, QString hash); + QNetworkReply* postRequest(const QString& endpoint, const QByteArray& json = QByteArray()); + Response* postRequestReturnLogic(const QString& endpoint, const QByteArray& data = QByteArray()); + QString getFromJson(const QString& json, const QString &member); + QString encryptedPassword(const QString& password); + QString getLoginHeader(const QString& username, const QString& hash); - QByteArray makeTimeStampJson(uint64_t time); + QByteArray makeTimestampJson(uint64_t time); QByteArray makeTokensJson(const QHash> &tokens); QByteArray makeIdsJson(const QList &ids); Response* getLoginResponse(); diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index 1cfb763..6556cf6 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -4,9 +4,9 @@ #include -Subject::Subject(QString namee) +Subject::Subject(QString name) { - this->name = namee; + setName(std::move(name)); } QString Subject::getEmail() const { @@ -17,10 +17,10 @@ void Subject::fromJSON(const QJsonObject &json) { Entity::fromJSON(json); attributes = json.value("attributes").toObject().value("items").toObject(); - for (int i = 0; i < attributeTypes->length(); i++) + for (const auto & attributeType : attributeTypes) { - if (!attributes[attributeTypes[i]].toString().isEmpty()){ - atr.append(qMakePair(attributeTypes[i], attributes[attributeTypes[i]].toString())); + if (!attributes[attributeType].toString().isEmpty()){ + atr.append(qMakePair(attributeType, attributes[attributeType].toString())); } } const auto &tokenFlagsArray = json.value("tokenFlags").toArray(); diff --git a/src/colnod/subject.h b/src/colnod/subject.h index 1377c50..dd587eb 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -12,7 +12,7 @@ class Subject : public Entity { public: using Entity::Entity; - + Subject() = default; Subject(QString name); QString getEmail() const; @@ -33,14 +33,14 @@ public: void fromJSON(const QJsonObject &json) override; QJsonObject toJSON() const override; -protected: +private: QJsonObject attributes; QSet tokenFlags; QString pin; QSet pinFlags; //QList> atr; QList> atr; - const QString attributeTypes[6] = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; + const std::array attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; }; diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 2b48e1e..6f24b9b 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -1,13 +1,14 @@ #include "token.h" #include +#include -Token::Token(QString namee, QString tokenData, QString decription) +Token::Token(QString name, QString tokenData, QString decription) { - this->name = namee; - this->tokenData = tokenData; - this->description = decription; - this->id = QUuid::createUuid(); + this->setName(std::move(name)); + this->tokenData = std::move(tokenData); + this->setDescription(std::move(decription)); + this->setId(QUuid::createUuid()); this->tokenType = "Token"; this->tokenBits = 32; this->timeToLive = 255; @@ -16,9 +17,9 @@ Token::Token(QString namee, QString tokenData, QString decription) } -Token::Token(QString namee) +Token::Token(QString name) { - this->name = namee; + this->setName(std::move(name)); } @@ -57,17 +58,17 @@ QJsonObject Token::toJSON() const { void Token::fromSQLRecord(QSqlQuery *query) { - id = query->value(0).toUuid(); + setId(query->value(0).toUuid()); authErrors = query->value(1).toInt(); - description = query->value(2).toString(); + setDescription(query->value(2).toString()); QSet flags; if (query->value(6).toBool()) flags.insert("NoValidity"); if (query->value(3).toBool()) flags.insert("Enabled"); this->flags = flags; - lastUpdate = query->value(4).toUInt(); - name = query->value(5).toString(); + setLastUpdate(query->value(4).toUInt()); + setName(query->value(5).toString()); timeToLive = query->value(7).toInt(); tokenBits = query->value(8).toInt(); tokenData = query->value(9).toString(); diff --git a/src/colnod/token.h b/src/colnod/token.h index c06dcdc..5d58eff 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -51,18 +51,19 @@ public: void fromSQLRecord(QSqlQuery* query); void fromJSON(const QJsonObject &json) override; QJsonObject toJSON() const override; -protected: + +private: QString tokenType; - int tokenBits; + int tokenBits{}; QString tokenData; - quint64 validFrom; - quint64 validTo; - int timeToLive; - int authErrors; + qint64 validFrom{}; + qint64 validTo{}; + int timeToLive{}; + int authErrors{}; QSet flags; QUuid subjectId; - quint64 lastModified; - bool deleted; + quint64 lastModified{}; + bool deleted{}; }; diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index d907b5e..f442bbd 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -7,12 +7,11 @@ void UnitTest::initTestCase() void UnitTest::loginSuccessfully() { - RequestManager* testAccess = new RequestManager(); - QJsonDocument config = testAccess->getConfig(); + auto testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(successLogin())); QVERIFY(spy.isValid()); testAccess->login(); - spy.wait(15000); + spy.wait(timeout); QCOMPARE(spy.count(), 1); QString json = testAccess->getResponse(); @@ -24,13 +23,13 @@ void UnitTest::loginSuccessfully() //POST request w/o datas void UnitTest::getSubjects() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); QVERIFY(spy.isValid()); Response* response = testAccess->getSubjects(); QSignalSpy spy1(response, &Response::ready); - spy.wait(15000); + spy.wait(timeout); QCOMPARE(spy.count(), 1); QCOMPARE(spy1.count(), 1); @@ -45,11 +44,11 @@ void UnitTest::getSubjects() void UnitTest::getTokens() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); Response* response = testAccess->getTokens(); QSignalSpy spy(response, &Response::ready); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -62,11 +61,11 @@ void UnitTest::getTokens() void UnitTest::getTokenSubject() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->getTokenSubject(); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -75,11 +74,11 @@ void UnitTest::getTokenSubject() void UnitTest::getSubjectsUpdated() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getSubjectsUpdated(1568646217767); + Response* response = testAccess->getSubjectsUpdated(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -88,11 +87,11 @@ void UnitTest::getSubjectsUpdated() void UnitTest::getSubjectsDeleted() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getSubjectsDeleted(1568646217767); + Response* response = testAccess->getSubjectsDeleted(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -101,11 +100,11 @@ void UnitTest::getSubjectsDeleted() void UnitTest::getTokensUpdated() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getTokensUpdated(1570109859681); + Response* response = testAccess->getTokensUpdated(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -114,11 +113,11 @@ void UnitTest::getTokensUpdated() void UnitTest::getTokensDeleted() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getTokensDeleted(1570109859681); + Response* response = testAccess->getTokensDeleted(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -127,11 +126,11 @@ void UnitTest::getTokensDeleted() void UnitTest::getAccessGroups() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->getAccessGroups(); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -140,11 +139,11 @@ void UnitTest::getAccessGroups() void UnitTest::getAccessGroupsUpdated() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getAccessGroupsUpdated(1568646217767); + Response* response = testAccess->getAccessGroupsUpdated(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -153,11 +152,11 @@ void UnitTest::getAccessGroupsUpdated() void UnitTest::getAccessGroupsDeleted() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getAccessGroupsDeleted(1568646217767); + Response* response = testAccess->getAccessGroupsDeleted(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -166,11 +165,11 @@ void UnitTest::getAccessGroupsDeleted() void UnitTest::getAccessGroupMembership() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->getAccessGroupMembership(); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -179,11 +178,11 @@ void UnitTest::getAccessGroupMembership() void UnitTest::getAccessGroupMembershipUpdated() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getAccessGroupMembershipUpdated(1568646217767); + Response* response = testAccess->getAccessGroupMembershipUpdated(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -192,11 +191,11 @@ void UnitTest::getAccessGroupMembershipUpdated() void UnitTest::getAccessGroupMembershipDeleted() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); - Response* response = testAccess->getAccessGroupMembershipDeleted(1568646217767); + Response* response = testAccess->getAccessGroupMembershipDeleted(epochMS); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -220,11 +219,11 @@ void UnitTest::setTokens() qDebug() << token; tokens.insert(token->idToStringWithoutBraces(), token); } - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->setTokens(tokens); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -233,14 +232,14 @@ void UnitTest::setTokens() void UnitTest::deleteTokens() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); QList ids; ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); Response* response = testAccess->deleteTokens(ids); QCOMPARE(spy.count(), 0); - spy.wait(15000); + spy.wait(timeout); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 1); QString json = response->getJson(); @@ -262,10 +261,10 @@ void UnitTest::subjectJSONParser() QJsonObject obj = doc.object(); QJsonArray arr = obj["items"].toArray(); */ - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->getSubjects(); - spy.wait(15000); + spy.wait(timeout); QString json = response->getJson(); QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray arr = doc.object()["items"].toArray(); @@ -277,10 +276,10 @@ void UnitTest::subjectJSONParser() void UnitTest::tokenJSONParser() { - RequestManager* testAccess = new RequestManager(); + auto* testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->getTokens(); - spy.wait(15000); + spy.wait(timeout); QString json = response->getJson(); QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray arr = doc.object()["items"].toArray(); @@ -290,15 +289,15 @@ void UnitTest::tokenJSONParser() QVERIFY(!testToken->getName().isEmpty()); } -void UnitTest::connectToDB() -{ - DatabaseManager *db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12"); - QVERIFY(db->getOpened()); - qDebug() << db->getTestMessage(1); - QVERIFY(true); - QCOMPARE(db->getTestMessage(1), QStringLiteral("Hello world")); - QCOMPARE(db->getTestMessage(db->createTestRecord("Now it's diffrent")), QStringLiteral("Now it's diffrent")); -} +//void UnitTest::connectToDB() +//{ +// DatabaseManager *db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12"); +// QVERIFY(db->getOpened()); +// qDebug() << db->getTestMessage(1); +// QVERIFY(true); +// QCOMPARE(db->getTestMessage(1), QStringLiteral("Hello world")); +// QCOMPARE(db->getTestMessage(db->createTestRecord("Now it's diffrent")), QStringLiteral("Now it's diffrent")); +//} /* void UnitTest::debugConnection() diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index cbe31d5..a2ea479 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -9,7 +9,7 @@ void ComplexTest::initTestCase() Response* deleteTokensResp = reqMan1->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); + deleteTokensRespSpy.wait(timeout); QTest::qWait(2500); start = QDateTime::currentMSecsSinceEpoch()-2000; api = new ColnodAPI; @@ -26,7 +26,7 @@ void ComplexTest::cleanupTestCase() Response* deleteTokensResp = reqMan->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); + deleteTokensRespSpy.wait(timeout); QCOMPARE(deleteTokensRespSpy.count(), 1); } @@ -39,7 +39,7 @@ void ComplexTest::complexTest() QSignalSpy loginRespSpy(loginResp, &Response::ready); QCOMPARE(loginSpy.count(), 0); QCOMPARE(loginRespSpy.count(), 0); - loginSpy.wait(10000); + loginSpy.wait(timeout); QCOMPARE(loginResp->getStatusCode(), 200); // HTTP status code check QCOMPARE(loginSpy.count(), 1); // Checking multiple calls QCOMPARE(loginRespSpy.count(), 1); @@ -62,7 +62,7 @@ void ComplexTest::complexTest() Response* setTokensResp = reqMan->setTokens(tokens); QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); QCOMPARE(setTokensRespSpy.count(), 0); - setTokensRespSpy.wait(10000); + setTokensRespSpy.wait(timeout); QCOMPARE(setTokensRespSpy.count(), 1); QCOMPARE(setTokensResp->getStatusCode(), 200); QCOMPARE(getNumOfTokens(), numOfTokens + 1); @@ -73,7 +73,7 @@ void ComplexTest::complexTest() //start = QDateTime::currentMSecsSinceEpoch(); QSignalSpy getTokensUpdatedRespSpy(getTokensUpdatedResp, &Response::ready); QCOMPARE(getTokensUpdatedRespSpy.count(), 0); - getTokensUpdatedRespSpy.wait(10000); + getTokensUpdatedRespSpy.wait(timeout); QCOMPARE(getTokensUpdatedResp->getStatusCode(), 200); QCOMPARE(getTokensUpdatedRespSpy.count(), 1); auto doc1 = getJsonDoc(getTokensUpdatedResp->getJson()); @@ -86,7 +86,7 @@ void ComplexTest::complexTest() Response* deleteTokensResp = reqMan->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); + deleteTokensRespSpy.wait(timeout); QCOMPARE(deleteTokensRespSpy.count(), 1); QCOMPARE(deleteTokensResp->getStatusCode(), 200); // DELETE_TOKENS_CHECK_END @@ -96,7 +96,7 @@ void ComplexTest::complexTest() start = QDateTime::currentMSecsSinceEpoch(); QSignalSpy getTokensDeletedRespSpy(getTokensDeletedResp, &Response::ready); QCOMPARE(getTokensDeletedRespSpy.count(), 0); - getTokensDeletedRespSpy.wait(10000); + getTokensDeletedRespSpy.wait(timeout); QCOMPARE(getTokensDeletedResp->getStatusCode(), 200); QCOMPARE(getTokensDeletedRespSpy.count(), 1); auto doc2 = getJsonDoc(getTokensDeletedResp->getJson()); @@ -119,7 +119,7 @@ void ComplexTest::fullSync() api->prepareDatabase(); api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); - spy.wait(10000); + spy.wait(timeout); api->syncDataFromColnod(); // api->syncDataToColnod(); } @@ -128,12 +128,14 @@ void ComplexTest::syncLastUpdated() { api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); - spy.wait(10000); + spy.wait(timeout); api->loadDataFromDB(); api->syncDataFromColnod(); - api->syncDataFromDB(); - QSignalSpy processSpy(api, &ColnodAPI::dataProcessed); - processSpy.wait(10000); + api->syncDataFromDBToColnod(); + QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod); + processSpy.wait(timeout); + QSignalSpy finish(api, &ColnodAPI::syncFinished); + finish.wait(timeout); qDebug() << "All right, at least should be."; } @@ -150,7 +152,7 @@ int ComplexTest::getNumOfSubjects() { Response* subjectsResp = reqMan->getSubjects(); QSignalSpy subjectsRespSpy(subjectsResp, &Response::ready); - subjectsRespSpy.wait(10000); + subjectsRespSpy.wait(timeout); auto doc = getJsonDoc(subjectsResp->getJson()); return doc.object()["items"].toArray().size(); } @@ -159,17 +161,17 @@ int ComplexTest::getNumOfTokens() { Response* tokensResp = reqMan->getTokens(); QSignalSpy tokensRespSpy(tokensResp, &Response::ready); - tokensRespSpy.wait(10000); + tokensRespSpy.wait(timeout); auto doc = getJsonDoc(tokensResp->getJson()); return doc.object()["items"].toArray().size(); } -QJsonDocument ComplexTest::getJsonDoc(QString json) +QJsonDocument ComplexTest::getJsonDoc(const QString &json) { return QJsonDocument::fromJson(json.toUtf8()); } -Token* ComplexTest::getTestToken() +QPointer ComplexTest::getTestToken() { QJsonObject jsonToken; jsonToken.insert("id", "582c982d-6fd7-4856-8548-7ce542791c7a"); @@ -185,7 +187,7 @@ Token* ComplexTest::getTestToken() flags.push_back("NoValidity"); jsonToken.insert("flags", flags); jsonToken.insert("subjectId", "72b37f7e-5761-4e6c-8e87-20c0bed0d904"); - Token* token = new Token; + QPointer token = new Token; token->fromJSON(jsonToken); return token; } diff --git a/test/unitTests/complextest.h b/test/unitTests/complextest.h index ed34fe5..0aa1c74 100644 --- a/test/unitTests/complextest.h +++ b/test/unitTests/complextest.h @@ -23,8 +23,8 @@ private: // FUNCTIONS int getNumOfSubjects(); int getNumOfTokens(); - QJsonDocument getJsonDoc(QString json); - Token* getTestToken(); + QJsonDocument getJsonDoc(const QString &json); + QPointer getTestToken(); // VARIABLES @@ -34,5 +34,7 @@ private: RequestManager* reqMan = nullptr; uint64_t start = 0; ColnodAPI* api = nullptr; + + static constexpr qint16 timeout = 10000; }; diff --git a/test/unitTests/unittest.h b/test/unitTests/unittest.h index 2fabad0..3e414e5 100644 --- a/test/unitTests/unittest.h +++ b/test/unitTests/unittest.h @@ -37,7 +37,7 @@ private slots: void deleteTokens(); void subjectJSONParser(); void tokenJSONParser(); - void connectToDB(); + //void connectToDB(); //void debugConnection(); void saveDataToDB(); void getUuid(); @@ -48,4 +48,7 @@ private: QString host = "https://192.168.1.3:8443"; //local testing server QString password = "spaceti1"; QString email = "spaceti"; -}; + + static constexpr int timeout = 10000; + static constexpr qint64 epochMS = 1568646217767; +}; From 520a45d912dd2fb89b577344bcbcd13f473d7073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 23 Oct 2019 15:09:57 +0200 Subject: [PATCH 06/23] fix for correct build --- src/colnod/databasemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index aabd7c7..00b962e 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -186,7 +186,7 @@ void DatabaseManager::createTables() } // return last_sync time -uint64_t DatabaseManager::getLastSync() +quint64 DatabaseManager::getLastSync() { query.exec("SELECT last_sync FROM config"); query.next(); From 7b21c1f9a7d299b3ce7f094a992c6630c5f04624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 23 Oct 2019 15:43:03 +0200 Subject: [PATCH 07/23] Change ifndef to pragma once --- src/app/main.cpp | 30 +++++++++--------------------- src/colnod/colnodapi.cpp | 4 ++-- src/colnod/colnodapi.h | 9 ++------- src/colnod/databasemanager.cpp | 20 ++++++++++---------- src/colnod/databasemanager.h | 6 ++---- src/colnod/datamanager.h | 7 ++----- src/colnod/entity.cpp | 3 ++- src/colnod/entity.h | 7 +------ src/colnod/requestmanager.h | 5 +---- src/colnod/response.h | 5 +---- src/colnod/subject.h | 6 +----- src/colnod/token.h | 8 +------- test/unitTests/complextest.cpp | 5 ++--- 13 files changed, 36 insertions(+), 79 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 41eeeab..8ea2fbd 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -7,28 +7,16 @@ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); auto *api = new ColnodAPI(); - - - /*api->downloadData(); // this will start downloading data - QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ - qDebug() << "now I have all data"; - api->syncDataToColnod(); - QCoreApplication::quit(); - });*/ -// bool syncChanged = false; -// api->downloadChangedDataFromColnod(); -// QObject::connect(api, &ColnodAPI::downloadData, [&](){ -// qDebug() << "Data ready."; -// api->syncChangedDataFromColnod(); -// if (!syncChanged) -// { -// api->syncChangedDataToColnod(); -// syncChanged = true; -// } -// }); - - api->loadDataFromColnod(); api->loadDataFromDB(); + api->loadDataFromColnod(); + QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ + qDebug() << "All items are loaded to data manager."; + api->syncDataFromColnodToDB(); + api->syncDataFromDBToColnod(); + QObject::connect(api, &ColnodAPI::syncFinished, [=](){ + QCoreApplication::exit(); + }); + }); return QCoreApplication::exec(); diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index 739f925..b788b49 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -70,7 +70,7 @@ void ColnodAPI::loadDataFromDB() dataMan->fillTokensToUpdateDB(); } -void ColnodAPI::syncDataFromColnod() +void ColnodAPI::syncDataFromColnodToDB() { dataMan->filterTokensColnod(); syncUpdatedDataFromColnodToDB(); @@ -105,7 +105,7 @@ void ColnodAPI::syncDataFromDBToColnod() connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::clear); connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::setLastSync); connect(this, &ColnodAPI::dataUpdatedToColnod, [=](){ - auto resp = reqMan->getTokensUpdated(dataMan->getActualSync()); + auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync()); connect(resp, &Response::ready, [=](){ dataMan->fillTokensToUpdateColnod(resp->getJson()); dataMan->setLastUpdate(); diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index b5353d8..ba7a19a 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -1,12 +1,8 @@ -#ifndef COLNODAPI_H -#define COLNODAPI_H +#pragma once #include "requestmanager.h" #include "datamanager.h" - - - class ColnodAPI : public QObject { Q_OBJECT @@ -15,7 +11,7 @@ public: ColnodAPI(bool debugMode = false); - void syncDataFromColnod(); + void syncDataFromColnodToDB(); void syncDataFromDBToColnod(); void prepareDatabase(); @@ -56,4 +52,3 @@ private: bool deleteFinished = false; }; -#endif // COLNODAPI_H diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 00b962e..b724328 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -33,7 +33,7 @@ void DatabaseManager::saveSubject(Subject* subject, const QString& table) query.bindValue(":name", subject->getName()); query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":pin", subject->getPin()); - query.exec(); + executeQuery(query); } else { @@ -44,7 +44,7 @@ void DatabaseManager::saveSubject(Subject* subject, const QString& table) query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":name", subject->getName()); query.bindValue(":pin", subject->getPin()); - query.exec(); + executeQuery(query); } } @@ -69,7 +69,7 @@ void DatabaseManager::saveToken(Token* token, const QString& table) query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":deleted", token->getDeleted()); - query.exec(); + executeQuery(query); } else { @@ -89,7 +89,7 @@ void DatabaseManager::saveToken(Token* token, const QString& table) query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":deleted", token->getDeleted()); - query.exec(); + executeQuery(query); } } @@ -106,7 +106,7 @@ void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& tab query.bindValue(":key", attribute.first); query.bindValue(":value", attribute.second); query.bindValue(":subject_id", subject->idToStringWithoutBraces()); - query.exec(); + executeQuery(query); } else{ query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)" @@ -115,7 +115,7 @@ void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& tab query.bindValue(":key", attribute.first); query.bindValue(":value", attribute.second); query.bindValue(":subject_id", subject->idToStringWithoutBraces()); - query.exec(); + executeQuery(query); } } } @@ -128,14 +128,14 @@ void DatabaseManager::setDeleted(const QString& id, const QString& table) query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table)); query.bindValue(":id", id); query.bindValue(":now", nowString); - query.exec(); + executeQuery(query); } bool DatabaseManager::checkIfExists(const QString& id, const QString& table) { query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table)); query.bindValue(":id", id); - query.exec(); + executeQuery(query); query.first(); return query.value(0).toBool(); } @@ -199,7 +199,7 @@ void DatabaseManager::updateLastSync(quint64 lastSync) { query.prepare("UPDATE config SET last_sync = :last_sync"); query.bindValue(":last_sync", lastSync); - query.exec(); + executeQuery(query); } @@ -238,6 +238,6 @@ void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id"); query.bindValue(":id", id); query.bindValue(":lastUpdate", lastUpdate); - query.exec(); + executeQuery(query); } diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 971f1ca..2ad7faf 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -1,5 +1,5 @@ -#ifndef DATABASEMANAGER_H -#define DATABASEMANAGER_H +#pragma once + #include #include #include @@ -43,5 +43,3 @@ private: QSqlDatabase db; QSqlQuery query; }; - -#endif // DATABASEMANAGER_H diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index ebe5eff..3420b07 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -1,5 +1,4 @@ -#ifndef DATAMANAGER_H -#define DATAMANAGER_H +#pragma once #include "token.h" #include "subject.h" @@ -48,7 +47,7 @@ public: QList getTokensToDeleteDB() {return tokensFromDBToDeleteFromColnod;} const quint64 &getLastSync() {return lastSync;} - const quint64 &getActualSync() {return nextLastSync;} + const quint64 &getCurrentSync() {return nextLastSync;} public slots: void clear(); @@ -73,5 +72,3 @@ private: QList tokensFromDBToDeleteFromColnod; }; - -#endif // DATAMANAGER_H diff --git a/src/colnod/entity.cpp b/src/colnod/entity.cpp index 932e3ca..f18bb48 100644 --- a/src/colnod/entity.cpp +++ b/src/colnod/entity.cpp @@ -35,7 +35,8 @@ void Entity::setLastUpdate(quint64 lastUpdate) { QString Entity::idToStringWithoutBraces() { - return id.toString().mid(1,36); + const qint8 lengthOfUuid = 36; + return id.toString().mid(1, lengthOfUuid); } void Entity::fromJSON(const QJsonObject &json) { diff --git a/src/colnod/entity.h b/src/colnod/entity.h index 97925c2..d5fa1dc 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -1,5 +1,4 @@ -#ifndef COLNOD_CONNECTOR_ENTITY_H -#define COLNOD_CONNECTOR_ENTITY_H +#pragma once #include #include @@ -33,7 +32,3 @@ private: QString description; qint64 lastUpdate{}; }; - - - -#endif //COLNOD_CONNECTOR_ENTITY_H diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index 375499e..17b1bba 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -1,5 +1,4 @@ -#ifndef REQUESTMANAGER_H -#define REQUESTMANAGER_H +#pragma once #include #include @@ -93,5 +92,3 @@ private: bool loginStatus; }; - -#endif // REQUESTMANAGER_H diff --git a/src/colnod/response.h b/src/colnod/response.h index 4416f88..7c75c65 100644 --- a/src/colnod/response.h +++ b/src/colnod/response.h @@ -1,5 +1,4 @@ -#ifndef RESPONSE_H -#define RESPONSE_H +#pragma once #include #include @@ -31,5 +30,3 @@ private: QString json; QNetworkReply *reply = nullptr; }; - -#endif // RESPONSE_H diff --git a/src/colnod/subject.h b/src/colnod/subject.h index dd587eb..0046e1a 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -1,5 +1,4 @@ -#ifndef COLNOD_CONNECTOR_SUBJECT_H -#define COLNOD_CONNECTOR_SUBJECT_H +#pragma once #include @@ -43,6 +42,3 @@ private: const std::array attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; }; - - -#endif //COLNOD_CONNECTOR_SUBJECT_H diff --git a/src/colnod/token.h b/src/colnod/token.h index 5d58eff..287aadb 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -1,13 +1,10 @@ -#ifndef COLNOD_CONNECTOR_TOKEN_H -#define COLNOD_CONNECTOR_TOKEN_H +#pragma once #include "entity.h" - #include #include #include - class Token : public Entity { public: // using Entity::Entity; @@ -65,6 +62,3 @@ private: quint64 lastModified{}; bool deleted{}; }; - - -#endif //COLNOD_CONNECTOR_TOKEN_H diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index a2ea479..04c2e70 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -120,7 +120,7 @@ void ComplexTest::fullSync() api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(timeout); - api->syncDataFromColnod(); + api->syncDataFromColnodToDB(); // api->syncDataToColnod(); } @@ -130,14 +130,13 @@ void ComplexTest::syncLastUpdated() QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(timeout); api->loadDataFromDB(); - api->syncDataFromColnod(); + api->syncDataFromColnodToDB(); api->syncDataFromDBToColnod(); QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod); processSpy.wait(timeout); QSignalSpy finish(api, &ColnodAPI::syncFinished); finish.wait(timeout); qDebug() << "All right, at least should be."; - } void ComplexTest::testingStuff() From e0e0d5be7ed9c6ff10f6e730f3f37dba9a991ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 23 Oct 2019 16:10:46 +0200 Subject: [PATCH 08/23] Another analyze changes --- src/colnod/entity.cpp | 4 ++-- src/colnod/entity.h | 2 +- src/colnod/subject.cpp | 4 ++-- src/colnod/subject.h | 2 +- src/colnod/token.cpp | 10 +++++----- src/colnod/token.h | 4 ++-- test/unitTests/complextest.cpp | 3 --- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/colnod/entity.cpp b/src/colnod/entity.cpp index f18bb48..d1d93cb 100644 --- a/src/colnod/entity.cpp +++ b/src/colnod/entity.cpp @@ -33,7 +33,7 @@ void Entity::setLastUpdate(quint64 lastUpdate) { this->lastUpdate = lastUpdate; } -QString Entity::idToStringWithoutBraces() +QString Entity::idToStringWithoutBraces() const { const qint8 lengthOfUuid = 36; return id.toString().mid(1, lengthOfUuid); @@ -49,7 +49,7 @@ void Entity::fromJSON(const QJsonObject &json) { QJsonObject Entity::toJSON() const { QJsonObject json; - json.value("id") = id.toString().mid(1,36); + json.value("id") = this->idToStringWithoutBraces(); json.value("name") = name; json.value("description") = description; json.value("lastUpdate") = lastUpdate; diff --git a/src/colnod/entity.h b/src/colnod/entity.h index d5fa1dc..ec71351 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -22,7 +22,7 @@ public: quint64 getLastUpdate() const; void setLastUpdate(quint64 lastUpdate); - QString idToStringWithoutBraces(); + QString idToStringWithoutBraces() const; virtual void fromJSON(const QJsonObject &json); virtual QJsonObject toJSON() const; diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index 6556cf6..f92f113 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -4,9 +4,9 @@ #include -Subject::Subject(QString name) +Subject::Subject(const QString& name) { - setName(std::move(name)); + setName(name); } QString Subject::getEmail() const { diff --git a/src/colnod/subject.h b/src/colnod/subject.h index 0046e1a..ed7b213 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -12,7 +12,7 @@ class Subject : public Entity { public: using Entity::Entity; Subject() = default; - Subject(QString name); + Subject(const QString& name); QString getEmail() const; diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 6f24b9b..7043c41 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -3,11 +3,11 @@ #include #include -Token::Token(QString name, QString tokenData, QString decription) +Token::Token(const QString& name, QString tokenData, const QString& decription) { - this->setName(std::move(name)); + this->setName(name); this->tokenData = std::move(tokenData); - this->setDescription(std::move(decription)); + this->setDescription(decription); this->setId(QUuid::createUuid()); this->tokenType = "Token"; this->tokenBits = 32; @@ -17,9 +17,9 @@ Token::Token(QString name, QString tokenData, QString decription) } -Token::Token(QString name) +Token::Token(const QString& name) { - this->setName(std::move(name)); + this->setName(name); } diff --git a/src/colnod/token.h b/src/colnod/token.h index 287aadb..e98ef68 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -10,8 +10,8 @@ public: // using Entity::Entity; Token() = default; - Token(QString name, QString tokenData, QString decription = "mobile"); - Token(QString name); + Token(const QString& name, QString tokenData, const QString& decription = "mobile"); + Token(const QString& name); friend bool operator<(const Token &rToken, const Token &lToken){ return rToken.getLastModified() < lToken.getLastUpdate(); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 04c2e70..df99862 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -104,8 +104,6 @@ void ComplexTest::complexTest() QVERIFY(doc2.object()["items"].toArray().contains("582c982d-6fd7-4856-8548-7ce542791c7a")); // CHECK_DELETED_TOKENS_END - - // LAST_TESTS (for sure) QCOMPARE(loginSpy.count(), 1); // Checking multiple calls QCOMPARE(loginRespSpy.count(), 1); @@ -113,7 +111,6 @@ void ComplexTest::complexTest() QCOMPARE(getNumOfTokens(), numOfTokens); } - void ComplexTest::fullSync() { api->prepareDatabase(); From 921fc2cb776067da675ac2d4e2e378794168c9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Thu, 24 Oct 2019 15:56:53 +0200 Subject: [PATCH 09/23] add dry mode, compare '>' for tokens doesnt work correctly --- README.md | 1 + src/app/main.cpp | 12 ++++- src/colnod/colnodapi.cpp | 35 +++++++++----- src/colnod/colnodapi.h | 4 +- src/colnod/databasemanager.cpp | 85 +++++++++++++++++++++++----------- src/colnod/databasemanager.h | 9 ++-- src/colnod/datamanager.cpp | 70 ++++++++++++++++------------ src/colnod/datamanager.h | 6 ++- src/colnod/requestmanager.cpp | 2 +- src/colnod/subject.cpp | 2 +- src/colnod/token.cpp | 8 ++-- src/colnod/token.h | 8 ++-- test/unitTests/complextest.cpp | 9 +++- 13 files changed, 163 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index ca289c0..b652349 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Acces Management System of Colsys: [Product info](http://produkty.colsys.cz/coln - To DB - Number of subjects added/deleted/updated - Number of tokens added/deleted/updated + ## Requirements - QPSQL driver must be installed (PostgreSQL) diff --git a/src/app/main.cpp b/src/app/main.cpp index 8ea2fbd..62ab6ea 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -2,11 +2,19 @@ #include "datamanager.h" #include "colnodapi.h" +#include int main(int argc, char *argv[]) { - QCoreApplication a(argc, argv); - auto *api = new ColnodAPI(); + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName("colnod-connector"); + QCoreApplication::setApplicationVersion("1.0"); + QCommandLineParser parser; + parser.setApplicationDescription("Dry mode"); + QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which normally be doing"); + parser.addOption(dryModeOption); + parser.process(app); + auto *api = new ColnodAPI(true); // parser.isSet(dryModeOption)); api->loadDataFromDB(); api->loadDataFromColnod(); QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index b788b49..c6a4add 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -1,10 +1,10 @@ #include "colnodapi.h" -ColnodAPI::ColnodAPI(bool debug) +ColnodAPI::ColnodAPI(bool dryMode) { reqMan = new RequestManager(); - dataMan = new DataManager(); - debugMode = debug; + dataMan = new DataManager(dryMode); + this->dryMode = dryMode; } void ColnodAPI::loadDataFromColnod() @@ -67,12 +67,11 @@ void ColnodAPI::loadDeletedDataFromColnod() // fill structures in data manager (tokens to updata/to delte) void ColnodAPI::loadDataFromDB() { - dataMan->fillTokensToUpdateDB(); + dataMan->fillTokensToChangeDB(); } void ColnodAPI::syncDataFromColnodToDB() { - dataMan->filterTokensColnod(); syncUpdatedDataFromColnodToDB(); if (dataMan->getLastSync() != 0) syncDeletedDataFromColnodToDB(); @@ -95,13 +94,17 @@ void ColnodAPI::syncDeletedDataFromColnodToDB() // push changes form DB to Colnod void ColnodAPI::syncDataFromDBToColnod() { - dataMan->filterTokensDB(); + if (!dataMan->getTokensToUpdateDB().contains("empty")){ syncDeletedDataFromDBToColnod(); } + else + deleteFinished = true; if (!dataMan->getTokensToDeleteDB().contains("empty")){ syncUpdatedDataFromDBToColnod(); } + else + updateFinished = true; connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::clear); connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::setLastSync); connect(this, &ColnodAPI::dataUpdatedToColnod, [=](){ @@ -121,17 +124,25 @@ void ColnodAPI::syncDataFromDBToColnod() void ColnodAPI::syncUpdatedDataFromDBToColnod() { auto tokensToUpdate = dataMan->getTokensToUpdateDB(); - Response* resp0 = reqMan->setTokens(tokensToUpdate); - connect(resp0, &Response::ready, [=](){ - updateFinished = true; - areDataUpdatedToColnod(); - resp0->deleteLater(); - }); + if (dryMode){ + for (const auto &token : tokensToUpdate) + qInfo() << "Updating token: " << token->idToStringWithoutBraces() << "to Colnod"; + } + else { + Response* resp0 = reqMan->setTokens(tokensToUpdate); + connect(resp0, &Response::ready, [=](){ + updateFinished = true; + areDataUpdatedToColnod(); + resp0->deleteLater(); + }); + + } } // delete tokens in Colnod void ColnodAPI::syncDeletedDataFromDBToColnod() { + dataMan->filterTokensDB(); auto tokensToDelete = dataMan->getTokensToDeleteDB(); Response* resp1 = reqMan->deleteTokens(tokensToDelete); connect(resp1, &Response::ready, [=](){ diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index ba7a19a..264320e 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -9,7 +9,7 @@ class ColnodAPI : public QObject public: - ColnodAPI(bool debugMode = false); + ColnodAPI(bool dryMode = false); void syncDataFromColnodToDB(); void syncDataFromDBToColnod(); @@ -47,7 +47,7 @@ private: private: RequestManager* reqMan = nullptr; DataManager* dataMan = nullptr; - bool debugMode = false; + bool dryMode = false; bool updateFinished = false; bool deleteFinished = false; }; diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index b724328..4d1f248 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -1,27 +1,22 @@ #include "databasemanager.h" -DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password) +DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode) { - db = QSqlDatabase::addDatabase("QPSQL"); - db.setDatabaseName(dbName); db.setHostName(host); - db.setUserName(user); - // home-office stuff - //db.setPort(80); - // + db.setUserName(user); // home-office stuff -->> db.setPort(80); db.setPassword(password); - if (!db.open()) { qDebug() << "Opening error" + db.lastError().text(); } query = QSqlQuery("query", db); + this->dryMode = dryMode; } // add or update subject to db -void DatabaseManager::saveSubject(Subject* subject, const QString& table) +int DatabaseManager::saveSubject(Subject* subject, const QString& table) { QString id = subject->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -34,6 +29,7 @@ void DatabaseManager::saveSubject(Subject* subject, const QString& table) query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":pin", subject->getPin()); executeQuery(query); + return -1; } else { @@ -45,11 +41,12 @@ void DatabaseManager::saveSubject(Subject* subject, const QString& table) query.bindValue(":name", subject->getName()); query.bindValue(":pin", subject->getPin()); executeQuery(query); + return 1; } } // add or update token to DB -void DatabaseManager::saveToken(Token* token, const QString& table) +int DatabaseManager::saveToken(Token* token, const QString& table) { QString id = token->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -70,6 +67,7 @@ void DatabaseManager::saveToken(Token* token, const QString& table) query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":deleted", token->getDeleted()); executeQuery(query); + return -1; } else { @@ -90,6 +88,7 @@ void DatabaseManager::saveToken(Token* token, const QString& table) query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); query.bindValue(":deleted", token->getDeleted()); executeQuery(query); + return 1; } } @@ -140,29 +139,60 @@ bool DatabaseManager::checkIfExists(const QString& id, const QString& table) return query.value(0).toBool(); } +QString DatabaseManager::getLastQuery(const QSqlQuery& query) const +{ + QString str = query.lastQuery(); + QMapIterator it(query.boundValues()); + while (it.hasNext()) + { + it.next(); + str.replace(it.key(),it.value().toString()); + } + return str; +} + +void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) const +{ + if (dryMode){ + if (statement.contains("SELECT")) + query.exec(statement); + } + else{ + query.exec(statement); + } + +} + bool DatabaseManager::executeQuery(QSqlQuery &query) const { - bool res = query.exec(); - return res; - + if (dryMode){ + QString sqlStatement = getLastQuery(query); + qDebug() << sqlStatement; + if (sqlStatement.contains("SELECT")) + query.exec(); + return true; + } + else{ + bool res = query.exec(); + return res; + } } void DatabaseManager::dropTables() { - query.exec("DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute"); + executeNonPreperedQuery("DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute", query); } // create table after deleting, it is used for full sync void DatabaseManager::createTables() { - query.exec("CREATE TABLE colnod_subject (" + executeNonPreperedQuery("CREATE TABLE colnod_subject (" "id character(36) primary key NOT NULL," "description character varying(255)," "last_update timestamp NOT NULL," "name character varying(255)," - "pin character varying(255))"); - - query.exec("CREATE TABLE colnod_token (" + "pin character varying(255))", query); + executeNonPreperedQuery("CREATE TABLE colnod_token (" "id CHAR(36) primary key NOT NULL," "auth_errors INTEGER NOT NULL," "description VARCHAR(255)," @@ -176,19 +206,18 @@ void DatabaseManager::createTables() "token_type VARCHAR(255)," "subject_id CHAR(36)," "last_modified timestamp," - "deleted BOOLEAN)"); - - query.exec("CREATE TABLE colnod_subject_attribute (" + "deleted BOOLEAN)", query); + executeNonPreperedQuery("CREATE TABLE colnod_subject_attribute (" "id VARCHAR(255) primary key," "attribute_key VARCHAR(255)," "attribute_value VARCHAR(255)," - "subject_id CHAR(36))"); + "subject_id CHAR(36))", query); } // return last_sync time quint64 DatabaseManager::getLastSync() { - query.exec("SELECT last_sync FROM config"); + executeNonPreperedQuery("SELECT last_sync FROM config", query); query.next(); quint64 temp = query.value(0).toULongLong(); return temp; @@ -207,18 +236,18 @@ void DatabaseManager::updateLastSync(quint64 lastSync) QSqlQuery* DatabaseManager::getUpdatedTokens() { QSqlQuery* qry = new QSqlQuery; - qry->exec("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " - "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000"); + executeNonPreperedQuery("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000", *qry); return qry; } QSqlQuery* DatabaseManager::getToken(const QString& id) { QSqlQuery* qry = new QSqlQuery; - qry->prepare("SELECT SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + qry->prepare("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " "FROM colnod_token WHERE id = :id"); qry->bindValue(":id", id); - qry->exec(); + executeQuery(*qry); if (qry->next()){ return qry; } @@ -227,7 +256,7 @@ QSqlQuery* DatabaseManager::getToken(const QString& id) quint64 DatabaseManager::getNow() { - query.exec("SELECT EXTRACT(EPOCH FROM NOW())*1000"); + executeNonPreperedQuery("SELECT EXTRACT(EPOCH FROM NOW())*1000", query); query.next(); return query.value(0).toULongLong(); } diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 2ad7faf..84a654d 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -16,10 +16,10 @@ class DatabaseManager : public QObject { Q_OBJECT public: - DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password); + DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false); - void saveSubject(Subject* subject, const QString& table); - void saveToken(Token* token, const QString& table); + int saveSubject(Subject* subject, const QString& table); + int saveToken(Token* token, const QString& table); void saveSubjectAttributes(Subject* subject, const QString& table); void setDeleted(const QString& id, const QString& table); @@ -38,8 +38,11 @@ public: private: bool checkIfExists(const QString& id, const QString& table); bool executeQuery(QSqlQuery &query) const; + QString getLastQuery(const QSqlQuery &query) const; + void executeNonPreperedQuery(const QString &statement, QSqlQuery& query) const; private: QSqlDatabase db; QSqlQuery query; + bool dryMode = false; }; diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 66995c9..bd221f2 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -1,11 +1,11 @@ #include "datamanager.h" -DataManager::DataManager() +DataManager::DataManager(const bool &dryMode) { - db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12"); + db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode); nextLastSync = db->getNow(); lastSync = db->getLastSync(); - qDebug() << lastSync; + this->dryMode = dryMode; //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); } @@ -25,6 +25,7 @@ void DataManager::fillFullTokensColnod(const QString& response) } else { + qCritical() << "Colnod is Empty"; auto token = new Token("empty"); allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } @@ -44,11 +45,13 @@ void DataManager::fillTokensToUpdateColnod(const QString& response) token->setDeleted(false); tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); } + qInfo() << tokensToUpdateFromColnodToDB.size() << " tokens to update from Colnod"; } else { + qInfo() << "0 tokens to update from Colnod"; auto token = new Token("empty"); - tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateFromColnodToDB.insert(token->getName(), token); } } @@ -65,16 +68,18 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) subject->fromJSON(item.toObject()); subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } + qInfo() << subjectsToUpdateFromColnodToDB.size() << " subjects to update from Colnod"; } else { + qInfo() << "0 subjects to update from Colnod"; Subject* subject = new Subject("empty"); - subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); + subjectsToUpdateFromColnodToDB.insert(subject->getName(), subject); } } // load working sets with updated/deleted tokens from DB -void DataManager::fillTokensToUpdateDB() +void DataManager::fillTokensToChangeDB() { QSqlQuery* query = db->getUpdatedTokens(); while (query->next()) @@ -88,8 +93,8 @@ void DataManager::fillTokensToUpdateDB() tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); } } - qDebug() << "Number of tokens to update from DB: "<< tokensToUpdateFromDBToColnod.size(); - qDebug() << "Number of tokens to delete from DB: "<< tokensFromDBToDeleteFromColnod.size(); + qDebug() << tokensToUpdateFromDBToColnod.size() << " tokens to update from DB"; + qDebug() << tokensFromDBToDeleteFromColnod.size() << " tokens to delete from DB"; } void DataManager::fillSubjectsToUpdateDB() @@ -107,13 +112,15 @@ void DataManager::fillSubjectsToDeleteColnod(const QString& json) for (QJsonValueRef item : items) { subjectsFromColnodToDeleteFromDB.append(item.toString()); } + qInfo() << subjectsFromColnodToDeleteFromDB.size() << " subjects deleted in Colnod"; } else { + qInfo() << "0 subjects deleted in Colnod"; subjectsFromColnodToDeleteFromDB.append("empty"); } } -// load working set with tokenst to delete from colnod +// load working set with tokens to delete from colnod void DataManager::fillTokensToDeleteColnod(const QString& json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); @@ -123,8 +130,10 @@ void DataManager::fillTokensToDeleteColnod(const QString& json) for (QJsonValueRef item : items) { tokensFromColnodToDeleteFromDB.append(item.toString()); } + qInfo() << tokensFromColnodToDeleteFromDB.size() << " tokens deleted in Colnod"; } else { + qInfo() << "0 tokens deleted in Colnod"; tokensFromColnodToDeleteFromDB.append("empty"); } } @@ -138,52 +147,54 @@ void DataManager::fillSubjectsToDeleteDB() void DataManager::pushSubjectsToDB() { if (subjectsToUpdateFromColnodToDB.contains("empty")) { - qDebug() << "All subjects are up to date"; return; } - //QSqlDatabase::database().transaction(); - qDebug() << "Subjects in progress..."; + int updated = 0, added = 0; + qInfo() << "Subjects in progress..."; for (const auto& subject : subjectsToUpdateFromColnodToDB) { - db->saveSubject(subject, "colnod_subject"); + if (db->saveSubject(subject, "colnod_subject") > 0) + added++; + else + updated++; db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } - //QSqlDatabase::database().commit(); - qDebug() << subjectsToUpdateFromColnodToDB.size() << " subjects has been updated"; - + qInfo() << added << " subjects added to DB"; + qInfo() << updated << " subjects updated to DB"; } // update tokens from colnod to DB void DataManager::pushTokensToDB() { - if (tokensToUpdateFromColnodToDB.contains("empty")) - { - qDebug() << "All tokens are up to date"; + if (tokensToUpdateFromColnodToDB.contains("empty")){ return; } - //QSqlDatabase::database().transaction(); - qDebug() << "Tokens in progress..."; + filterTokensColnod(); + int updated = 0, added = 0; + qInfo() << "Tokens in progress..."; for (const auto& token : tokensToUpdateFromColnodToDB) { - db->saveToken(token, "colnod_token"); + if (db->saveToken(token, "colnod_token") > 0) + added++; + else + updated++; } - //QSqlDatabase::database().commit(); - qDebug() << tokensToUpdateFromColnodToDB.size() << " tokens has been updated"; + qInfo() << added << " tokens added to DB"; + qInfo() << updated << " tokens updated to DB"; } void DataManager::deleteSubjectsFromDB() { if (subjectsFromColnodToDeleteFromDB[0] == "empty") { - qDebug() << "No subjects to be deleted"; return; } - qDebug() << "Deleted subjects in progress..."; + qInfo() << "Deleting subjects in progress..."; for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { db->setDeleted(subjectId, "colnod_subject"); } - qDebug() << subjectsFromColnodToDeleteFromDB.size() << "subject has beed deleted"; + qInfo() << subjectsFromColnodToDeleteFromDB.size() << " subject deleted from DB"; } // "delete" (set deleted true) tokens in DB depends on Colnod @@ -191,7 +202,7 @@ void DataManager::setDeletedToTokensFromDB() { if (tokensFromColnodToDeleteFromDB[0] == "empty") { - qDebug() << "No tokens to be deleted"; + qDebug() << "0 tokens to be deleted"; return; } qDebug() << "Deleted tokens in progress..."; @@ -199,7 +210,7 @@ void DataManager::setDeletedToTokensFromDB() { db->setDeleted(tokenId, "colnod_token"); } - qDebug() << tokensFromColnodToDeleteFromDB.size() << "tokens has beed deleted"; + qDebug() << tokensFromColnodToDeleteFromDB.size() << "tokens deleted from DB"; } // do I have loaded all data @@ -262,6 +273,7 @@ void DataManager::filterTokensColnod() auto tokenDB = new Token; tokenDB->fromSQLRecord(record); Q_ASSERT(tokenDB != token); + qDebug() << tokenDB->getLastModified() << " > " << token->getLastUpdate(); if (tokenDB > token) tokensToUpdateFromColnodToDB.remove(id); } diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 3420b07..2824ed8 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -14,7 +14,7 @@ class DataManager : public QObject Q_OBJECT public: - DataManager(); + DataManager(const bool& dryMode = false); void fillFullTokensColnod(const QString& jsonResponse); @@ -23,7 +23,7 @@ public: void fillSubjectsToDeleteColnod(const QString& jsonResponse); void fillTokensToDeleteColnod(const QString& jsonResponse); - void fillTokensToUpdateDB(); + void fillTokensToChangeDB(); void fillSubjectsToUpdateDB(); void fillSubjectsToDeleteDB(); @@ -71,4 +71,6 @@ private: QList subjectsToDeleteDB; QList tokensFromDBToDeleteFromColnod; + bool dryMode = false; + }; diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 39f9b48..b17ad74 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -60,7 +60,7 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA reply->deleteLater(); return; } - qDebug() << "Authorized successfully, response ready."; + //qDebug() << "Authorized successfully, response ready."; emit responseReady(); reply->deleteLater(); }); diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index f92f113..c5ef386 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -4,7 +4,7 @@ #include -Subject::Subject(const QString& name) +Subject::Subject(const QString &name) { setName(name); } diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 7043c41..32315ce 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -17,7 +17,7 @@ Token::Token(const QString& name, QString tokenData, const QString& decription) } -Token::Token(const QString& name) +Token::Token(const QString &name) { this->setName(name); } @@ -67,14 +67,16 @@ void Token::fromSQLRecord(QSqlQuery *query) if (query->value(3).toBool()) flags.insert("Enabled"); this->flags = flags; - setLastUpdate(query->value(4).toUInt()); + QDateTime date = query->value(4).toDateTime(); + setLastUpdate(date.toMSecsSinceEpoch()); setName(query->value(5).toString()); timeToLive = query->value(7).toInt(); tokenBits = query->value(8).toInt(); tokenData = query->value(9).toString(); tokenType = query->value(10).toString(); subjectId = query->value(11).toUuid(); - lastModified = query->value(12).toUInt(); + date = query->value(12).toDateTime(); + lastModified = date.toMSecsSinceEpoch(); deleted = query->value(13).toBool(); } diff --git a/src/colnod/token.h b/src/colnod/token.h index e98ef68..452a6f7 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include class Token : public Entity { public: @@ -13,10 +15,10 @@ public: Token(const QString& name, QString tokenData, const QString& decription = "mobile"); Token(const QString& name); - friend bool operator<(const Token &rToken, const Token &lToken){ - return rToken.getLastModified() < lToken.getLastUpdate(); + friend bool operator<(const Token &lToken, const Token &rToken){ + return lToken.getLastModified() < rToken.getLastUpdate(); } - friend bool operator>(const Token &rToken, const Token &lToken){ + friend bool operator>(const Token &lToken, const Token &rToken){ return rToken.getLastModified() > lToken.getLastUpdate(); } diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index df99862..a489a1d 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -12,7 +12,7 @@ void ComplexTest::initTestCase() deleteTokensRespSpy.wait(timeout); QTest::qWait(2500); start = QDateTime::currentMSecsSinceEpoch()-2000; - api = new ColnodAPI; + api = new ColnodAPI(true); qDebug() << start; } @@ -117,8 +117,13 @@ void ComplexTest::fullSync() api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(timeout); + api->loadDataFromDB(); api->syncDataFromColnodToDB(); - // api->syncDataToColnod(); + api->syncDataFromDBToColnod(); + QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod); + processSpy.wait(timeout); + QSignalSpy finish(api, &ColnodAPI::syncFinished); + finish.wait(timeout); } void ComplexTest::syncLastUpdated() From a55a6f6b93d981b219424dff45bcf63d0fd58dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 29 Oct 2019 15:59:21 +0100 Subject: [PATCH 10/23] Add logger class --- src/app/main.cpp | 3 ++- src/colnod/colnod.pri | 2 ++ src/colnod/colnodapi.h | 1 + src/colnod/databasemanager.cpp | 24 +++++++++++------ src/colnod/databasemanager.h | 3 +++ src/colnod/datamanager.cpp | 23 ++++++++++------- src/colnod/datamanager.h | 1 + src/colnod/entity.cpp | 16 ++++++------ src/colnod/logger.cpp | 33 ++++++++++++++++++++++++ src/colnod/logger.h | 28 ++++++++++++++++++++ src/colnod/requestmanager.h | 3 ++- src/colnod/subject.cpp | 16 ++++++------ src/colnod/token.cpp | 47 ++++++++++------------------------ src/colnod/token.h | 8 +----- test/unitTests/complextest.cpp | 47 ++++++++++++++++++---------------- test/unitTests/complextest.h | 1 + 16 files changed, 159 insertions(+), 97 deletions(-) create mode 100644 src/colnod/logger.cpp create mode 100644 src/colnod/logger.h diff --git a/src/app/main.cpp b/src/app/main.cpp index 62ab6ea..10a4150 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -10,8 +10,9 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("colnod-connector"); QCoreApplication::setApplicationVersion("1.0"); QCommandLineParser parser; + Logger *logger = Logger::getLogger(); parser.setApplicationDescription("Dry mode"); - QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which normally be doing"); + QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made"); parser.addOption(dryModeOption); parser.process(app); auto *api = new ColnodAPI(true); // parser.isSet(dryModeOption)); diff --git a/src/colnod/colnod.pri b/src/colnod/colnod.pri index 51c711d..d9e86e2 100644 --- a/src/colnod/colnod.pri +++ b/src/colnod/colnod.pri @@ -6,6 +6,7 @@ SOURCES += \ $$PWD/databasemanager.cpp \ $$PWD/datamanager.cpp \ $$PWD/entity.cpp \ + $$PWD/logger.cpp \ $$PWD/requestmanager.cpp \ $$PWD/response.cpp \ $$PWD/subject.cpp \ @@ -16,6 +17,7 @@ HEADERS += \ $$PWD/databasemanager.h \ $$PWD/datamanager.h \ $$PWD/entity.h \ + $$PWD/logger.h \ $$PWD/requestmanager.h \ $$PWD/response.h \ $$PWD/subject.h \ diff --git a/src/colnod/colnodapi.h b/src/colnod/colnodapi.h index 264320e..c287b6b 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/colnodapi.h @@ -2,6 +2,7 @@ #include "requestmanager.h" #include "datamanager.h" +#include "logger.h" class ColnodAPI : public QObject { diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 4d1f248..27a54d4 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -31,8 +31,8 @@ int DatabaseManager::saveSubject(Subject* subject, const QString& table) executeQuery(query); return -1; } - else - { + + query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin) " "VALUES (:id, :description, :last_update, :name, :pin)").arg(table)); query.bindValue(":id", id); @@ -42,7 +42,7 @@ int DatabaseManager::saveSubject(Subject* subject, const QString& table) query.bindValue(":pin", subject->getPin()); executeQuery(query); return 1; - } + } // add or update token to DB @@ -69,8 +69,8 @@ int DatabaseManager::saveToken(Token* token, const QString& table) executeQuery(query); return -1; } - else - { + + query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) " "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table)); query.bindValue(":id", id); @@ -89,7 +89,7 @@ int DatabaseManager::saveToken(Token* token, const QString& table) query.bindValue(":deleted", token->getDeleted()); executeQuery(query); return 1; - } + } // add of update subject attributes @@ -172,10 +172,10 @@ bool DatabaseManager::executeQuery(QSqlQuery &query) const query.exec(); return true; } - else{ + bool res = query.exec(); return res; - } + } void DatabaseManager::dropTables() @@ -270,3 +270,11 @@ void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) executeQuery(query); } +void DatabaseManager::log(QString msg) +{ + query.prepare("INSERT INTO logs (msg) VALUES (:msg)"); + query.bindValue(":msg", msg); + query.exec(); + //executeQuery(query); +} + diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 84a654d..2e4ddb6 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -10,6 +10,7 @@ #include "subject.h" #include "token.h" #include +//#include "logger.h" class DatabaseManager : public QObject @@ -35,6 +36,8 @@ public: void setLastUpdate(const QString& id, quint64 lastUpdate); + void log(QString msg); + private: bool checkIfExists(const QString& id, const QString& table); bool executeQuery(QSqlQuery &query) const; diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index bd221f2..e758a1d 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -3,10 +3,11 @@ DataManager::DataManager(const bool &dryMode) { db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode); + //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); + Logger::setDBMan(db); nextLastSync = db->getNow(); lastSync = db->getLastSync(); this->dryMode = dryMode; - //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); } // load all tokens from colnod to comparing with working set from DB @@ -105,6 +106,8 @@ void DataManager::fillSubjectsToUpdateDB() // load working set with subjest to delete from Colnod void DataManager::fillSubjectsToDeleteColnod(const QString& json) { + Logger::log("hello from dataManager :)"); + Logger::logToDb("testing"); QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); if (!items.empty()) @@ -120,7 +123,7 @@ void DataManager::fillSubjectsToDeleteColnod(const QString& json) } } -// load working set with tokens to delete from colnod +// load working set with tokens to delete from DB void DataManager::fillTokensToDeleteColnod(const QString& json) { QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); @@ -149,7 +152,8 @@ void DataManager::pushSubjectsToDB() if (subjectsToUpdateFromColnodToDB.contains("empty")) { return; } - int updated = 0, added = 0; + int updated = 0; + int added = 0; qInfo() << "Subjects in progress..."; for (const auto& subject : subjectsToUpdateFromColnodToDB) { @@ -170,7 +174,8 @@ void DataManager::pushTokensToDB() return; } filterTokensColnod(); - int updated = 0, added = 0; + int updated = 0; + int added = 0; qInfo() << "Tokens in progress..."; for (const auto& token : tokensToUpdateFromColnodToDB) { @@ -181,6 +186,7 @@ void DataManager::pushTokensToDB() } qInfo() << added << " tokens added to DB"; qInfo() << updated << " tokens updated to DB"; + } void DataManager::deleteSubjectsFromDB() @@ -253,11 +259,11 @@ void DataManager::updateLastSync() // these to filter functions solve colision tokens -> remove when change on this token is earlier then change on the same token on the other side (Colnod/DB) void DataManager::filterTokensDB() { - for (auto token : tokensToUpdateFromDBToColnod) + for (const auto& token : tokensToUpdateFromDBToColnod) { QString id = token->idToStringWithoutBraces(); - Q_ASSERT(token = allTokensFromColnod.value(id)); // if working sets are loading correctly equels should never happend - if (allTokensFromColnod.contains(id) && token < allTokensFromColnod.value(id)) + Q_ASSERT(token != allTokensFromColnod.value(id)); // if working sets are loading correctly equels should never happend + if (allTokensFromColnod.contains(id) && *token < *allTokensFromColnod.value(id)) tokensToUpdateFromDBToColnod.remove(id); } } @@ -273,8 +279,7 @@ void DataManager::filterTokensColnod() auto tokenDB = new Token; tokenDB->fromSQLRecord(record); Q_ASSERT(tokenDB != token); - qDebug() << tokenDB->getLastModified() << " > " << token->getLastUpdate(); - if (tokenDB > token) + if (*tokenDB > *token) tokensToUpdateFromColnodToDB.remove(id); } } diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 2824ed8..7c036d1 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -6,6 +6,7 @@ #include "databasemanager.h" #include #include +#include class DataManager : public QObject diff --git a/src/colnod/entity.cpp b/src/colnod/entity.cpp index d1d93cb..fcae765 100644 --- a/src/colnod/entity.cpp +++ b/src/colnod/entity.cpp @@ -40,19 +40,19 @@ QString Entity::idToStringWithoutBraces() const } void Entity::fromJSON(const QJsonObject &json) { - id = json.value("id").toString(); - name = json.value("name").toString(); - description = json.value("description").toString(); - lastUpdate = json.value("lastUpdate").toDouble(); + id = json["id"].toString(); + name = json["name"].toString(); + description = json["description"].toString(); + lastUpdate = json["lastUpdate"].toDouble(); } QJsonObject Entity::toJSON() const { QJsonObject json; - json.value("id") = this->idToStringWithoutBraces(); - json.value("name") = name; - json.value("description") = description; - json.value("lastUpdate") = lastUpdate; + json["id"] = this->idToStringWithoutBraces(); + json["name"] = name; + json["description"] = description; + json["lastUpdate"] = lastUpdate; return json; } diff --git a/src/colnod/logger.cpp b/src/colnod/logger.cpp new file mode 100644 index 0000000..431897d --- /dev/null +++ b/src/colnod/logger.cpp @@ -0,0 +1,33 @@ +#include "logger.h" + +Logger::Logger() +{ + dbMan = nullptr; +} + +Logger *Logger::getLogger() +{ + if (!logger) + logger = new Logger; + return logger; +} + +void Logger::log(const QString& msg) +{ + qDebug() << msg; +} + +void Logger::logToDb(const QString &msg) +{ + dbMan->log(msg); +} + +void Logger::setDBMan(DatabaseManager *dbMan) +{ + Logger::dbMan = dbMan; +} + + +Logger *Logger::logger = nullptr; +DatabaseManager *Logger::dbMan = nullptr; + diff --git a/src/colnod/logger.h b/src/colnod/logger.h new file mode 100644 index 0000000..13e8494 --- /dev/null +++ b/src/colnod/logger.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include "databasemanager.h" + + +class Logger +{ + + static Logger *logger; + + Logger(); + + static DatabaseManager *dbMan; + +public: + static Logger *getLogger(); + static void log(const QString& msg); + static void logToDb(const QString& msg); + static void setDBMan(DatabaseManager* dbMan); + + +private: + +}; + diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index 17b1bba..4d868ac 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -24,6 +24,7 @@ #include "token.h" #include "response.h" +#include "logger.h" class RequestManager : public QObject { @@ -83,7 +84,7 @@ private: QJsonDocument config; QString authHeader; QString host = "https://192.168.1.3:8443"; - // QString host = "https://localhost:8080"; + //QString host = "https://localhost:8080"; QString password = "spaceti1"; QString user = "spaceti"; diff --git a/src/colnod/subject.cpp b/src/colnod/subject.cpp index c5ef386..55e5999 100644 --- a/src/colnod/subject.cpp +++ b/src/colnod/subject.cpp @@ -16,21 +16,21 @@ QString Subject::getEmail() const { void Subject::fromJSON(const QJsonObject &json) { Entity::fromJSON(json); - attributes = json.value("attributes").toObject().value("items").toObject(); + attributes = json["attributes"].toObject()["items"].toObject(); for (const auto & attributeType : attributeTypes) { if (!attributes[attributeType].toString().isEmpty()){ atr.append(qMakePair(attributeType, attributes[attributeType].toString())); } } - const auto &tokenFlagsArray = json.value("tokenFlags").toArray(); + const auto &tokenFlagsArray = json["tokenFlags"].toArray(); for(const auto &flag : tokenFlagsArray){ tokenFlags.insert(flag.toString()); } - pin = json.value("pin").toString(); + pin = json["pin"].toString(); - const auto &pinFlagsArray = json.value("pinFlags").toArray(); + const auto &pinFlagsArray = json["pinFlags"].toArray(); for(const auto &flag : pinFlagsArray){ pinFlags.insert(flag.toString()); } @@ -41,10 +41,10 @@ QJsonObject Subject::toJSON() const { QJsonObject json = Entity::toJSON(); QJsonObject items({{"items", attributes}}); - json.value("atributes") = items; - json.value("tokenFlags") = QJsonArray::fromStringList(tokenFlags.toList()); - json.value("pin") = pin; - json.value("pinFlags") = QJsonArray::fromStringList(pinFlags.toList()); + json["atributes"] = items; + json["tokenFlags"] = QJsonArray::fromStringList(tokenFlags.toList()); + json["pin"] = pin; + json["pinFlags"] = QJsonArray::fromStringList(pinFlags.toList()); return json; } diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 32315ce..001da85 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -26,32 +26,29 @@ Token::Token(const QString &name) void Token::fromJSON(const QJsonObject &json) { Entity::fromJSON(json); - tokenType = json.value("tokenType").toString(); - tokenBits = json.value("tokenBits").toInt(); - tokenData = json.value("tokenData").toString(); - validFrom = json.value("validFrom").toDouble(); - validTo = json.value("validTo").toDouble(); - timeToLive = json.value("timeToLive").toInt(); + tokenType = json["tokenType"].toString(); + tokenBits = json["tokenBits"].toInt(); + tokenData = json["tokenData"].toString(); + timeToLive = json["timeToLive"].toInt(); authErrors = json["authErrors"].toInt(); const auto &flagsArray = json["flags"].toArray(); for(const auto &flag : flagsArray){ flags.insert(flag.toString()); } - subjectId = json.value("subjectId").toString(); + subjectId = json["subjectId"].toString(); } QJsonObject Token::toJSON() const { QJsonObject json = Entity::toJSON(); - - json.value("tokenType") = tokenType; - json.value("tokenBits") = tokenBits; - json.value("tokenData") = tokenData; - json.value("validFrom") = validFrom; - json.value("validTo") = validTo; - json.value("timeToLive") = timeToLive; - json.value("authErrors") = authErrors; - json.value("flags") = QJsonArray::fromStringList(flags.toList()); - json.value("subjectId") = subjectId.toString().mid(1,36); + json.insert("tokenType", tokenType); + json["tokenBits"] = tokenBits; + json["tokenType"] = tokenType; + json["tokenBits"] = tokenBits; + json["tokenData"] = tokenData; + json["timeToLive"] = timeToLive; + json["authErrors"] = authErrors; + json["flags"] = QJsonArray::fromStringList(flags.toList()); + json["subjectId"] = subjectId.toString().mid(1,36); return json; } @@ -104,22 +101,6 @@ void Token::setTokenData(const QString &tokenData) { Token::tokenData = tokenData; } -quint64 Token::getValidFrom() const { - return validFrom; -} - -void Token::setValidFrom(quint64 validFrom) { - Token::validFrom = validFrom; -} - -quint64 Token::getValidTo() const { - return validTo; -} - -void Token::setValidTo(quint64 validTo) { - Token::validTo = validTo; -} - int Token::getTimeToLive() const { return timeToLive; } diff --git a/src/colnod/token.h b/src/colnod/token.h index 452a6f7..fe6b665 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -19,7 +19,7 @@ public: return lToken.getLastModified() < rToken.getLastUpdate(); } friend bool operator>(const Token &lToken, const Token &rToken){ - return rToken.getLastModified() > lToken.getLastUpdate(); + return lToken.getLastModified() > rToken.getLastUpdate(); } const QString &getTokenType() const; @@ -28,10 +28,6 @@ public: void setTokenBits(int tokenBits); const QString &getTokenData() const; void setTokenData(const QString &tokenData); - quint64 getValidFrom() const; - void setValidFrom(quint64 validFrom); - quint64 getValidTo() const; - void setValidTo(quint64 validTo); int getTimeToLive() const; void setTimeToLive(int timeToLive); int getAuthErrors() const; @@ -55,8 +51,6 @@ private: QString tokenType; int tokenBits{}; QString tokenData; - qint64 validFrom{}; - qint64 validTo{}; int timeToLive{}; int authErrors{}; QSet flags; diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index a489a1d..0bd7616 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -2,32 +2,33 @@ void ComplexTest::initTestCase() { - auto reqMan1 = new RequestManager; - QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); - Response* deleteTokensResp = reqMan1->deleteTokens(ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(timeout); - QTest::qWait(2500); +// auto reqMan1 = new RequestManager; +// QList ids; +// ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); +// ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); +// Response* deleteTokensResp = reqMan1->deleteTokens(ids); +// QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); +// QCOMPARE(deleteTokensRespSpy.count(), 0); +// deleteTokensRespSpy.wait(timeout); +// QTest::qWait(2500); start = QDateTime::currentMSecsSinceEpoch()-2000; - api = new ColnodAPI(true); + api = new ColnodAPI(); qDebug() << start; + } void ComplexTest::cleanupTestCase() { - QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); - auto reqMan = new RequestManager; - Response* deleteTokensResp = reqMan->deleteTokens(ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(timeout); - QCOMPARE(deleteTokensRespSpy.count(), 1); +// QList ids; +// ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); +// ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); +// auto reqMan = new RequestManager; +// Response* deleteTokensResp = reqMan->deleteTokens(ids); +// QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); +// QCOMPARE(deleteTokensRespSpy.count(), 0); +// deleteTokensRespSpy.wait(timeout); +// QCOMPARE(deleteTokensRespSpy.count(), 1); } void ComplexTest::complexTest() @@ -82,7 +83,7 @@ void ComplexTest::complexTest() // DELETE_TOKENS_CHECK_BEGIN QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); + ids.append("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); Response* deleteTokensResp = reqMan->deleteTokens(ids); QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); QCOMPARE(deleteTokensRespSpy.count(), 0); @@ -101,7 +102,7 @@ void ComplexTest::complexTest() QCOMPARE(getTokensDeletedRespSpy.count(), 1); auto doc2 = getJsonDoc(getTokensDeletedResp->getJson()); QCOMPARE(doc2.object()["items"].toArray().size(), 1); - QVERIFY(doc2.object()["items"].toArray().contains("582c982d-6fd7-4856-8548-7ce542791c7a")); + QVERIFY(doc2.object()["items"].toArray().contains("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9")); // CHECK_DELETED_TOKENS_END // LAST_TESTS (for sure) @@ -128,6 +129,8 @@ void ComplexTest::fullSync() void ComplexTest::syncLastUpdated() { + Logger *logger = Logger::getLogger(); + Logger::log("ahoj"); api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); spy.wait(timeout); @@ -175,7 +178,7 @@ QJsonDocument ComplexTest::getJsonDoc(const QString &json) QPointer ComplexTest::getTestToken() { QJsonObject jsonToken; - jsonToken.insert("id", "582c982d-6fd7-4856-8548-7ce542791c7a"); + jsonToken.insert("id", "062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); jsonToken.insert("name", "test"); jsonToken.insert("description", "mobile"); jsonToken.insert("tokenType", "Token"); diff --git a/test/unitTests/complextest.h b/test/unitTests/complextest.h index 0aa1c74..a887cab 100644 --- a/test/unitTests/complextest.h +++ b/test/unitTests/complextest.h @@ -6,6 +6,7 @@ #include "response.h" #include "requestmanager.h" #include "colnodapi.h" +#include "logger.h" class ComplexTest : public QObject { From ba1315d1da63b6f1d699b442293e85f6f70a5bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 30 Oct 2019 13:59:41 +0100 Subject: [PATCH 11/23] Working on logs --- src/app/main.cpp | 5 ++-- src/colnod/colnodapi.cpp | 19 +++++++----- src/colnod/databasemanager.cpp | 29 ++++++++++++++---- src/colnod/databasemanager.h | 5 +++- src/colnod/datamanager.cpp | 55 ++++++++++++++++++---------------- src/colnod/logger.cpp | 15 ++++++++-- src/colnod/logger.h | 2 ++ src/colnod/requestmanager.cpp | 2 +- test/unitTests/complextest.cpp | 2 +- 9 files changed, 88 insertions(+), 46 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 10a4150..112dc39 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -11,15 +11,14 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationVersion("1.0"); QCommandLineParser parser; Logger *logger = Logger::getLogger(); - parser.setApplicationDescription("Dry mode"); + parser.setApplicationDescription("Colnod sync"); QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made"); parser.addOption(dryModeOption); parser.process(app); - auto *api = new ColnodAPI(true); // parser.isSet(dryModeOption)); + auto *api = new ColnodAPI(parser.isSet(dryModeOption)); api->loadDataFromDB(); api->loadDataFromColnod(); QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ - qDebug() << "All items are loaded to data manager."; api->syncDataFromColnodToDB(); api->syncDataFromDBToColnod(); QObject::connect(api, &ColnodAPI::syncFinished, [=](){ diff --git a/src/colnod/colnodapi.cpp b/src/colnod/colnodapi.cpp index c6a4add..4fbdbeb 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/colnodapi.cpp @@ -135,7 +135,6 @@ void ColnodAPI::syncUpdatedDataFromDBToColnod() areDataUpdatedToColnod(); resp0->deleteLater(); }); - } } @@ -144,12 +143,18 @@ void ColnodAPI::syncDeletedDataFromDBToColnod() { dataMan->filterTokensDB(); auto tokensToDelete = dataMan->getTokensToDeleteDB(); - Response* resp1 = reqMan->deleteTokens(tokensToDelete); - connect(resp1, &Response::ready, [=](){ - deleteFinished = true; - areDataUpdatedToColnod(); - resp1->deleteLater(); - }); + if (dryMode){ + for (const auto &token : tokensToDelete) + qInfo() << "Deleting token: " << token << "from Colnod"; + } + else { + Response* resp1 = reqMan->deleteTokens(tokensToDelete); + connect(resp1, &Response::ready, [=](){ + deleteFinished = true; + areDataUpdatedToColnod(); + resp1->deleteLater(); + }); + } } // For full sync diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 27a54d4..7b84c1f 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -154,15 +154,17 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) const { if (dryMode){ + QString sqlStatement = getLastQuery(query); + qDebug() << sqlStatement; if (statement.contains("SELECT")) query.exec(statement); } else{ query.exec(statement); } - } + bool DatabaseManager::executeQuery(QSqlQuery &query) const { if (dryMode){ @@ -172,7 +174,6 @@ bool DatabaseManager::executeQuery(QSqlQuery &query) const query.exec(); return true; } - bool res = query.exec(); return res; @@ -270,11 +271,29 @@ void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) executeQuery(query); } -void DatabaseManager::log(QString msg) +void DatabaseManager::log(const QString &msg) { - query.prepare("INSERT INTO logs (msg) VALUES (:msg)"); + query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)"); query.bindValue(":msg", msg); query.exec(); - //executeQuery(query); } +QString DatabaseManager::getSubjectName(const QString &tokenId) +{ + query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)"); + query.bindValue(":tokenId", tokenId); + executeQuery(query); + if (query.next()) + return query.value(0).toString(); + qWarning() << "Token:" << tokenId << "is not assigned to any sbject"; + return "No Subject"; +} + +bool DatabaseManager::checkDeletedToken(const QString &id) +{ + query.prepare("SELECT deleted FROM colnod_token WHERE id = :id"); + query.bindValue(":id", id); + executeQuery(query); + query.next(); + return query.value(0).toBool(); +} diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 2e4ddb6..54e0771 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -36,7 +36,10 @@ public: void setLastUpdate(const QString& id, quint64 lastUpdate); - void log(QString msg); + void log(const QString &msg); + QString getSubjectName(const QString &tokenId); + bool checkDeletedToken(const QString &id); + private: bool checkIfExists(const QString& id, const QString& table); diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index e758a1d..06fa344 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -46,11 +46,11 @@ void DataManager::fillTokensToUpdateColnod(const QString& response) token->setDeleted(false); tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); } - qInfo() << tokensToUpdateFromColnodToDB.size() << " tokens to update from Colnod"; + qInfo() << "Colnod:" << tokensToUpdateFromColnodToDB.size() << "tokens to update"; } else { - qInfo() << "0 tokens to update from Colnod"; + qInfo() << "Colnod: 0 tokens to update"; auto token = new Token("empty"); tokensToUpdateFromColnodToDB.insert(token->getName(), token); } @@ -69,11 +69,11 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) subject->fromJSON(item.toObject()); subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } - qInfo() << subjectsToUpdateFromColnodToDB.size() << " subjects to update from Colnod"; + qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update"; } else { - qInfo() << "0 subjects to update from Colnod"; + qInfo() << "Colnod:" << "0 subjects to update"; Subject* subject = new Subject("empty"); subjectsToUpdateFromColnodToDB.insert(subject->getName(), subject); } @@ -94,8 +94,8 @@ void DataManager::fillTokensToChangeDB() tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); } } - qDebug() << tokensToUpdateFromDBToColnod.size() << " tokens to update from DB"; - qDebug() << tokensFromDBToDeleteFromColnod.size() << " tokens to delete from DB"; + qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update"; + qDebug() << "DB:" << tokensFromDBToDeleteFromColnod.size() << "tokens to delete"; } void DataManager::fillSubjectsToUpdateDB() @@ -106,8 +106,6 @@ void DataManager::fillSubjectsToUpdateDB() // load working set with subjest to delete from Colnod void DataManager::fillSubjectsToDeleteColnod(const QString& json) { - Logger::log("hello from dataManager :)"); - Logger::logToDb("testing"); QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QJsonArray items = doc.object()["items"].toArray(); if (!items.empty()) @@ -115,10 +113,10 @@ void DataManager::fillSubjectsToDeleteColnod(const QString& json) for (QJsonValueRef item : items) { subjectsFromColnodToDeleteFromDB.append(item.toString()); } - qInfo() << subjectsFromColnodToDeleteFromDB.size() << " subjects deleted in Colnod"; + qInfo() << "Colnod:" << subjectsFromColnodToDeleteFromDB.size() << "subjects to delete"; } else { - qInfo() << "0 subjects deleted in Colnod"; + qInfo() << "Colnod: 0 subjects to delete"; subjectsFromColnodToDeleteFromDB.append("empty"); } } @@ -133,10 +131,10 @@ void DataManager::fillTokensToDeleteColnod(const QString& json) for (QJsonValueRef item : items) { tokensFromColnodToDeleteFromDB.append(item.toString()); } - qInfo() << tokensFromColnodToDeleteFromDB.size() << " tokens deleted in Colnod"; + qInfo() << "Colnod:" << tokensFromColnodToDeleteFromDB.size() << "tokens to delete"; } else { - qInfo() << "0 tokens deleted in Colnod"; + qInfo() << "Colnod: 0 tokens to delete"; tokensFromColnodToDeleteFromDB.append("empty"); } } @@ -150,11 +148,12 @@ void DataManager::fillSubjectsToDeleteDB() void DataManager::pushSubjectsToDB() { if (subjectsToUpdateFromColnodToDB.contains("empty")) { + qInfo() << "DB: 0 subjects added"; + qInfo() << "DB: 0 subjects updated"; return; } int updated = 0; int added = 0; - qInfo() << "Subjects in progress..."; for (const auto& subject : subjectsToUpdateFromColnodToDB) { if (db->saveSubject(subject, "colnod_subject") > 0) @@ -163,20 +162,21 @@ void DataManager::pushSubjectsToDB() updated++; db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } - qInfo() << added << " subjects added to DB"; - qInfo() << updated << " subjects updated to DB"; + qInfo() << "DB:" << added << "subjects added"; + qInfo() << "DB:" << updated << "subjects updated"; } // update tokens from colnod to DB void DataManager::pushTokensToDB() { if (tokensToUpdateFromColnodToDB.contains("empty")){ + qInfo() << "DB: 0 tokens added"; + qInfo() << "DB: 0 tokens updated"; return; } filterTokensColnod(); int updated = 0; int added = 0; - qInfo() << "Tokens in progress..."; for (const auto& token : tokensToUpdateFromColnodToDB) { if (db->saveToken(token, "colnod_token") > 0) @@ -184,8 +184,8 @@ void DataManager::pushTokensToDB() else updated++; } - qInfo() << added << " tokens added to DB"; - qInfo() << updated << " tokens updated to DB"; + qInfo() << "DB:" << added << " tokens added"; + qInfo() << "DB:" << updated << " tokens updated"; } @@ -193,14 +193,14 @@ void DataManager::deleteSubjectsFromDB() { if (subjectsFromColnodToDeleteFromDB[0] == "empty") { + qInfo() << "DB: 0 subjects deleted"; return; } - qInfo() << "Deleting subjects in progress..."; for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { db->setDeleted(subjectId, "colnod_subject"); } - qInfo() << subjectsFromColnodToDeleteFromDB.size() << " subject deleted from DB"; + qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted"; } // "delete" (set deleted true) tokens in DB depends on Colnod @@ -208,15 +208,20 @@ void DataManager::setDeletedToTokensFromDB() { if (tokensFromColnodToDeleteFromDB[0] == "empty") { - qDebug() << "0 tokens to be deleted"; + qDebug() << "DB: 0 tokens deleted"; return; } - qDebug() << "Deleted tokens in progress..."; + int alreadyDeleted = 0; for (const auto& tokenId : tokensFromColnodToDeleteFromDB) { - db->setDeleted(tokenId, "colnod_token"); + if (!db->checkDeletedToken(tokenId)){ + db->setDeleted(tokenId, "colnod_token"); + Logger::logToDb(Logger::makeMsg(tokenId, "deleted", "DB")); + } + else + alreadyDeleted++; } - qDebug() << tokensFromColnodToDeleteFromDB.size() << "tokens deleted from DB"; + qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted"; } // do I have loaded all data @@ -284,7 +289,7 @@ void DataManager::filterTokensColnod() } } -// sync last update in colnod and DB +// sync last update from colnod to DB void DataManager::setLastUpdate() { for (const auto &token : tokensToUpdateFromColnodToDB){ diff --git a/src/colnod/logger.cpp b/src/colnod/logger.cpp index 431897d..bf9a2b9 100644 --- a/src/colnod/logger.cpp +++ b/src/colnod/logger.cpp @@ -1,5 +1,8 @@ #include "logger.h" +DatabaseManager *Logger::dbMan = nullptr; +Logger *Logger::logger = nullptr; + Logger::Logger() { dbMan = nullptr; @@ -19,7 +22,8 @@ void Logger::log(const QString& msg) void Logger::logToDb(const QString &msg) { - dbMan->log(msg); + Q_ASSERT(Logger::dbMan); + Logger::dbMan->log(msg); } void Logger::setDBMan(DatabaseManager *dbMan) @@ -27,7 +31,12 @@ void Logger::setDBMan(DatabaseManager *dbMan) Logger::dbMan = dbMan; } +QString Logger::makeMsg(const QString &tokenId, const QString &action, const QString &source) +{ + QString msg = QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectName(tokenId), action, source); + return msg; +} + + -Logger *Logger::logger = nullptr; -DatabaseManager *Logger::dbMan = nullptr; diff --git a/src/colnod/logger.h b/src/colnod/logger.h index 13e8494..06290fe 100644 --- a/src/colnod/logger.h +++ b/src/colnod/logger.h @@ -20,9 +20,11 @@ public: static void log(const QString& msg); static void logToDb(const QString& msg); static void setDBMan(DatabaseManager* dbMan); + static QString makeMsg(const QString& tokenId, const QString& action, const QString& source); private: }; + diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index b17ad74..4225213 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -35,7 +35,7 @@ Response* RequestManager::login() reply->deleteLater(); return; } - qDebug() << "Logged in successfully."; + //qDebug() << "Logged in successfully."; loginStatus = true; emit successLogin(); reply->deleteLater(); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 0bd7616..7fabed1 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -11,6 +11,7 @@ void ComplexTest::initTestCase() // QCOMPARE(deleteTokensRespSpy.count(), 0); // deleteTokensRespSpy.wait(timeout); // QTest::qWait(2500); + // Logger *logger = Logger::getLogger(); start = QDateTime::currentMSecsSinceEpoch()-2000; api = new ColnodAPI(); qDebug() << start; @@ -129,7 +130,6 @@ void ComplexTest::fullSync() void ComplexTest::syncLastUpdated() { - Logger *logger = Logger::getLogger(); Logger::log("ahoj"); api->loadDataFromColnod(); QSignalSpy spy(api, &ColnodAPI::dataDownloaded); From 31183087c266419ffe068ee957a30c850dcb8f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 30 Oct 2019 14:31:10 +0100 Subject: [PATCH 12/23] Logs to db first version --- src/app/main.cpp | 2 -- src/colnod/databasemanager.cpp | 20 +++++++++++++++----- src/colnod/databasemanager.h | 3 ++- src/colnod/datamanager.cpp | 27 +++++++++++++++++---------- src/colnod/logger.cpp | 10 ++++++++-- src/colnod/logger.h | 3 ++- 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 112dc39..0a90c76 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -25,7 +25,5 @@ int main(int argc, char *argv[]) QCoreApplication::exit(); }); }); - - return QCoreApplication::exec(); } diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 7b84c1f..74ca21d 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -156,7 +156,7 @@ void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuer if (dryMode){ QString sqlStatement = getLastQuery(query); qDebug() << sqlStatement; - if (statement.contains("SELECT")) + if (statement.startsWith("SELECT")) query.exec(statement); } else{ @@ -164,13 +164,12 @@ void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuer } } - bool DatabaseManager::executeQuery(QSqlQuery &query) const { if (dryMode){ QString sqlStatement = getLastQuery(query); qDebug() << sqlStatement; - if (sqlStatement.contains("SELECT")) + if (sqlStatement.startsWith("SELECT")) query.exec(); return true; } @@ -278,14 +277,25 @@ void DatabaseManager::log(const QString &msg) query.exec(); } -QString DatabaseManager::getSubjectName(const QString &tokenId) +QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId) { query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)"); query.bindValue(":tokenId", tokenId); executeQuery(query); if (query.next()) return query.value(0).toString(); - qWarning() << "Token:" << tokenId << "is not assigned to any sbject"; + qWarning() << "Token:" << tokenId << "is not assigned to any subject"; + return "No Subject"; +} + +QString DatabaseManager::getSubjectNameById(const QString &id) +{ + query.prepare("SELECT name FROM colnod_subject WHERE id = :id"); + query.bindValue(":id", id); + executeQuery(query); + if (query.next()) + return query.value(0).toString(); + qWarning() << "Subject:" << id << "doesn't exists"; return "No Subject"; } diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 54e0771..0e259f3 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -37,7 +37,8 @@ public: void setLastUpdate(const QString& id, quint64 lastUpdate); void log(const QString &msg); - QString getSubjectName(const QString &tokenId); + QString getSubjectNameByTokenId(const QString &tokenId); + QString getSubjectNameById(const QString &id); bool checkDeletedToken(const QString &id); diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 06fa344..355d997 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -17,15 +17,13 @@ void DataManager::fillFullTokensColnod(const QString& response) QJsonArray items = doc.object()["items"].toArray(); if (!items.empty()) { - for (QJsonValueRef item : items) - { + for (QJsonValueRef item : items){ auto token = new Token(); token->fromJSON(item.toObject()); allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } - else - { + else{ qCritical() << "Colnod is Empty"; auto token = new Token("empty"); allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); @@ -87,7 +85,7 @@ void DataManager::fillTokensToChangeDB() { auto token = new Token; token->fromSQLRecord(query); - if (token->getDeleted()){ // sort to delete and to update + if (token->getDeleted()){ // sort to delete / to update tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces()); } else{ @@ -156,10 +154,14 @@ void DataManager::pushSubjectsToDB() int added = 0; for (const auto& subject : subjectsToUpdateFromColnodToDB) { - if (db->saveSubject(subject, "colnod_subject") > 0) + if (db->saveSubject(subject, "colnod_subject") > 0){ added++; - else + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); + } + else{ updated++; + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); + } db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } qInfo() << "DB:" << added << "subjects added"; @@ -179,10 +181,14 @@ void DataManager::pushTokensToDB() int added = 0; for (const auto& token : tokensToUpdateFromColnodToDB) { - if (db->saveToken(token, "colnod_token") > 0) + if (db->saveToken(token, "colnod_token") > 0){ added++; - else + Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "added", "DB")); + } + else{ updated++; + Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "updated", "DB")); + } } qInfo() << "DB:" << added << " tokens added"; qInfo() << "DB:" << updated << " tokens updated"; @@ -199,6 +205,7 @@ void DataManager::deleteSubjectsFromDB() for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { db->setDeleted(subjectId, "colnod_subject"); + Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB")); } qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted"; } @@ -216,7 +223,7 @@ void DataManager::setDeletedToTokensFromDB() { if (!db->checkDeletedToken(tokenId)){ db->setDeleted(tokenId, "colnod_token"); - Logger::logToDb(Logger::makeMsg(tokenId, "deleted", "DB")); + Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB")); } else alreadyDeleted++; diff --git a/src/colnod/logger.cpp b/src/colnod/logger.cpp index bf9a2b9..d5d6d8b 100644 --- a/src/colnod/logger.cpp +++ b/src/colnod/logger.cpp @@ -31,9 +31,15 @@ void Logger::setDBMan(DatabaseManager *dbMan) Logger::dbMan = dbMan; } -QString Logger::makeMsg(const QString &tokenId, const QString &action, const QString &source) +QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source) { - QString msg = QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectName(tokenId), action, source); + QString msg = QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source); + return msg; +} + +QString Logger::makeSubjectMsg(const QString &subjectId, const QString &action, const QString &source) +{ + QString msg = QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source); return msg; } diff --git a/src/colnod/logger.h b/src/colnod/logger.h index 06290fe..80931ec 100644 --- a/src/colnod/logger.h +++ b/src/colnod/logger.h @@ -20,7 +20,8 @@ public: static void log(const QString& msg); static void logToDb(const QString& msg); static void setDBMan(DatabaseManager* dbMan); - static QString makeMsg(const QString& tokenId, const QString& action, const QString& source); + static QString makeTokenMsg(const QString& tokenId, const QString& action, const QString& source); + static QString makeSubjectMsg(const QString& subjectId, const QString& action, const QString& source); private: From 8d6dc6714c72947f6dc15f5b0f756f98d54ca93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 30 Oct 2019 15:59:30 +0100 Subject: [PATCH 13/23] Change time of deleting to time of sync begin --- src/colnod/databasemanager.cpp | 8 ++++---- src/colnod/databasemanager.h | 2 +- src/colnod/datamanager.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 74ca21d..787b0af 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -120,13 +120,13 @@ void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& tab } // "delete" tokens from DB -> set deleted true -void DatabaseManager::setDeleted(const QString& id, const QString& table) +void DatabaseManager::setDeleted(const QString& id, const QString& table, quint64 time) { - quint64 now = getNow(); - QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz"); + //quint64 now = getNow(); + //QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz"); query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table)); query.bindValue(":id", id); - query.bindValue(":now", nowString); + query.bindValue(":now", time); executeQuery(query); } diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 0e259f3..e3f96e3 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -22,7 +22,7 @@ public: int saveSubject(Subject* subject, const QString& table); int saveToken(Token* token, const QString& table); void saveSubjectAttributes(Subject* subject, const QString& table); - void setDeleted(const QString& id, const QString& table); + void setDeleted(const QString& id, const QString& table, quint64 time); void dropTables(); void createTables(); diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 355d997..afa882a 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -204,7 +204,7 @@ void DataManager::deleteSubjectsFromDB() } for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { - db->setDeleted(subjectId, "colnod_subject"); + db->setDeleted(subjectId, "colnod_subject", nextLastSync); Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB")); } qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted"; @@ -222,7 +222,7 @@ void DataManager::setDeletedToTokensFromDB() for (const auto& tokenId : tokensFromColnodToDeleteFromDB) { if (!db->checkDeletedToken(tokenId)){ - db->setDeleted(tokenId, "colnod_token"); + db->setDeleted(tokenId, "colnod_token", nextLastSync); Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB")); } else From 8f16ac06a6c4942a50fc9206751eb58e1578b558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 4 Nov 2019 11:07:11 +0100 Subject: [PATCH 14/23] Fix memory leaks and add error handling --- src/app/main.cpp | 20 ++++---- src/colnod/colnod.pri | 4 +- src/colnod/databasemanager.cpp | 47 +++++++++++-------- src/colnod/databasemanager.h | 13 +++-- src/colnod/datamanager.cpp | 21 +++++---- src/colnod/datamanager.h | 19 ++++---- src/colnod/entity.h | 2 + src/colnod/logger.cpp | 15 +++--- src/colnod/logger.h | 6 +-- src/colnod/requestmanager.cpp | 33 ++++++------- src/colnod/requestmanager.h | 39 ++++++++------- src/colnod/subject.h | 2 +- src/colnod/{colnodapi.cpp => syncmanager.cpp} | 45 +++++++++--------- src/colnod/{colnodapi.h => syncmanager.h} | 9 ++-- src/colnod/token.cpp | 4 ++ src/colnod/token.h | 1 + test/unitTests/UnitTest.cpp | 9 ++-- test/unitTests/complextest.cpp | 24 +++++----- test/unitTests/complextest.h | 6 +-- 19 files changed, 176 insertions(+), 143 deletions(-) rename src/colnod/{colnodapi.cpp => syncmanager.cpp} (75%) rename src/colnod/{colnodapi.h => syncmanager.h} (79%) diff --git a/src/app/main.cpp b/src/app/main.cpp index 0a90c76..3c951e3 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,7 +1,7 @@ #include #include "datamanager.h" -#include "colnodapi.h" +#include "syncmanager.h" #include int main(int argc, char *argv[]) @@ -15,15 +15,19 @@ int main(int argc, char *argv[]) QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made"); parser.addOption(dryModeOption); parser.process(app); - auto *api = new ColnodAPI(parser.isSet(dryModeOption)); - api->loadDataFromDB(); - api->loadDataFromColnod(); - QObject::connect(api, &ColnodAPI::dataDownloaded, [=](){ - api->syncDataFromColnodToDB(); - api->syncDataFromDBToColnod(); - QObject::connect(api, &ColnodAPI::syncFinished, [=](){ + SyncManager api(parser.isSet(dryModeOption)); + api.loadDataFromDB(); + api.loadDataFromColnod(); + QObject::connect(&api, &SyncManager::dataDownloaded, [&](){ + api.syncDataFromColnodToDB(); + api.syncDataFromDBToColnod(); + QObject::connect(&api, &SyncManager::syncFinished, [](){ + qDebug() << "Quit"; QCoreApplication::exit(); }); }); + QObject::connect(&api, &SyncManager::error, [](){ + QCoreApplication::exit(1); + }); return QCoreApplication::exec(); } diff --git a/src/colnod/colnod.pri b/src/colnod/colnod.pri index d9e86e2..d5cabe1 100644 --- a/src/colnod/colnod.pri +++ b/src/colnod/colnod.pri @@ -2,7 +2,6 @@ INCLUDEPATH += $$PWD #SRC_DIR = $$PWD message($$PWD) SOURCES += \ - $$PWD/colnodapi.cpp \ $$PWD/databasemanager.cpp \ $$PWD/datamanager.cpp \ $$PWD/entity.cpp \ @@ -10,10 +9,10 @@ SOURCES += \ $$PWD/requestmanager.cpp \ $$PWD/response.cpp \ $$PWD/subject.cpp \ + $$PWD/syncmanager.cpp \ $$PWD/token.cpp HEADERS += \ - $$PWD/colnodapi.h \ $$PWD/databasemanager.h \ $$PWD/datamanager.h \ $$PWD/entity.h \ @@ -21,5 +20,6 @@ HEADERS += \ $$PWD/requestmanager.h \ $$PWD/response.h \ $$PWD/subject.h \ + $$PWD/syncmanager.h \ $$PWD/token.h message($$SOURCES) diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 787b0af..7c5a158 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -9,14 +9,15 @@ DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, con db.setPassword(password); if (!db.open()) { - qDebug() << "Opening error" + db.lastError().text(); + log("Opening error" + db.lastError().text()); + emit error(); } query = QSqlQuery("query", db); this->dryMode = dryMode; } // add or update subject to db -int DatabaseManager::saveSubject(Subject* subject, const QString& table) +int DatabaseManager::saveSubject(std::shared_ptr subject, const QString& table) { QString id = subject->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -46,7 +47,7 @@ int DatabaseManager::saveSubject(Subject* subject, const QString& table) } // add or update token to DB -int DatabaseManager::saveToken(Token* token, const QString& table) +int DatabaseManager::saveToken(std::shared_ptr token, const QString& table) { QString id = token->idToStringWithoutBraces(); if (checkIfExists(id, table)) @@ -93,7 +94,7 @@ int DatabaseManager::saveToken(Token* token, const QString& table) } // add of update subject attributes -void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& table) +void DatabaseManager::saveSubjectAttributes(std::shared_ptr subject, const QString& table) { auto attributes = subject->getAtr(); for (const auto& attribute : attributes){ @@ -123,10 +124,10 @@ void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& tab void DatabaseManager::setDeleted(const QString& id, const QString& table, quint64 time) { //quint64 now = getNow(); - //QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz"); + QString nowString = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd hh:mm:ss.zzz"); query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table)); query.bindValue(":id", id); - query.bindValue(":now", time); + query.bindValue(":now", nowString); executeQuery(query); } @@ -151,31 +152,37 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const return str; } -void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) const +void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) + { if (dryMode){ QString sqlStatement = getLastQuery(query); qDebug() << sqlStatement; - if (statement.startsWith("SELECT")) - query.exec(statement); } - else{ - query.exec(statement); + if (!dryMode || statement.startsWith("SELECT")){ + if (!query.exec(statement)){ + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + log(QString(msg)); + emit error(); + } } } -bool DatabaseManager::executeQuery(QSqlQuery &query) const +bool DatabaseManager::executeQuery(QSqlQuery &query) { if (dryMode){ QString sqlStatement = getLastQuery(query); qDebug() << sqlStatement; - if (sqlStatement.startsWith("SELECT")) - query.exec(); - return true; + } - bool res = query.exec(); - return res; - + if (!dryMode || query.isSelect()){ + if (!query.exec()){ + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + log(QString(msg)); + emit error(); + } + } + return true; } void DatabaseManager::dropTables() @@ -285,7 +292,7 @@ QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId) if (query.next()) return query.value(0).toString(); qWarning() << "Token:" << tokenId << "is not assigned to any subject"; - return "No Subject"; + return "(No subject)"; } QString DatabaseManager::getSubjectNameById(const QString &id) @@ -296,7 +303,7 @@ QString DatabaseManager::getSubjectNameById(const QString &id) if (query.next()) return query.value(0).toString(); qWarning() << "Subject:" << id << "doesn't exists"; - return "No Subject"; + return "(No subject)"; } bool DatabaseManager::checkDeletedToken(const QString &id) diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index e3f96e3..6a56cb2 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -19,9 +19,9 @@ class DatabaseManager : public QObject public: DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false); - int saveSubject(Subject* subject, const QString& table); - int saveToken(Token* token, const QString& table); - void saveSubjectAttributes(Subject* subject, const QString& table); + int saveSubject(std::shared_ptr subject, const QString& table); + int saveToken(std::shared_ptr token, const QString& table); + void saveSubjectAttributes(std::shared_ptr subject, const QString& table); void setDeleted(const QString& id, const QString& table, quint64 time); void dropTables(); @@ -44,9 +44,12 @@ public: private: bool checkIfExists(const QString& id, const QString& table); - bool executeQuery(QSqlQuery &query) const; + bool executeQuery(QSqlQuery &query); QString getLastQuery(const QSqlQuery &query) const; - void executeNonPreperedQuery(const QString &statement, QSqlQuery& query) const; + void executeNonPreperedQuery(const QString &statement, QSqlQuery& query); + +signals: + void error(); private: QSqlDatabase db; diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index afa882a..bf0382a 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -2,12 +2,13 @@ DataManager::DataManager(const bool &dryMode) { - db = new DatabaseManager("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode); - //db = new DatabaseManager("localhost", "deloitte", "postgres", "34rjkciea12"); + db = std::make_shared("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode); + //db = std::make_shared("localhost", "deloitte", "postgres", "34rjkciea12"); Logger::setDBMan(db); nextLastSync = db->getNow(); lastSync = db->getLastSync(); this->dryMode = dryMode; + connect(db.get(), &DatabaseManager::error, this, &DataManager::error); } // load all tokens from colnod to comparing with working set from DB @@ -18,14 +19,14 @@ void DataManager::fillFullTokensColnod(const QString& response) if (!items.empty()) { for (QJsonValueRef item : items){ - auto token = new Token(); + auto token = std::make_shared(); token->fromJSON(item.toObject()); allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } else{ qCritical() << "Colnod is Empty"; - auto token = new Token("empty"); + auto token = std::make_shared("empty"); allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } @@ -39,7 +40,7 @@ void DataManager::fillTokensToUpdateColnod(const QString& response) { for (QJsonValueRef item : items) { - auto token = new Token(); + auto token = std::make_shared(); token->fromJSON(item.toObject()); token->setDeleted(false); tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); @@ -49,7 +50,7 @@ void DataManager::fillTokensToUpdateColnod(const QString& response) else { qInfo() << "Colnod: 0 tokens to update"; - auto token = new Token("empty"); + auto token = std::make_shared("empty"); tokensToUpdateFromColnodToDB.insert(token->getName(), token); } } @@ -63,7 +64,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) { for (QJsonValueRef item : items) { - auto subject = new Subject(); + auto subject = std::make_shared(); subject->fromJSON(item.toObject()); subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } @@ -72,7 +73,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) else { qInfo() << "Colnod:" << "0 subjects to update"; - Subject* subject = new Subject("empty"); + auto subject = std::make_shared("empty"); subjectsToUpdateFromColnodToDB.insert(subject->getName(), subject); } } @@ -83,7 +84,7 @@ void DataManager::fillTokensToChangeDB() QSqlQuery* query = db->getUpdatedTokens(); while (query->next()) { - auto token = new Token; + auto token = std::make_shared(); token->fromSQLRecord(query); if (token->getDeleted()){ // sort to delete / to update tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces()); @@ -288,7 +289,7 @@ void DataManager::filterTokensColnod() auto record = db->getToken(id); if (!record) continue; - auto tokenDB = new Token; + auto tokenDB = std::shared_ptr(); tokenDB->fromSQLRecord(record); Q_ASSERT(tokenDB != token); if (*tokenDB > *token) diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 7c036d1..24ebbd1 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -42,9 +42,9 @@ public: void emptyDatabase(); - QHash> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;} + QHash> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;} QList getTokensToDeleteColnod() {return tokensFromColnodToDeleteFromDB;} - QHash> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;} + QHash> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;} QList getTokensToDeleteDB() {return tokensFromDBToDeleteFromColnod;} const quint64 &getLastSync() {return lastSync;} @@ -55,17 +55,20 @@ public slots: void setLastSync() {db->updateLastSync(nextLastSync);} void setLastUpdate(); +signals: + void error(); + private: - DatabaseManager *db = nullptr; + std::shared_ptr db; quint64 lastSync; // time of last run quint64 nextLastSync; // time of begin of this run - QHash> subjectsToUpdateFromColnodToDB; - QHash> tokensToUpdateFromColnodToDB; - QHash> allTokensFromColnod; - QHash> subjectsDB; // in future - QHash> tokensToUpdateFromDBToColnod; + QHash> subjectsToUpdateFromColnodToDB; + QHash> tokensToUpdateFromColnodToDB; + QHash> allTokensFromColnod; + QHash> subjectsDB; // in future + QHash> tokensToUpdateFromDBToColnod; QList subjectsFromColnodToDeleteFromDB; QList tokensFromColnodToDeleteFromDB; diff --git a/src/colnod/entity.h b/src/colnod/entity.h index ec71351..e9d0d7d 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include class Entity : public QObject { diff --git a/src/colnod/logger.cpp b/src/colnod/logger.cpp index d5d6d8b..b06d2ef 100644 --- a/src/colnod/logger.cpp +++ b/src/colnod/logger.cpp @@ -1,6 +1,6 @@ #include "logger.h" -DatabaseManager *Logger::dbMan = nullptr; +std::shared_ptr Logger::dbMan = nullptr; Logger *Logger::logger = nullptr; Logger::Logger() @@ -26,21 +26,24 @@ void Logger::logToDb(const QString &msg) Logger::dbMan->log(msg); } -void Logger::setDBMan(DatabaseManager *dbMan) +void Logger::setDBMan(std::shared_ptr dbMan) { Logger::dbMan = dbMan; } QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source) { - QString msg = QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source); - return msg; + return QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source); } QString Logger::makeSubjectMsg(const QString &subjectId, const QString &action, const QString &source) { - QString msg = QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source); - return msg; + return QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source); +} + +QString Logger::makeErrorMsg(const QString &source, const QString &errMsg) +{ + return QString("Source: %1, Error: %2").arg(source, errMsg); } diff --git a/src/colnod/logger.h b/src/colnod/logger.h index 80931ec..7c62211 100644 --- a/src/colnod/logger.h +++ b/src/colnod/logger.h @@ -13,16 +13,16 @@ class Logger Logger(); - static DatabaseManager *dbMan; + static std::shared_ptr dbMan; public: static Logger *getLogger(); static void log(const QString& msg); static void logToDb(const QString& msg); - static void setDBMan(DatabaseManager* dbMan); + static void setDBMan(std::shared_ptr dbMan); static QString makeTokenMsg(const QString& tokenId, const QString& action, const QString& source); static QString makeSubjectMsg(const QString& subjectId, const QString& action, const QString& source); - + static QString makeErrorMsg(const QString& source, const QString& errMsg); private: diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 4225213..79a9b42 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -2,16 +2,14 @@ RequestManager::RequestManager() { - manager = new QNetworkAccessManager(); - token = ""; - loginStatus = false; - QObject::connect(manager, &QNetworkAccessManager::sslErrors, this, &RequestManager::onSSLError); + manager = std::make_unique(); + connect(manager.get(), &QNetworkAccessManager::sslErrors, this, &RequestManager::onSSLError); } -Response* RequestManager::login() +std::shared_ptr RequestManager::login() { Q_ASSERT(!loginResponse); - loginResponse = new Response; + loginResponse = std::make_shared(); QNetworkRequest request; QString hash = encryptedPassword(this->password); authHeader = getLoginHeader(this->user, hash); @@ -22,25 +20,24 @@ Response* RequestManager::login() request.setUrl(this->host + "/AaaManager/authSession"); request.setRawHeader("Authorization", authHeader.toLocal8Bit()); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json; charset=UTF-8"); - QJsonDocument jsonDocument; jsonDocument.setObject(reqBody); QNetworkReply* reply = manager->post(request, jsonDocument.toJson()); loginResponse->setReply(reply); - QObject::connect(reply, &QNetworkReply::finished, [=]() { + connect(reply, &QNetworkReply::finished, [=]() { if (reply->error()) { - qDebug() << "Login failed: "<< reply->errorString(); + Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString())); loginStatus = false; reply->deleteLater(); + emit error(); return; } - //qDebug() << "Logged in successfully."; loginStatus = true; emit successLogin(); reply->deleteLater(); }); - connect(this, &RequestManager::successLogin, loginResponse, &Response::ready); + connect(this, &RequestManager::successLogin, loginResponse.get(), &Response::ready); connect(this, &RequestManager::successLogin, this, &RequestManager::prepareAuthHeader); return loginResponse; } @@ -55,12 +52,12 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA QObject::connect(reply, &QNetworkReply::finished, [=]() { if (reply->error()) { - qDebug() << "Authorization failed: " << reply->errorString(); + Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString())); loginStatus = false; reply->deleteLater(); + emit error(); return; } - //qDebug() << "Authorized successfully, response ready."; emit responseReady(); reply->deleteLater(); }); @@ -68,7 +65,7 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA } // This will ensure login is called only once -Response* RequestManager::getLoginResponse() { +std::shared_ptr RequestManager::getLoginResponse() { if (!loginResponse){ loginResponse = login(); } @@ -79,7 +76,7 @@ Response* RequestManager::postRequestReturnLogic(const QString& endpoint, const { auto loginResponse = getLoginResponse(); Q_ASSERT(loginResponse); - auto* response = new Response; + auto response = new Response; if (!loginStatus){ connect(this, &RequestManager::successLogin, [=](){ @@ -121,7 +118,7 @@ QString RequestManager::getLoginHeader(const QString& username, const QString& h void RequestManager::prepareAuthHeader() { jsonResponse = loginResponse->getJson(); - token = getFromJson(jsonResponse, "id"); + QString token = getFromJson(jsonResponse, "id"); QString authValue = token + ":"; authHeader = "Basic " + authValue.toLocal8Bit().toBase64(); } @@ -146,7 +143,7 @@ QByteArray RequestManager::makeTimestampJson(uint64_t time) return doc.toJson(); } -QByteArray RequestManager::makeTokensJson(const QHash > &tokens) +QByteArray RequestManager::makeTokensJson(const QHash> &tokens) { QJsonObject items; QJsonArray jsonTokens; @@ -239,7 +236,7 @@ Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time) return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimestampJson(time)); } -Response* RequestManager::setTokens(const QHash > &tokens) +Response* RequestManager::setTokens(const QHash> &tokens) { return postRequestReturnLogic("/TokenManager/setTokens", makeTokensJson(tokens)); } diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index 4d868ac..2cea1e1 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -31,7 +31,12 @@ class RequestManager : public QObject Q_OBJECT public: + friend class UnitTest; + friend class ComplexTest; + RequestManager(); + +// this should be in ColnodAPI class BEGIN Response* getSubjects(); Response* getTokens(); Response* getTokenSubject(); @@ -49,47 +54,47 @@ public: Response* getAccessGroupMembershipUpdated(uint64_t time); Response* getAccessGroupMembershipDeleted(uint64_t time); - Response* setTokens(const QHash> &tokens); + Response* setTokens(const QHash> &tokens); Response* deleteTokens(const QList &ids); - - Response* login(); //I want it private, but unittest??? - - const QJsonDocument &getConfig() const {return config;} - const QString &getResponse() const {return jsonResponse;} +// END private: +// should be public QNetworkReply* postRequest(const QString& endpoint, const QByteArray& json = QByteArray()); Response* postRequestReturnLogic(const QString& endpoint, const QByteArray& data = QByteArray()); + + std::shared_ptr login(); + std::shared_ptr getLoginResponse(); QString getFromJson(const QString& json, const QString &member); QString encryptedPassword(const QString& password); QString getLoginHeader(const QString& username, const QString& hash); +// in colnod api as well QByteArray makeTimestampJson(uint64_t time); - QByteArray makeTokensJson(const QHash> &tokens); - QByteArray makeIdsJson(const QList &ids); - Response* getLoginResponse(); + QByteArray makeTokensJson(const QHash> &tokens); // maybe better to be in Token class + QByteArray makeIdsJson(const QList &ids); // Entity class private slots: void onSSLError(QNetworkReply *reply, const QList &errors); + //void onReplyFinished(QNetworkReply *reply); void prepareAuthHeader(); signals: void successLogin(); void responseReady(); - + void error(); private: - QNetworkAccessManager* manager = nullptr; - Response* loginResponse = nullptr; + std::unique_ptr manager; + std::shared_ptr loginResponse; QJsonDocument config; QString authHeader; - QString host = "https://192.168.1.3:8443"; + const QString host = "https://192.168.1.3:8443"; //QString host = "https://localhost:8080"; - QString password = "spaceti1"; - QString user = "spaceti"; - QString token; + const QString password = "spaceti1"; + const QString user = "spaceti"; QString jsonResponse; - bool loginStatus; + bool loginStatus = false; }; diff --git a/src/colnod/subject.h b/src/colnod/subject.h index ed7b213..cc7f4ac 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -39,6 +39,6 @@ private: QSet pinFlags; //QList> atr; QList> atr; - const std::array attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; + const QList attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; }; diff --git a/src/colnod/colnodapi.cpp b/src/colnod/syncmanager.cpp similarity index 75% rename from src/colnod/colnodapi.cpp rename to src/colnod/syncmanager.cpp index 4fbdbeb..a048118 100644 --- a/src/colnod/colnodapi.cpp +++ b/src/colnod/syncmanager.cpp @@ -1,13 +1,16 @@ -#include "colnodapi.h" +#include "syncmanager.h" -ColnodAPI::ColnodAPI(bool dryMode) +SyncManager::SyncManager(bool dryMode) { - reqMan = new RequestManager(); - dataMan = new DataManager(dryMode); + reqMan = std::make_unique(); + dataMan = std::make_unique(dryMode); this->dryMode = dryMode; + + connect(reqMan.get(), &RequestManager::error, this, &SyncManager::error); + connect(dataMan.get(), &DataManager::error, this, &SyncManager::error); } -void ColnodAPI::loadDataFromColnod() +void SyncManager::loadDataFromColnod() { loadTokensFromColnod(); loadUpdatedDataFromColnod(); @@ -15,7 +18,7 @@ void ColnodAPI::loadDataFromColnod() } // download all tokens form colnod for comparing with tokens to update from DB -void ColnodAPI::loadTokensFromColnod() +void SyncManager::loadTokensFromColnod() { Response* resp = reqMan->getTokens(); connect(resp, &Response::ready, [=](){ @@ -26,7 +29,7 @@ void ColnodAPI::loadTokensFromColnod() } // fill tokens/subjects to update in data manager -void ColnodAPI::loadUpdatedDataFromColnod() +void SyncManager::loadUpdatedDataFromColnod() { uint64_t lastUpdate = dataMan->getLastSync(); Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate); @@ -45,7 +48,7 @@ void ColnodAPI::loadUpdatedDataFromColnod() } // fill tokens/subjects to delete in data manager -void ColnodAPI::loadDeletedDataFromColnod() +void SyncManager::loadDeletedDataFromColnod() { uint64_t lastUpdate = dataMan->getLastSync(); Response* resp2 = reqMan->getSubjectsDeleted(lastUpdate); @@ -65,12 +68,12 @@ void ColnodAPI::loadDeletedDataFromColnod() } // fill structures in data manager (tokens to updata/to delte) -void ColnodAPI::loadDataFromDB() +void SyncManager::loadDataFromDB() { dataMan->fillTokensToChangeDB(); } -void ColnodAPI::syncDataFromColnodToDB() +void SyncManager::syncDataFromColnodToDB() { syncUpdatedDataFromColnodToDB(); if (dataMan->getLastSync() != 0) @@ -78,21 +81,21 @@ void ColnodAPI::syncDataFromColnodToDB() } // push data from colnod to DB -void ColnodAPI::syncUpdatedDataFromColnodToDB() +void SyncManager::syncUpdatedDataFromColnodToDB() { dataMan->pushSubjectsToDB(); dataMan->pushTokensToDB(); } // set deleted tokens from Colnod, delete subject -void ColnodAPI::syncDeletedDataFromColnodToDB() +void SyncManager::syncDeletedDataFromColnodToDB() { dataMan->deleteSubjectsFromDB(); dataMan->setDeletedToTokensFromDB(); } // push changes form DB to Colnod -void ColnodAPI::syncDataFromDBToColnod() +void SyncManager::syncDataFromDBToColnod() { if (!dataMan->getTokensToUpdateDB().contains("empty")){ @@ -105,9 +108,9 @@ void ColnodAPI::syncDataFromDBToColnod() } else updateFinished = true; - connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::clear); - connect(this, &ColnodAPI::dataUpdatedToColnod, dataMan, &DataManager::setLastSync); - connect(this, &ColnodAPI::dataUpdatedToColnod, [=](){ + connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear); + connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync); + connect(this, &SyncManager::dataUpdatedToColnod, [=](){ auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync()); connect(resp, &Response::ready, [=](){ dataMan->fillTokensToUpdateColnod(resp->getJson()); @@ -121,7 +124,7 @@ void ColnodAPI::syncDataFromDBToColnod() } // add or update tokens to Colnod -void ColnodAPI::syncUpdatedDataFromDBToColnod() +void SyncManager::syncUpdatedDataFromDBToColnod() { auto tokensToUpdate = dataMan->getTokensToUpdateDB(); if (dryMode){ @@ -139,7 +142,7 @@ void ColnodAPI::syncUpdatedDataFromDBToColnod() } // delete tokens in Colnod -void ColnodAPI::syncDeletedDataFromDBToColnod() +void SyncManager::syncDeletedDataFromDBToColnod() { dataMan->filterTokensDB(); auto tokensToDelete = dataMan->getTokensToDeleteDB(); @@ -158,20 +161,20 @@ void ColnodAPI::syncDeletedDataFromDBToColnod() } // For full sync -void ColnodAPI::prepareDatabase() +void SyncManager::prepareDatabase() { dataMan->emptyDatabase(); } // emit signal when all data is downloaded from Colnod -void ColnodAPI::areChangedDataReady() +void SyncManager::areChangedDataReady() { if (dataMan->haveChangedData()) emit dataDownloaded(); } // emit signal when writing to Colnod is finised -void ColnodAPI::areDataUpdatedToColnod() +void SyncManager::areDataUpdatedToColnod() { if (deleteFinished && updateFinished) { diff --git a/src/colnod/colnodapi.h b/src/colnod/syncmanager.h similarity index 79% rename from src/colnod/colnodapi.h rename to src/colnod/syncmanager.h index c287b6b..c3209e7 100644 --- a/src/colnod/colnodapi.h +++ b/src/colnod/syncmanager.h @@ -4,13 +4,13 @@ #include "datamanager.h" #include "logger.h" -class ColnodAPI : public QObject +class SyncManager : public QObject { Q_OBJECT public: - ColnodAPI(bool dryMode = false); + SyncManager(bool dryMode = false); void syncDataFromColnodToDB(); void syncDataFromDBToColnod(); @@ -25,6 +25,7 @@ signals: void dataDownloaded(); void dataUpdatedToColnod(); void syncFinished(); + void error(); private slots: @@ -46,8 +47,8 @@ private: void areDataUpdatedToColnod(); private: - RequestManager* reqMan = nullptr; - DataManager* dataMan = nullptr; + std::unique_ptr reqMan; + std::unique_ptr dataMan; bool dryMode = false; bool updateFinished = false; bool deleteFinished = false; diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 001da85..6f26430 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -22,6 +22,10 @@ Token::Token(const QString &name) this->setName(name); } +Token::~Token() +{ +} + void Token::fromJSON(const QJsonObject &json) { Entity::fromJSON(json); diff --git a/src/colnod/token.h b/src/colnod/token.h index fe6b665..89c6f9d 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -14,6 +14,7 @@ public: Token() = default; Token(const QString& name, QString tokenData, const QString& decription = "mobile"); Token(const QString& name); + ~Token() override; friend bool operator<(const Token &lToken, const Token &rToken){ return lToken.getLastModified() < rToken.getLastUpdate(); diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index f442bbd..e5f940a 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -14,7 +14,7 @@ void UnitTest::loginSuccessfully() spy.wait(timeout); QCOMPARE(spy.count(), 1); - QString json = testAccess->getResponse(); + QString json = testAccess->jsonResponse; qDebug() << json; QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); QVERIFY2(doc.object().value("id").isString(), "No parameter 'id' in response"); @@ -211,15 +211,14 @@ void UnitTest::setTokens() QJsonObject obj = doc.object(); QJsonArray arr = obj["items"].toArray(); qDebug() << arr; - QHash> tokens; + QHash> tokens; for (auto object : arr) { - auto token = new Token; + auto token = std::shared_ptr(); token->fromJSON(object.toObject()); - qDebug() << token; tokens.insert(token->idToStringWithoutBraces(), token); } - auto* testAccess = new RequestManager(); + auto testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->setTokens(tokens); QCOMPARE(spy.count(), 0); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 7fabed1..60548fc 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -13,7 +13,7 @@ void ComplexTest::initTestCase() // QTest::qWait(2500); // Logger *logger = Logger::getLogger(); start = QDateTime::currentMSecsSinceEpoch()-2000; - api = new ColnodAPI(); + api = new SyncManager(); qDebug() << start; } @@ -37,8 +37,8 @@ void ComplexTest::complexTest() // LOGIN_BEGIN reqMan = new RequestManager; QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); - Response* loginResp = reqMan->login(); - QSignalSpy loginRespSpy(loginResp, &Response::ready); + auto loginResp = reqMan->login(); + QSignalSpy loginRespSpy(loginResp.get(), &Response::ready); QCOMPARE(loginSpy.count(), 0); QCOMPARE(loginRespSpy.count(), 0); loginSpy.wait(timeout); @@ -58,7 +58,7 @@ void ComplexTest::complexTest() // ADD_TOKENS_CHECK_BEGIN - QHash> tokens; + QHash> tokens; auto token = getTestToken(); tokens.insert(token->idToStringWithoutBraces(), token); Response* setTokensResp = reqMan->setTokens(tokens); @@ -117,14 +117,14 @@ void ComplexTest::fullSync() { api->prepareDatabase(); api->loadDataFromColnod(); - QSignalSpy spy(api, &ColnodAPI::dataDownloaded); + QSignalSpy spy(api, &SyncManager::dataDownloaded); spy.wait(timeout); api->loadDataFromDB(); api->syncDataFromColnodToDB(); api->syncDataFromDBToColnod(); - QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod); + QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod); processSpy.wait(timeout); - QSignalSpy finish(api, &ColnodAPI::syncFinished); + QSignalSpy finish(api, &SyncManager::syncFinished); finish.wait(timeout); } @@ -132,14 +132,14 @@ void ComplexTest::syncLastUpdated() { Logger::log("ahoj"); api->loadDataFromColnod(); - QSignalSpy spy(api, &ColnodAPI::dataDownloaded); + QSignalSpy spy(api, &SyncManager::dataDownloaded); spy.wait(timeout); api->loadDataFromDB(); api->syncDataFromColnodToDB(); api->syncDataFromDBToColnod(); - QSignalSpy processSpy(api, &ColnodAPI::dataUpdatedToColnod); + QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod); processSpy.wait(timeout); - QSignalSpy finish(api, &ColnodAPI::syncFinished); + QSignalSpy finish(api, &SyncManager::syncFinished); finish.wait(timeout); qDebug() << "All right, at least should be."; } @@ -175,7 +175,7 @@ QJsonDocument ComplexTest::getJsonDoc(const QString &json) return QJsonDocument::fromJson(json.toUtf8()); } -QPointer ComplexTest::getTestToken() +std::shared_ptr ComplexTest::getTestToken() { QJsonObject jsonToken; jsonToken.insert("id", "062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); @@ -191,7 +191,7 @@ QPointer ComplexTest::getTestToken() flags.push_back("NoValidity"); jsonToken.insert("flags", flags); jsonToken.insert("subjectId", "72b37f7e-5761-4e6c-8e87-20c0bed0d904"); - QPointer token = new Token; + auto token = std::shared_ptr(); token->fromJSON(jsonToken); return token; } diff --git a/test/unitTests/complextest.h b/test/unitTests/complextest.h index a887cab..f66020b 100644 --- a/test/unitTests/complextest.h +++ b/test/unitTests/complextest.h @@ -5,7 +5,7 @@ #include #include "response.h" #include "requestmanager.h" -#include "colnodapi.h" +#include "syncmanager.h" #include "logger.h" class ComplexTest : public QObject @@ -25,7 +25,7 @@ private: int getNumOfSubjects(); int getNumOfTokens(); QJsonDocument getJsonDoc(const QString &json); - QPointer getTestToken(); + std::shared_ptr getTestToken(); // VARIABLES @@ -34,7 +34,7 @@ private: QString password = "spaceti1"; RequestManager* reqMan = nullptr; uint64_t start = 0; - ColnodAPI* api = nullptr; + SyncManager* api = nullptr; static constexpr qint16 timeout = 10000; }; From 4cc0b0e2c6e856997e5775c2f2686e4809e51856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Mon, 4 Nov 2019 17:24:57 +0100 Subject: [PATCH 15/23] script for representation api bug --- bugs/getTokensDeleted.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 bugs/getTokensDeleted.sh diff --git a/bugs/getTokensDeleted.sh b/bugs/getTokensDeleted.sh new file mode 100644 index 0000000..c255144 --- /dev/null +++ b/bugs/getTokensDeleted.sh @@ -0,0 +1,7 @@ +#!/bin/bash + + +TOKEN=$(curl -k --user "spaceti:E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0" -d '{"password":"E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0","username":"spaceti"}' -H "Content-Type: application/json" https://192.168.1.3:8443/AaaManager/authSession 2>/dev/null | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["id"]') + + +curl -k -u "$TOKEN:" -d '{"timestamp":"1572884491121"}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted From 44da045e29e75d0401bb3a69430893d5bb6d0286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 5 Nov 2019 11:05:15 +0100 Subject: [PATCH 16/23] Update bug script --- bugs/getTokensDeleted.sh | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/bugs/getTokensDeleted.sh b/bugs/getTokensDeleted.sh index c255144..57d464b 100644 --- a/bugs/getTokensDeleted.sh +++ b/bugs/getTokensDeleted.sh @@ -1,7 +1,29 @@ #!/bin/bash - - +# Saving login token TOKEN=$(curl -k --user "spaceti:E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0" -d '{"password":"E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0","username":"spaceti"}' -H "Content-Type: application/json" https://192.168.1.3:8443/AaaManager/authSession 2>/dev/null | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["id"]') - - -curl -k -u "$TOKEN:" -d '{"timestamp":"1572884491121"}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted +# Saving current time and timestamp +DATE=`date +"%Y-%m-%d %H:%M:%S"` +TIMESTAMP=`date +%s%N | cut -b1-13` +echo "==================================" +echo "Current time: $DATE / timestamp: $TIMESTAMP" +echo "==================================" +echo "Creating test token with id = 235c4a3c-7e20-4f2a-8ed2-2fe36cc87907" +curl -k -u "$TOKEN:" -d '{"items":[{"id":"235c4a3c-7e20-4f2a-8ed2-2fe36cc87907","name":"bug test","description":"mobile","tokenType":"Token","tokenBits":32,"tokenData":"7B9D32","timeToLive":255,"authErrors":255,"flags":["Enabled","NoValidity"],"subjectId":"72b37f7e-5761-4e6c-8e87-20c0bed0d904"}]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/setTokens +echo +echo "Deleting test token..." +curl -k -u "$TOKEN:" -d '{"items":["235c4a3c-7e20-4f2a-8ed2-2fe36cc87907"]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/deleteTokens +echo +echo "/getTokensDeleted with time: $DATE" +echo "Expect only one token which has been deleted" +curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted +echo +echo "Wait 5 secs" +echo "==================================" +sleep 5 +echo "/getTokensDeleted with time: $DATE + 2 sec" +echo "Expect no tokens returned, because token has been deleted before more than 5 secs" +((TIMESTAMP=TIMESTAMP+2000)) +curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted +echo +exit +#if $EXPECTED_TOKEN is empty; then \ No newline at end of file From 39205695b34253234e77e1380c7edc16c003f81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Tue, 5 Nov 2019 11:48:12 +0100 Subject: [PATCH 17/23] edit for more readability --- bugs/getTokensDeleted.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/bugs/getTokensDeleted.sh b/bugs/getTokensDeleted.sh index 57d464b..6d762b7 100644 --- a/bugs/getTokensDeleted.sh +++ b/bugs/getTokensDeleted.sh @@ -4,26 +4,33 @@ TOKEN=$(curl -k --user "spaceti:E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507 # Saving current time and timestamp DATE=`date +"%Y-%m-%d %H:%M:%S"` TIMESTAMP=`date +%s%N | cut -b1-13` -echo "==================================" +echo +echo "I'm going to add and delete test token," +echo "then ask for deleted tokens with time before deleting" +echo "and with time after deleting." +echo "It should return token deleted with time before," +echo "but should NOT with time after." +echo "====================================================================" echo "Current time: $DATE / timestamp: $TIMESTAMP" -echo "==================================" +echo "====================================================================" echo "Creating test token with id = 235c4a3c-7e20-4f2a-8ed2-2fe36cc87907" curl -k -u "$TOKEN:" -d '{"items":[{"id":"235c4a3c-7e20-4f2a-8ed2-2fe36cc87907","name":"bug test","description":"mobile","tokenType":"Token","tokenBits":32,"tokenData":"7B9D32","timeToLive":255,"authErrors":255,"flags":["Enabled","NoValidity"],"subjectId":"72b37f7e-5761-4e6c-8e87-20c0bed0d904"}]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/setTokens echo echo "Deleting test token..." curl -k -u "$TOKEN:" -d '{"items":["235c4a3c-7e20-4f2a-8ed2-2fe36cc87907"]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/deleteTokens +echo echo -echo "/getTokensDeleted with time: $DATE" +echo "getTokensDeleted with time (before deleting): $DATE" echo "Expect only one token which has been deleted" curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted echo -echo "Wait 5 secs" -echo "==================================" +echo "====================================================================" +echo "Waiting 5 secs, so we can ask again after deleting" +echo "====================================================================" sleep 5 -echo "/getTokensDeleted with time: $DATE + 2 sec" +echo "getTokensDeleted with time (after deleting): $DATE + 2 sec" echo "Expect no tokens returned, because token has been deleted before more than 5 secs" ((TIMESTAMP=TIMESTAMP+2000)) curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted echo -exit -#if $EXPECTED_TOKEN is empty; then \ No newline at end of file +exit \ No newline at end of file From c0a016f87bd53761c38a54e6682bb143ff92bfa5 Mon Sep 17 00:00:00 2001 From: Filip Bucek Date: Tue, 5 Nov 2019 11:49:40 +0100 Subject: [PATCH 18/23] added another script to describe BUG with getTokensDeleted --- bugs/getTokensDeleted.sh | 0 bugs/getTokensDeleted_01.sh | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) mode change 100644 => 100755 bugs/getTokensDeleted.sh create mode 100755 bugs/getTokensDeleted_01.sh diff --git a/bugs/getTokensDeleted.sh b/bugs/getTokensDeleted.sh old mode 100644 new mode 100755 diff --git a/bugs/getTokensDeleted_01.sh b/bugs/getTokensDeleted_01.sh new file mode 100755 index 0000000..42aa9b3 --- /dev/null +++ b/bugs/getTokensDeleted_01.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Saving login token +TOKEN=$(curl -k --user "spaceti:E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0" -d '{"password":"E7FEA07DBC82FB9BA34B2E453E2EFE89F0583E7187543507EF11E84726071FE428445372F2E46B455EB0C79747C51E362F403CE39473A2A8C2DFA0CE5C9826C0","username":"spaceti"}' -H "Content-Type: application/json" https://192.168.1.3:8443/AaaManager/authSession 2>/dev/null | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["id"]') +# Saving current time and timestamp +# echo "==================================" +# echo "Saving current time ( saved_time ): $DATE / timestamp: $TIMESTAMP" +# echo "==================================" + +echo "========================" +echo "Script to show uncorrect behavior when returing deleted tokens" +echo "1. create token" +echo "2. deletet token" +echo "3. request deleted token with time after last token was deleted" +echo "------------------------" + +DATE=`date +"%Y-%m-%d %H:%M:%S"` +TIMESTAMP=`date +%s000 | cut -b1-13` + +echo "------------------------" +echo "STEPS : Create TOKEN and then deletes it" +echo "EXPECT : Token is deleted and is returned when getting deleted token with saved_time ( time before was deleted )" +echo "------------------------" +#echo "Creating test token with id = 235c4a3c-7e20-4f2a-8ed2-2fe36cc87907" +RES=$(curl -k -u "$TOKEN:" -d '{"items":[{"id":"235c4a3c-7e20-4f2a-8ed2-2fe36cc87907","name":"bug test","description":"mobile","tokenType":"Token","tokenBits":32,"tokenData":"7B9D32","timeToLive":255,"authErrors":255,"flags":["Enabled","NoValidity"],"subjectId":"72b37f7e-5761-4e6c-8e87-20c0bed0d904"}]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/setTokens 2>/dev/null ) +#echo +#echo "Deleting test token..." +RES=$(curl -k -u "$TOKEN:" -d '{"items":["235c4a3c-7e20-4f2a-8ed2-2fe36cc87907"]}' -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/deleteTokens 2>/dev/null ) +#echo "/getTokensDeleted with time: $DATE" +#echo "Expect only one token which has been deleted" +RES=$(curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted 2>/dev/null ) +echo "EXPECTED : {\"items\":[\"235c4a3c-7e20-4f2a-8ed2-2fe36cc87907\"]}" +echo "ACTUAL : $RES" +echo "------------------------" +echo "OK - expected token is returned" +echo "------------------------" +echo "" +echo "==================================" +echo "Now we wait 5 sec to ensure timestamp for deleted token is in past" +echo "==================================" +echo "" +sleep 5 +echo "------------------------" +echo "STEPS : Getting deleted tokens before 2 sec" +echo "EXPECT : no tokens ( since we have deleted token before 5 sec )" +echo "------------------------" +((TIMESTAMP=TIMESTAMP+2000)) # adding 2000 ms to saved timestamp +RES=$(curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted 2>/dev/null ) +echo "EXPECTED : {"items":[]}" +echo "ACTUAL : $RES" +echo "------------------------" +echo "BUG: Token was deleted 5 seconds ago, but was returned even we requested tokens deleted 2 sec ago" +echo "------------------------" + +echo "" +echo "Another bug: future date" +echo "------------------------" +echo "STEPS : Getting deleted tokens with future date" +echo "EXPECT : no tokens" +echo "------------------------" +((TIMESTAMP=TIMESTAMP+20000)) # adding 20s to saved timestamp +RES=$(curl -k -u "$TOKEN:" -d "{\"timestamp\":$TIMESTAMP}" -H "Content-Type: application/json" -X POST https://192.168.1.3:8443/TokenManager/getTokensDeleted 2>/dev/null ) +echo "EXPECTED : {"items":[]}" +echo "ACTUAL : $RES" +echo "------------------------" +echo "BUG: Token was deleted 5 seconds ago, but was returned even we requested time in future" +echo "------------------------" From 836452383920e91cf1c73098c9a3f03cc61a3cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 6 Nov 2019 16:46:49 +0100 Subject: [PATCH 19/23] Fixed bugs, first working version --- src/app/main.cpp | 7 +- src/colnod/databasemanager.cpp | 248 ++++++++++++++++----------------- src/colnod/databasemanager.h | 8 +- src/colnod/datamanager.cpp | 134 +++++++++++------- src/colnod/datamanager.h | 13 +- src/colnod/entity.cpp | 18 +++ src/colnod/entity.h | 11 ++ src/colnod/subject.h | 3 - src/colnod/syncmanager.cpp | 64 ++++++--- src/colnod/syncmanager.h | 1 + src/colnod/token.cpp | 50 +++---- src/colnod/token.h | 25 +++- 12 files changed, 320 insertions(+), 262 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 3c951e3..3a95aa2 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -19,15 +19,16 @@ int main(int argc, char *argv[]) api.loadDataFromDB(); api.loadDataFromColnod(); QObject::connect(&api, &SyncManager::dataDownloaded, [&](){ - api.syncDataFromColnodToDB(); - api.syncDataFromDBToColnod(); QObject::connect(&api, &SyncManager::syncFinished, [](){ qDebug() << "Quit"; QCoreApplication::exit(); }); + api.syncDataFromColnodToDB(); + api.syncDataFromDBToColnod(); }); QObject::connect(&api, &SyncManager::error, [](){ - QCoreApplication::exit(1); + qDebug() << "error"; + QCoreApplication::exit(); }); return QCoreApplication::exec(); } diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 7c5a158..94109b8 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -1,6 +1,7 @@ #include "databasemanager.h" DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode) + :dryMode(dryMode) { db = QSqlDatabase::addDatabase("QPSQL"); db.setDatabaseName(dbName); @@ -12,118 +13,93 @@ DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, con log("Opening error" + db.lastError().text()); emit error(); } - query = QSqlQuery("query", db); - this->dryMode = dryMode; } // add or update subject to db int DatabaseManager::saveSubject(std::shared_ptr subject, const QString& table) { + QSqlQuery query; QString id = subject->idToStringWithoutBraces(); - if (checkIfExists(id, table)) - { - query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = last_update:, name = :name, pin = :pin" - "WHERE id = :id)").arg(table)); - query.bindValue(":id", id); - query.bindValue(":description", subject->getDescription()); - query.bindValue(":name", subject->getName()); - query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":pin", subject->getPin()); - executeQuery(query); - return -1; - } - - - query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin) " - "VALUES (:id, :description, :last_update, :name, :pin)").arg(table)); - query.bindValue(":id", id); - query.bindValue(":description", subject->getDescription()); - query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":name", subject->getName()); - query.bindValue(":pin", subject->getPin()); - executeQuery(query); - return 1; - + int rtn; + if (checkIfExists(id, table)){ + query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = :last_update, name = :name, pin = :pin, last_modified = :last_modified, deleted = :deleted " + "WHERE id = :id").arg(table)); + rtn = -1; + }else{ + query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) " + "VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table)); + rtn = 1; + } + query.bindValue(":id", id); + query.bindValue(":description", subject->getDescription()); + query.bindValue(":name", subject->getName()); + query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":pin", subject->getPin()); + query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":deleted", subject->getDeleted()); + executeQuery(query); + return rtn; } // add or update token to DB int DatabaseManager::saveToken(std::shared_ptr token, const QString& table) { + QSqlQuery query; QString id = token->idToStringWithoutBraces(); - if (checkIfExists(id, table)) - { - query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified deleted = :deleted) " + int rtn; + if (checkIfExists(id, table)){ + query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, last_update = :last_update, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified, deleted = :deleted " "WHERE id = :id").arg(table)); - query.bindValue(":id", id); - query.bindValue(":auth_errors", token->getAuthErrors()); - query.bindValue(":description", token->getDescription()); - query.bindValue(":enabled", token->getFlags().contains("Enabled")); - query.bindValue(":name", token->getName()); - query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); - query.bindValue(":time_to_live", token->getTimeToLive()); - query.bindValue(":token_bits", token->getTokenBits()); - query.bindValue(":token_data", token->getTokenData()); - query.bindValue(":token_type", token->getTokenType()); - query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); - query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":deleted", token->getDeleted()); - executeQuery(query); - return -1; - } - - + rtn = -1; + }else{ query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) " "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table)); - query.bindValue(":id", id); - query.bindValue(":auth_errors", token->getAuthErrors()); - query.bindValue(":description", token->getDescription()); - query.bindValue(":enabled", token->getFlags().contains("Enabled")); - query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":name", token->getName()); - query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); - query.bindValue(":time_to_live", token->getTimeToLive()); - query.bindValue(":token_bits", token->getTokenBits()); - query.bindValue(":token_data", token->getTokenData()); - query.bindValue(":token_type", token->getTokenType()); - query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); - query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); - query.bindValue(":deleted", token->getDeleted()); - executeQuery(query); - return 1; - + rtn = 1; + } + query.bindValue(":id", id); + query.bindValue(":auth_errors", token->getAuthErrors()); + query.bindValue(":description", token->getDescription()); + query.bindValue(":enabled", token->getFlags().contains("Enabled")); + query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":name", token->getName()); + query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); + query.bindValue(":time_to_live", token->getTimeToLive()); + query.bindValue(":token_bits", token->getTokenBits()); + query.bindValue(":token_data", token->getTokenData()); + query.bindValue(":token_type", token->getTokenType()); + query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); + query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); + query.bindValue(":deleted", token->getDeleted()); + executeQuery(query); + return rtn; } // add of update subject attributes void DatabaseManager::saveSubjectAttributes(std::shared_ptr subject, const QString& table) { + QSqlQuery query; auto attributes = subject->getAtr(); for (const auto& attribute : attributes){ QString id = subject->idToStringWithoutBraces() + " " + attribute.first; if (checkIfExists(id, table)){ query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) " "WHERE id = :id").arg(table)); - query.bindValue(":id", id); - query.bindValue(":key", attribute.first); - query.bindValue(":value", attribute.second); - query.bindValue(":subject_id", subject->idToStringWithoutBraces()); - executeQuery(query); - } - else{ + }else{ query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)" "VALUES (:id, :key, :value, :subject_id)").arg(table)); - query.bindValue(":id", id); - query.bindValue(":key", attribute.first); - query.bindValue(":value", attribute.second); - query.bindValue(":subject_id", subject->idToStringWithoutBraces()); - executeQuery(query); } + query.bindValue(":id", id); + query.bindValue(":key", attribute.first); + query.bindValue(":value", attribute.second); + query.bindValue(":subject_id", subject->idToStringWithoutBraces()); + executeQuery(query); } } // "delete" tokens from DB -> set deleted true void DatabaseManager::setDeleted(const QString& id, const QString& table, quint64 time) { - //quint64 now = getNow(); + QSqlQuery query; QString nowString = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd hh:mm:ss.zzz"); query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table)); query.bindValue(":id", id); @@ -133,6 +109,7 @@ void DatabaseManager::setDeleted(const QString& id, const QString& table, quint6 bool DatabaseManager::checkIfExists(const QString& id, const QString& table) { + QSqlQuery query; query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table)); query.bindValue(":id", id); executeQuery(query); @@ -152,54 +129,56 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const return str; } -void DatabaseManager::executeNonPreperedQuery(const QString &statement, QSqlQuery &query) - +bool DatabaseManager::executeQuery(QSqlQuery &query, const QString &statement) { - if (dryMode){ - QString sqlStatement = getLastQuery(query); - qDebug() << sqlStatement; + if (statement.isEmpty()){ + if (dryMode){ + QString sqlStatement = getLastQuery(query); + qDebug() << sqlStatement; + } + if (!dryMode || getLastQuery(query).startsWith("SELECT")){ + if (!query.exec()){ + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + log(QString(msg)); + emit error(); + } + } + return true; } - if (!dryMode || statement.startsWith("SELECT")){ - if (!query.exec(statement)){ - QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); - log(QString(msg)); - emit error(); - } - } -} - -bool DatabaseManager::executeQuery(QSqlQuery &query) -{ - if (dryMode){ - QString sqlStatement = getLastQuery(query); - qDebug() << sqlStatement; - - } - if (!dryMode || query.isSelect()){ - if (!query.exec()){ - QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); - log(QString(msg)); - emit error(); - } - } - return true; + if (dryMode){ + qDebug() << statement; + } + if (!dryMode || statement.startsWith("SELECT")){ + if (!query.exec(statement)){ + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + log(QString(msg)); + emit error(); + } + } + return true; } void DatabaseManager::dropTables() { - executeNonPreperedQuery("DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute", query); + QSqlQuery query; + + executeQuery(query, "DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute"); } // create table after deleting, it is used for full sync void DatabaseManager::createTables() { - executeNonPreperedQuery("CREATE TABLE colnod_subject (" + QSqlQuery query; + + executeQuery(query, "CREATE TABLE colnod_subject (" "id character(36) primary key NOT NULL," "description character varying(255)," "last_update timestamp NOT NULL," "name character varying(255)," - "pin character varying(255))", query); - executeNonPreperedQuery("CREATE TABLE colnod_token (" + "pin character varying(255)," + "last_modified timestamp," + "deleted BOOLEAN)"); + executeQuery(query, "CREATE TABLE colnod_token (" "id CHAR(36) primary key NOT NULL," "auth_errors INTEGER NOT NULL," "description VARCHAR(255)," @@ -213,18 +192,19 @@ void DatabaseManager::createTables() "token_type VARCHAR(255)," "subject_id CHAR(36)," "last_modified timestamp," - "deleted BOOLEAN)", query); - executeNonPreperedQuery("CREATE TABLE colnod_subject_attribute (" + "deleted BOOLEAN)"); + executeQuery(query, "CREATE TABLE colnod_subject_attribute (" "id VARCHAR(255) primary key," "attribute_key VARCHAR(255)," "attribute_value VARCHAR(255)," - "subject_id CHAR(36))", query); + "subject_id CHAR(36))"); } // return last_sync time quint64 DatabaseManager::getLastSync() { - executeNonPreperedQuery("SELECT last_sync FROM config", query); + QSqlQuery query; + executeQuery(query, "SELECT last_sync FROM config"); query.next(); quint64 temp = query.value(0).toULongLong(); return temp; @@ -233,6 +213,7 @@ quint64 DatabaseManager::getLastSync() // on the very end of sync set new Last_sync time (begin of this sync) void DatabaseManager::updateLastSync(quint64 lastSync) { + QSqlQuery query; query.prepare("UPDATE config SET last_sync = :last_sync"); query.bindValue(":last_sync", lastSync); executeQuery(query); @@ -240,30 +221,29 @@ void DatabaseManager::updateLastSync(quint64 lastSync) // return set of tokens to update form DB -QSqlQuery* DatabaseManager::getUpdatedTokens() +QSqlQuery DatabaseManager::getUpdatedTokens() { - QSqlQuery* qry = new QSqlQuery; - executeNonPreperedQuery("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " - "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000", *qry); - return qry; + QSqlQuery query; + executeQuery(query, "SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000"); + return query; } -QSqlQuery* DatabaseManager::getToken(const QString& id) +QSqlQuery DatabaseManager::getToken(const QString& id) { - QSqlQuery* qry = new QSqlQuery; - qry->prepare("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " + QSqlQuery query; + query.prepare("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " "FROM colnod_token WHERE id = :id"); - qry->bindValue(":id", id); - executeQuery(*qry); - if (qry->next()){ - return qry; - } - return nullptr; + query.bindValue(":id", id); + executeQuery(query); + query.next(); + return query; } quint64 DatabaseManager::getNow() { - executeNonPreperedQuery("SELECT EXTRACT(EPOCH FROM NOW())*1000", query); + QSqlQuery query; + executeQuery(query, "SELECT EXTRACT(EPOCH FROM NOW())*1000"); query.next(); return query.value(0).toULongLong(); } @@ -271,14 +251,17 @@ quint64 DatabaseManager::getNow() // sync last update back to DB from Colnod after changes made to Colnod void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) { - query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id"); + QSqlQuery query; + QString lsatUpdateString = QDateTime::fromMSecsSinceEpoch(lastUpdate).toString("yyyy-MM-dd hh:mm:ss.zzz"); + query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id"); query.bindValue(":id", id); - query.bindValue(":lastUpdate", lastUpdate); + query.bindValue(":last_update", lsatUpdateString); executeQuery(query); } void DatabaseManager::log(const QString &msg) { + QSqlQuery query; query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)"); query.bindValue(":msg", msg); query.exec(); @@ -286,6 +269,7 @@ void DatabaseManager::log(const QString &msg) QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId) { + QSqlQuery query; query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)"); query.bindValue(":tokenId", tokenId); executeQuery(query); @@ -297,6 +281,7 @@ QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId) QString DatabaseManager::getSubjectNameById(const QString &id) { + QSqlQuery query; query.prepare("SELECT name FROM colnod_subject WHERE id = :id"); query.bindValue(":id", id); executeQuery(query); @@ -308,6 +293,7 @@ QString DatabaseManager::getSubjectNameById(const QString &id) bool DatabaseManager::checkDeletedToken(const QString &id) { + QSqlQuery query; query.prepare("SELECT deleted FROM colnod_token WHERE id = :id"); query.bindValue(":id", id); executeQuery(query); diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 6a56cb2..3d3fef6 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -31,8 +31,8 @@ public: void updateLastSync(quint64 lastSync); quint64 getNow(); - QSqlQuery* getUpdatedTokens(); - QSqlQuery* getToken(const QString& id); + QSqlQuery getUpdatedTokens(); + QSqlQuery getToken(const QString& id); void setLastUpdate(const QString& id, quint64 lastUpdate); @@ -44,15 +44,13 @@ public: private: bool checkIfExists(const QString& id, const QString& table); - bool executeQuery(QSqlQuery &query); + bool executeQuery(QSqlQuery &query, const QString &statement = QString()); QString getLastQuery(const QSqlQuery &query) const; - void executeNonPreperedQuery(const QString &statement, QSqlQuery& query); signals: void error(); private: QSqlDatabase db; - QSqlQuery query; bool dryMode = false; }; diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index bf0382a..2ea2eac 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -1,13 +1,13 @@ #include "datamanager.h" DataManager::DataManager(const bool &dryMode) + :dryMode(dryMode) { db = std::make_shared("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode); //db = std::make_shared("localhost", "deloitte", "postgres", "34rjkciea12"); Logger::setDBMan(db); nextLastSync = db->getNow(); lastSync = db->getLastSync(); - this->dryMode = dryMode; connect(db.get(), &DatabaseManager::error, this, &DataManager::error); } @@ -21,13 +21,12 @@ void DataManager::fillFullTokensColnod(const QString& response) for (QJsonValueRef item : items){ auto token = std::make_shared(); token->fromJSON(item.toObject()); - allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); + allTokensFromColnodById.insert(token->idToStringWithoutBraces(), token); + allTokensFromColnodByName.insert(token->getName(), token); } } else{ qCritical() << "Colnod is Empty"; - auto token = std::make_shared("empty"); - allTokensFromColnod.insert(token->idToStringWithoutBraces(), token); } } @@ -50,8 +49,6 @@ void DataManager::fillTokensToUpdateColnod(const QString& response) else { qInfo() << "Colnod: 0 tokens to update"; - auto token = std::make_shared("empty"); - tokensToUpdateFromColnodToDB.insert(token->getName(), token); } } @@ -66,6 +63,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) { auto subject = std::make_shared(); subject->fromJSON(item.toObject()); + subject->setDeleted(false); subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); } qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update"; @@ -73,16 +71,14 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response) else { qInfo() << "Colnod:" << "0 subjects to update"; - auto subject = std::make_shared("empty"); - subjectsToUpdateFromColnodToDB.insert(subject->getName(), subject); } } // load working sets with updated/deleted tokens from DB void DataManager::fillTokensToChangeDB() { - QSqlQuery* query = db->getUpdatedTokens(); - while (query->next()) + QSqlQuery query = db->getUpdatedTokens(); + while (query.next()) { auto token = std::make_shared(); token->fromSQLRecord(query); @@ -116,7 +112,6 @@ void DataManager::fillSubjectsToDeleteColnod(const QString& json) } else { qInfo() << "Colnod: 0 subjects to delete"; - subjectsFromColnodToDeleteFromDB.append("empty"); } } @@ -134,7 +129,6 @@ void DataManager::fillTokensToDeleteColnod(const QString& json) } else { qInfo() << "Colnod: 0 tokens to delete"; - tokensFromColnodToDeleteFromDB.append("empty"); } } @@ -146,7 +140,7 @@ void DataManager::fillSubjectsToDeleteDB() // update subjects from colnod to DB void DataManager::pushSubjectsToDB() { - if (subjectsToUpdateFromColnodToDB.contains("empty")) { + if (subjectsToUpdateFromColnodToDB.isEmpty()) { qInfo() << "DB: 0 subjects added"; qInfo() << "DB: 0 subjects updated"; return; @@ -157,11 +151,17 @@ void DataManager::pushSubjectsToDB() { if (db->saveSubject(subject, "colnod_subject") > 0){ added++; - Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); + if (dryMode) + qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); } else{ updated++; - Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); + if (dryMode) + qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); } db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } @@ -172,7 +172,7 @@ void DataManager::pushSubjectsToDB() // update tokens from colnod to DB void DataManager::pushTokensToDB() { - if (tokensToUpdateFromColnodToDB.contains("empty")){ + if (tokensToUpdateFromColnodToDB.isEmpty()){ qInfo() << "DB: 0 tokens added"; qInfo() << "DB: 0 tokens updated"; return; @@ -182,23 +182,31 @@ void DataManager::pushTokensToDB() int added = 0; for (const auto& token : tokensToUpdateFromColnodToDB) { - if (db->saveToken(token, "colnod_token") > 0){ + + QString text; + // 1 = adding token + // -1 = updating token + if (db->saveToken(token, "colnod_token") == 1){ added++; - Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "added", "DB")); - } - else{ + text = "Added"; + } + else { updated++; - Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "updated", "DB")); - } + text = "Updating"; + } + if (dryMode) + qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB")); } - qInfo() << "DB:" << added << " tokens added"; - qInfo() << "DB:" << updated << " tokens updated"; + qInfo() << "DB:" << added << "tokens added/edited"; + qInfo() << "DB:" << updated << "tokens updated"; } void DataManager::deleteSubjectsFromDB() { - if (subjectsFromColnodToDeleteFromDB[0] == "empty") + if (subjectsFromColnodToDeleteFromDB.isEmpty()) { qInfo() << "DB: 0 subjects deleted"; return; @@ -206,7 +214,10 @@ void DataManager::deleteSubjectsFromDB() for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) { db->setDeleted(subjectId, "colnod_subject", nextLastSync); - Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB")); + if (dryMode) + qInfo() << "Deleting subject:" << subjectId << "from DB"; + else + Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB")); } qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted"; } @@ -214,7 +225,7 @@ void DataManager::deleteSubjectsFromDB() // "delete" (set deleted true) tokens in DB depends on Colnod void DataManager::setDeletedToTokensFromDB() { - if (tokensFromColnodToDeleteFromDB[0] == "empty") + if (tokensFromColnodToDeleteFromDB.isEmpty()) { qDebug() << "DB: 0 tokens deleted"; return; @@ -224,7 +235,10 @@ void DataManager::setDeletedToTokensFromDB() { if (!db->checkDeletedToken(tokenId)){ db->setDeleted(tokenId, "colnod_token", nextLastSync); - Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB")); + if (dryMode) + qInfo() << "Deleting token:" << tokenId << "from DB"; + else + Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB")); } else alreadyDeleted++; @@ -232,16 +246,6 @@ void DataManager::setDeletedToTokensFromDB() qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted"; } -// do I have loaded all data -bool DataManager::haveChangedData() -{ - return !subjectsToUpdateFromColnodToDB.isEmpty() && - !tokensToUpdateFromColnodToDB.isEmpty() && - !subjectsFromColnodToDeleteFromDB.isEmpty() && - !tokensFromColnodToDeleteFromDB.isEmpty() && - !allTokensFromColnod.isEmpty(); -} - // recreate working tables void DataManager::emptyDatabase() { @@ -249,6 +253,14 @@ void DataManager::emptyDatabase() db->createTables(); } +quint64 DataManager::getLastModifiedOfToken(const QString &id) +{ + auto record = db->getToken(id); + auto token = std::make_shared(); + token->fromSQLRecord(record); + return token->getLastModified(); +} + //clear all structures void DataManager::clear() { @@ -260,7 +272,7 @@ void DataManager::clear() // subjectsToDeleteDB.clear(); // not need yet tokensToUpdateFromDBToColnod.clear(); tokensFromDBToDeleteFromColnod.clear(); - allTokensFromColnod.clear(); + allTokensFromColnodById.clear(); } // on the very end of sync update last sync time to begin time of this sync @@ -272,37 +284,59 @@ void DataManager::updateLastSync() // these to filter functions solve colision tokens -> remove when change on this token is earlier then change on the same token on the other side (Colnod/DB) void DataManager::filterTokensDB() { + QList idsToDelete; for (const auto& token : tokensToUpdateFromDBToColnod) { QString id = token->idToStringWithoutBraces(); - Q_ASSERT(token != allTokensFromColnod.value(id)); // if working sets are loading correctly equels should never happend - if (allTokensFromColnod.contains(id) && *token < *allTokensFromColnod.value(id)) - tokensToUpdateFromDBToColnod.remove(id); + Q_ASSERT(token != allTokensFromColnodById.value(id)); // if working sets are loading correctly equels should never happend + if (allTokensFromColnodById.contains(id) && *token < *allTokensFromColnodById.value(id)) + idsToDelete.append(id); + if (allTokensFromColnodById.contains(id) && token->getLastModified() == allTokensFromColnodById.value(id)->getLastUpdate()){ + idsToDelete.append(id); + qWarning() << "Same token has been edited in colnod and db in same time. Change from Colnod has been used"; + } + if (allTokensFromColnodByName.contains(token->getName())){ + qWarning() << "Token:" << token->idToStringWithoutBraces() << "won't be added to Colnod, because token with the same name already exists, please change it manually"; + if (!dryMode){ + QString message = QString("Error: Token: %1 won't be added to Colnod, because token with the same name already exists, please change it manually").arg(token->idToStringWithoutBraces()); + Logger::logToDb(Logger::makeErrorMsg("Db", message)); + } + } } + for (const auto &id : idsToDelete) + tokensToUpdateFromDBToColnod.remove(id); } void DataManager::filterTokensColnod() { + QList idsToDelete; for (const auto &token : tokensToUpdateFromColnodToDB) { QString id = token->idToStringWithoutBraces(); auto record = db->getToken(id); - if (!record) + if (!record.isValid()) continue; - auto tokenDB = std::shared_ptr(); + auto tokenDB = std::make_shared(); tokenDB->fromSQLRecord(record); - Q_ASSERT(tokenDB != token); - if (*tokenDB > *token) - tokensToUpdateFromColnodToDB.remove(id); + if (*tokenDB == *token || *tokenDB > *token){ + idsToDelete.append(id); + } } + for (const auto &id : idsToDelete) + tokensToUpdateFromColnodToDB.remove(id); } // sync last update from colnod to DB void DataManager::setLastUpdate() { - for (const auto &token : tokensToUpdateFromColnodToDB){ - db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate()); - } + if (!tokensToUpdateFromColnodToDB.isEmpty()) + for (const auto &token : tokensToUpdateFromColnodToDB) + db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate()); +} + +void DataManager::setLastUpdate(const QString &id) +{ + db->setLastUpdate(id, nextLastSync); } diff --git a/src/colnod/datamanager.h b/src/colnod/datamanager.h index 24ebbd1..0c365d2 100644 --- a/src/colnod/datamanager.h +++ b/src/colnod/datamanager.h @@ -38,13 +38,13 @@ public: void updateLastSync(); - bool haveChangedData(); - void emptyDatabase(); - QHash> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;} + quint64 getLastModifiedOfToken(const QString &id); + + QHash> getTokensToUpdateFromColnod() {return tokensToUpdateFromColnodToDB;} QList getTokensToDeleteColnod() {return tokensFromColnodToDeleteFromDB;} - QHash> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;} + QHash> getTokensToUpdateFromDB() {return tokensToUpdateFromDBToColnod;} QList getTokensToDeleteDB() {return tokensFromDBToDeleteFromColnod;} const quint64 &getLastSync() {return lastSync;} @@ -52,8 +52,8 @@ public: public slots: void clear(); - void setLastSync() {db->updateLastSync(nextLastSync);} void setLastUpdate(); + void setLastUpdate(const QString &id); signals: void error(); @@ -64,9 +64,10 @@ private: quint64 lastSync; // time of last run quint64 nextLastSync; // time of begin of this run + QHash> allTokensFromColnodById; + QHash> allTokensFromColnodByName; QHash> subjectsToUpdateFromColnodToDB; QHash> tokensToUpdateFromColnodToDB; - QHash> allTokensFromColnod; QHash> subjectsDB; // in future QHash> tokensToUpdateFromDBToColnod; diff --git a/src/colnod/entity.cpp b/src/colnod/entity.cpp index fcae765..2a1db6a 100644 --- a/src/colnod/entity.cpp +++ b/src/colnod/entity.cpp @@ -33,6 +33,24 @@ void Entity::setLastUpdate(quint64 lastUpdate) { this->lastUpdate = lastUpdate; } +quint64 Entity::getLastModified() const { + return lastModified; +} + +void Entity::setLastModified(const quint64 &lastModified) { + this->lastModified = lastModified; +} + +bool Entity::getDeleted() const +{ + return deleted; +} + +void Entity::setDeleted(const bool &deleted) +{ + this->deleted = deleted; +} + QString Entity::idToStringWithoutBraces() const { const qint8 lengthOfUuid = 36; diff --git a/src/colnod/entity.h b/src/colnod/entity.h index e9d0d7d..07fb22d 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -24,13 +24,24 @@ public: quint64 getLastUpdate() const; void setLastUpdate(quint64 lastUpdate); + quint64 getLastModified() const; + void setLastModified(const quint64 &lastModified); + + bool getDeleted() const; + void setDeleted(const bool &deleted); + QString idToStringWithoutBraces() const; virtual void fromJSON(const QJsonObject &json); virtual QJsonObject toJSON() const; + + + private: QUuid id; QString name; QString description; qint64 lastUpdate{}; + quint64 lastModified{}; + bool deleted{}; }; diff --git a/src/colnod/subject.h b/src/colnod/subject.h index cc7f4ac..83cf489 100644 --- a/src/colnod/subject.h +++ b/src/colnod/subject.h @@ -24,8 +24,6 @@ public: void setPin(const QString &pin); const QSet &getPinFlags() const; void setPinFlags(const QSet &pinFlags); - // const QList> &getAtr() const; - // void setAtr(const QList> &atr); const QList> &getAtr() const; void setAtr(const QList> &atr); @@ -37,7 +35,6 @@ private: QSet tokenFlags; QString pin; QSet pinFlags; - //QList> atr; QList> atr; const QList attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"}; diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index a048118..b9d794b 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -98,42 +98,54 @@ void SyncManager::syncDeletedDataFromColnodToDB() void SyncManager::syncDataFromDBToColnod() { - if (!dataMan->getTokensToUpdateDB().contains("empty")){ - syncDeletedDataFromDBToColnod(); - } + connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear); + //connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync); + if (!dryMode) + connect(this, &SyncManager::dataUpdatedToColnod, [=](){ + auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync()); + connect(resp, &Response::ready, [=](){ + dataMan->fillTokensToUpdateColnod(resp->getJson()); + dataMan->setLastUpdate(); + dataMan->clear(); + dataMan->updateLastSync(); + emit syncFinished(); + resp->deleteLater(); + }); + }); else - deleteFinished = true; - if (!dataMan->getTokensToDeleteDB().contains("empty")){ + connect(this, &SyncManager::dataUpdatedToColnod, [=](){ + dataMan->updateLastSync(); + emit syncFinished(); + }); + if (!dataMan->getTokensToUpdateFromDB().contains("empty")){ syncUpdatedDataFromDBToColnod(); } else updateFinished = true; - connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear); - connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync); - connect(this, &SyncManager::dataUpdatedToColnod, [=](){ - auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync()); - connect(resp, &Response::ready, [=](){ - dataMan->fillTokensToUpdateColnod(resp->getJson()); - dataMan->setLastUpdate(); - dataMan->clear(); - dataMan->updateLastSync(); - emit syncFinished(); - resp->deleteLater(); - }); - }); + if (!dataMan->getTokensToDeleteDB().contains("empty")){ + syncDeletedDataFromDBToColnod(); + } + else + deleteFinished = true; } // add or update tokens to Colnod void SyncManager::syncUpdatedDataFromDBToColnod() { - auto tokensToUpdate = dataMan->getTokensToUpdateDB(); + dataMan->filterTokensDB(); + auto tokensToUpdate = dataMan->getTokensToUpdateFromDB(); if (dryMode){ for (const auto &token : tokensToUpdate) - qInfo() << "Updating token: " << token->idToStringWithoutBraces() << "to Colnod"; + qInfo() << "Updating token:" << token->idToStringWithoutBraces() << "to Colnod"; + updateFinished = true; + areDataUpdatedToColnod(); } else { Response* resp0 = reqMan->setTokens(tokensToUpdate); connect(resp0, &Response::ready, [=](){ + qInfo() << "Colnod:" << tokensToUpdate.size() << "tokens updated"; + for(const auto &token : tokensToUpdate) + Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "updated", "Colnod")); updateFinished = true; areDataUpdatedToColnod(); resp0->deleteLater(); @@ -144,15 +156,21 @@ void SyncManager::syncUpdatedDataFromDBToColnod() // delete tokens in Colnod void SyncManager::syncDeletedDataFromDBToColnod() { - dataMan->filterTokensDB(); auto tokensToDelete = dataMan->getTokensToDeleteDB(); if (dryMode){ for (const auto &token : tokensToDelete) - qInfo() << "Deleting token: " << token << "from Colnod"; + qInfo() << "Deleting token:" << token << "from Colnod"; + deleteFinished = true; + areDataUpdatedToColnod(); } else { Response* resp1 = reqMan->deleteTokens(tokensToDelete); connect(resp1, &Response::ready, [=](){ + qInfo() << "Colnod:" << tokensToDelete.size() << "tokens deleted"; + for (const auto &id : tokensToDelete){ + dataMan->setLastUpdate(id); + Logger::logToDb(Logger::makeTokenMsg(id, "deleted", "Colnod")); + } deleteFinished = true; areDataUpdatedToColnod(); resp1->deleteLater(); @@ -169,7 +187,7 @@ void SyncManager::prepareDatabase() // emit signal when all data is downloaded from Colnod void SyncManager::areChangedDataReady() { - if (dataMan->haveChangedData()) + if (++dataCounter == 5) emit dataDownloaded(); } diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index c3209e7..b7fbf58 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -52,5 +52,6 @@ private: bool dryMode = false; bool updateFinished = false; bool deleteFinished = false; + int dataCounter = 0; }; diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index 6f26430..add8e9a 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -57,28 +57,28 @@ QJsonObject Token::toJSON() const { return json; } -void Token::fromSQLRecord(QSqlQuery *query) +void Token::fromSQLRecord(QSqlQuery query) { - setId(query->value(0).toUuid()); - authErrors = query->value(1).toInt(); - setDescription(query->value(2).toString()); + setId(query.value(0).toUuid()); + authErrors = query.value(1).toInt(); + setDescription(query.value(2).toString()); QSet flags; - if (query->value(6).toBool()) + if (query.value(6).toBool()) flags.insert("NoValidity"); - if (query->value(3).toBool()) + if (query.value(3).toBool()) flags.insert("Enabled"); this->flags = flags; - QDateTime date = query->value(4).toDateTime(); + QDateTime date = query.value(4).toDateTime(); setLastUpdate(date.toMSecsSinceEpoch()); - setName(query->value(5).toString()); - timeToLive = query->value(7).toInt(); - tokenBits = query->value(8).toInt(); - tokenData = query->value(9).toString(); - tokenType = query->value(10).toString(); - subjectId = query->value(11).toUuid(); - date = query->value(12).toDateTime(); - lastModified = date.toMSecsSinceEpoch(); - deleted = query->value(13).toBool(); + setName(query.value(5).toString()); + timeToLive = query.value(7).toInt(); + tokenBits = query.value(8).toInt(); + tokenData = query.value(9).toString(); + tokenType = query.value(10).toString(); + subjectId = query.value(11).toUuid(); + date = query.value(12).toDateTime(); + setLastModified(date.toMSecsSinceEpoch()); + setDeleted(query.value(13).toBool()); } const QString &Token::getTokenType() const { @@ -140,21 +140,3 @@ void Token::setSubjectId(const QUuid &subjectId) { QString Token::subjectIdToStringWithoutBraces(){ return subjectId.toString().mid(1,36); } - -quint64 Token::getLastModified() const { - return lastModified; -} - -void Token::setLastModified(const quint64 &lastModified) { - Token::lastModified = lastModified; -} - -bool Token::getDeleted() const -{ - return deleted; -} - -void Token::setDeleted(const bool &deleted) -{ - this->deleted = deleted; -} diff --git a/src/colnod/token.h b/src/colnod/token.h index 89c6f9d..1e3f2b6 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -22,6 +22,22 @@ public: friend bool operator>(const Token &lToken, const Token &rToken){ return lToken.getLastModified() > rToken.getLastUpdate(); } + friend bool operator==(const Token &lToken, const Token &rToken){ + if ( lToken.getId() == rToken.getId() && + lToken.getName() == rToken.getName() && + lToken.getDescription() == rToken.getDescription() && + lToken.getLastUpdate() == rToken.getLastUpdate() && + lToken.tokenType == rToken.tokenType && + lToken.tokenBits == rToken.tokenBits && + lToken.tokenData == rToken.tokenData && + lToken.timeToLive == rToken.timeToLive && + lToken.authErrors == rToken.authErrors && + lToken.flags == rToken.flags && + lToken.subjectId == rToken.subjectId) + return true; + return false; + } + const QString &getTokenType() const; void setTokenType(const QString &tokenType); @@ -37,14 +53,11 @@ public: void setFlags(const QSet &flags); const QUuid &getSubjectId() const; void setSubjectId(const QUuid &subjectId); - quint64 getLastModified() const; - void setLastModified(const quint64 &lastModified); - bool getDeleted() const; - void setDeleted(const bool &deleted); + QString subjectIdToStringWithoutBraces(); - void fromSQLRecord(QSqlQuery* query); + void fromSQLRecord(QSqlQuery query); void fromJSON(const QJsonObject &json) override; QJsonObject toJSON() const override; @@ -56,6 +69,4 @@ private: int authErrors{}; QSet flags; QUuid subjectId; - quint64 lastModified{}; - bool deleted{}; }; From 8e21275b6ab112e8463ad61690da6240d98e4b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 6 Nov 2019 16:48:53 +0100 Subject: [PATCH 20/23] Fix code formating --- src/colnod/databasemanager.cpp | 82 +++++++++++++++++----------------- src/colnod/datamanager.cpp | 58 ++++++++++++------------ src/colnod/entity.h | 2 +- src/colnod/requestmanager.cpp | 12 ++--- src/colnod/requestmanager.h | 8 ++-- src/colnod/token.cpp | 2 +- src/colnod/token.h | 2 +- test/unitTests/UnitTest.cpp | 2 +- test/unitTests/complextest.cpp | 38 ++++++++-------- test/unitTests/unittest.h | 12 ++--- 10 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index 94109b8..eba3f10 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -27,9 +27,9 @@ int DatabaseManager::saveSubject(std::shared_ptr subject, const QString rtn = -1; }else{ query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) " - "VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table)); + "VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table)); rtn = 1; - } + } query.bindValue(":id", id); query.bindValue(":description", subject->getDescription()); query.bindValue(":name", subject->getName()); @@ -49,11 +49,11 @@ int DatabaseManager::saveToken(std::shared_ptr token, const QString& tabl int rtn; if (checkIfExists(id, table)){ query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, last_update = :last_update, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified, deleted = :deleted " - "WHERE id = :id").arg(table)); + "WHERE id = :id").arg(table)); rtn = -1; }else{ query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) " - "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table)); + "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table)); rtn = 1; } query.bindValue(":id", id); @@ -141,21 +141,21 @@ bool DatabaseManager::executeQuery(QSqlQuery &query, const QString &statement) QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); log(QString(msg)); emit error(); - } + } } return true; } - if (dryMode){ - qDebug() << statement; + if (dryMode){ + qDebug() << statement; + } + if (!dryMode || statement.startsWith("SELECT")){ + if (!query.exec(statement)){ + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + log(QString(msg)); + emit error(); } - if (!dryMode || statement.startsWith("SELECT")){ - if (!query.exec(statement)){ - QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); - log(QString(msg)); - emit error(); - } - } - return true; + } + return true; } void DatabaseManager::dropTables() @@ -171,33 +171,33 @@ void DatabaseManager::createTables() QSqlQuery query; executeQuery(query, "CREATE TABLE colnod_subject (" - "id character(36) primary key NOT NULL," - "description character varying(255)," - "last_update timestamp NOT NULL," - "name character varying(255)," - "pin character varying(255)," - "last_modified timestamp," - "deleted BOOLEAN)"); + "id character(36) primary key NOT NULL," + "description character varying(255)," + "last_update timestamp NOT NULL," + "name character varying(255)," + "pin character varying(255)," + "last_modified timestamp," + "deleted BOOLEAN)"); executeQuery(query, "CREATE TABLE colnod_token (" - "id CHAR(36) primary key NOT NULL," - "auth_errors INTEGER NOT NULL," - "description VARCHAR(255)," - "enabled BOOLEAN NOT NULL," - "last_update timestamp NOT NULL," - "name VARCHAR(255)," - "no_validity BOOLEAN NOT NULL," - "time_to_live INTEGER NOT NULL," - "token_bits INTEGER," - "token_data VARCHAR(255)," - "token_type VARCHAR(255)," - "subject_id CHAR(36)," - "last_modified timestamp," - "deleted BOOLEAN)"); + "id CHAR(36) primary key NOT NULL," + "auth_errors INTEGER NOT NULL," + "description VARCHAR(255)," + "enabled BOOLEAN NOT NULL," + "last_update timestamp NOT NULL," + "name VARCHAR(255)," + "no_validity BOOLEAN NOT NULL," + "time_to_live INTEGER NOT NULL," + "token_bits INTEGER," + "token_data VARCHAR(255)," + "token_type VARCHAR(255)," + "subject_id CHAR(36)," + "last_modified timestamp," + "deleted BOOLEAN)"); executeQuery(query, "CREATE TABLE colnod_subject_attribute (" - "id VARCHAR(255) primary key," - "attribute_key VARCHAR(255)," - "attribute_value VARCHAR(255)," - "subject_id CHAR(36))"); + "id VARCHAR(255) primary key," + "attribute_key VARCHAR(255)," + "attribute_value VARCHAR(255)," + "subject_id CHAR(36))"); } // return last_sync time @@ -225,7 +225,7 @@ QSqlQuery DatabaseManager::getUpdatedTokens() { QSqlQuery query; executeQuery(query, "SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted " - "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000"); + "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000"); return query; } diff --git a/src/colnod/datamanager.cpp b/src/colnod/datamanager.cpp index 2ea2eac..c74fa82 100644 --- a/src/colnod/datamanager.cpp +++ b/src/colnod/datamanager.cpp @@ -86,7 +86,7 @@ void DataManager::fillTokensToChangeDB() tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces()); } else{ - tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); + tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); } } qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update"; @@ -95,7 +95,7 @@ void DataManager::fillTokensToChangeDB() void DataManager::fillSubjectsToUpdateDB() { - // Not needed yet + // Not needed yet } // load working set with subjest to delete from Colnod @@ -150,18 +150,18 @@ void DataManager::pushSubjectsToDB() for (const auto& subject : subjectsToUpdateFromColnodToDB) { if (db->saveSubject(subject, "colnod_subject") > 0){ - added++; - if (dryMode) - qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB"; - else - Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); + added++; + if (dryMode) + qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); } else{ - updated++; - if (dryMode) - qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB"; - else - Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); + updated++; + if (dryMode) + qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); } db->saveSubjectAttributes(subject, "colnod_subject_attribute"); } @@ -183,21 +183,21 @@ void DataManager::pushTokensToDB() for (const auto& token : tokensToUpdateFromColnodToDB) { - QString text; - // 1 = adding token - // -1 = updating token - if (db->saveToken(token, "colnod_token") == 1){ - added++; - text = "Added"; - } - else { - updated++; - text = "Updating"; - } - if (dryMode) - qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB"; - else - Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB")); + QString text; + // 1 = adding token + // -1 = updating token + if (db->saveToken(token, "colnod_token") == 1){ + added++; + text = "Added"; + } + else { + updated++; + text = "Updating"; + } + if (dryMode) + qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB"; + else + Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB")); } qInfo() << "DB:" << added << "tokens added/edited"; qInfo() << "DB:" << updated << "tokens updated"; @@ -268,8 +268,8 @@ void DataManager::clear() subjectsFromColnodToDeleteFromDB.clear(); tokensToUpdateFromColnodToDB.clear(); tokensFromColnodToDeleteFromDB.clear(); - //subjectsDB.clear(); // not need yet - // subjectsToDeleteDB.clear(); // not need yet + //subjectsDB.clear(); // not need yet + // subjectsToDeleteDB.clear(); // not need yet tokensToUpdateFromDBToColnod.clear(); tokensFromDBToDeleteFromColnod.clear(); allTokensFromColnodById.clear(); diff --git a/src/colnod/entity.h b/src/colnod/entity.h index 07fb22d..131439a 100644 --- a/src/colnod/entity.h +++ b/src/colnod/entity.h @@ -8,7 +8,7 @@ class Entity : public QObject { -Q_OBJECT + Q_OBJECT public: using QObject::QObject; diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index 79a9b42..5d0e79c 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -14,8 +14,8 @@ std::shared_ptr RequestManager::login() QString hash = encryptedPassword(this->password); authHeader = getLoginHeader(this->user, hash); QJsonObject reqBody = { - {"password", hash}, - {"username", this->user} + {"password", hash}, + {"username", this->user} }; request.setUrl(this->host + "/AaaManager/authSession"); request.setRawHeader("Authorization", authHeader.toLocal8Bit()); @@ -36,7 +36,7 @@ std::shared_ptr RequestManager::login() loginStatus = true; emit successLogin(); reply->deleteLater(); - }); + }); connect(this, &RequestManager::successLogin, loginResponse.get(), &Response::ready); connect(this, &RequestManager::successLogin, this, &RequestManager::prepareAuthHeader); return loginResponse; @@ -82,7 +82,7 @@ Response* RequestManager::postRequestReturnLogic(const QString& endpoint, const connect(this, &RequestManager::successLogin, [=](){ response->setReply(postRequest(endpoint, data)); connect(response->getReply(), &QNetworkReply::finished, response, &Response::ready); - }); + }); } else { @@ -106,7 +106,7 @@ QString RequestManager::getFromJson(const QString& json, const QString &member) QString RequestManager::encryptedPassword(const QString& password) { - return QCryptographicHash::hash(password.toLocal8Bit(), QCryptographicHash::Sha512).toHex().toUpper(); + return QCryptographicHash::hash(password.toLocal8Bit(), QCryptographicHash::Sha512).toHex().toUpper(); } QString RequestManager::getLoginHeader(const QString& username, const QString& hash) @@ -233,7 +233,7 @@ Response* RequestManager::getAccessGroupMembershipUpdated(uint64_t time) Response* RequestManager::getAccessGroupMembershipDeleted(uint64_t time) { - return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimestampJson(time)); + return postRequestReturnLogic("/AccessManager/getAccessGroupMembershipDeleted", makeTimestampJson(time)); } Response* RequestManager::setTokens(const QHash> &tokens) diff --git a/src/colnod/requestmanager.h b/src/colnod/requestmanager.h index 2cea1e1..9eb37d3 100644 --- a/src/colnod/requestmanager.h +++ b/src/colnod/requestmanager.h @@ -36,7 +36,7 @@ public: RequestManager(); -// this should be in ColnodAPI class BEGIN + // this should be in ColnodAPI class BEGIN Response* getSubjects(); Response* getTokens(); Response* getTokenSubject(); @@ -56,10 +56,10 @@ public: Response* setTokens(const QHash> &tokens); Response* deleteTokens(const QList &ids); -// END + // END private: -// should be public + // should be public QNetworkReply* postRequest(const QString& endpoint, const QByteArray& json = QByteArray()); Response* postRequestReturnLogic(const QString& endpoint, const QByteArray& data = QByteArray()); @@ -69,7 +69,7 @@ private: QString encryptedPassword(const QString& password); QString getLoginHeader(const QString& username, const QString& hash); -// in colnod api as well + // in colnod api as well QByteArray makeTimestampJson(uint64_t time); QByteArray makeTokensJson(const QHash> &tokens); // maybe better to be in Token class QByteArray makeIdsJson(const QList &ids); // Entity class diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index add8e9a..fad1461 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -138,5 +138,5 @@ void Token::setSubjectId(const QUuid &subjectId) { } QString Token::subjectIdToStringWithoutBraces(){ - return subjectId.toString().mid(1,36); + return subjectId.toString().mid(1,36); } diff --git a/src/colnod/token.h b/src/colnod/token.h index 1e3f2b6..953561f 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -9,7 +9,7 @@ class Token : public Entity { public: - // using Entity::Entity; + // using Entity::Entity; Token() = default; Token(const QString& name, QString tokenData, const QString& decription = "mobile"); diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index e5f940a..f245487 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -342,7 +342,7 @@ void UnitTest::debugConnection() void UnitTest::saveDataToDB() { - // dataMan->localSaveTokens(); + // dataMan->localSaveTokens(); QVERIFY(true); } diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 60548fc..36ee3e5 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -2,16 +2,16 @@ void ComplexTest::initTestCase() { -// auto reqMan1 = new RequestManager; -// QList ids; -// ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); -// ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); -// Response* deleteTokensResp = reqMan1->deleteTokens(ids); -// QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); -// QCOMPARE(deleteTokensRespSpy.count(), 0); -// deleteTokensRespSpy.wait(timeout); -// QTest::qWait(2500); - // Logger *logger = Logger::getLogger(); + // auto reqMan1 = new RequestManager; + // QList ids; + // ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); + // ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); + // Response* deleteTokensResp = reqMan1->deleteTokens(ids); + // QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); + // QCOMPARE(deleteTokensRespSpy.count(), 0); + // deleteTokensRespSpy.wait(timeout); + // QTest::qWait(2500); + // Logger *logger = Logger::getLogger(); start = QDateTime::currentMSecsSinceEpoch()-2000; api = new SyncManager(); qDebug() << start; @@ -21,15 +21,15 @@ void ComplexTest::initTestCase() void ComplexTest::cleanupTestCase() { -// QList ids; -// ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); -// ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); -// auto reqMan = new RequestManager; -// Response* deleteTokensResp = reqMan->deleteTokens(ids); -// QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); -// QCOMPARE(deleteTokensRespSpy.count(), 0); -// deleteTokensRespSpy.wait(timeout); -// QCOMPARE(deleteTokensRespSpy.count(), 1); + // QList ids; + // ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); + // ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); + // auto reqMan = new RequestManager; + // Response* deleteTokensResp = reqMan->deleteTokens(ids); + // QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); + // QCOMPARE(deleteTokensRespSpy.count(), 0); + // deleteTokensRespSpy.wait(timeout); + // QCOMPARE(deleteTokensRespSpy.count(), 1); } void ComplexTest::complexTest() diff --git a/test/unitTests/unittest.h b/test/unitTests/unittest.h index 3e414e5..0b2b5fe 100644 --- a/test/unitTests/unittest.h +++ b/test/unitTests/unittest.h @@ -44,11 +44,11 @@ private slots: private: - //QString host = "http://localhost:8080"; //colnod server (ssh -L 8080:192.168.254.11:8443 penta-master) - QString host = "https://192.168.1.3:8443"; //local testing server - QString password = "spaceti1"; - QString email = "spaceti"; + //QString host = "http://localhost:8080"; //colnod server (ssh -L 8080:192.168.254.11:8443 penta-master) + QString host = "https://192.168.1.3:8443"; //local testing server + QString password = "spaceti1"; + QString email = "spaceti"; - static constexpr int timeout = 10000; - static constexpr qint64 epochMS = 1568646217767; + static constexpr int timeout = 10000; + static constexpr qint64 epochMS = 1568646217767; }; From 33e0c42eac691cd54aa3b258eac1361d4102cbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 6 Nov 2019 16:56:16 +0100 Subject: [PATCH 21/23] Clang-tidy and Clanzy --- src/colnod/databasemanager.cpp | 6 +++--- src/colnod/databasemanager.h | 6 +++--- src/colnod/logger.cpp | 4 +++- src/colnod/token.cpp | 5 ++--- src/colnod/token.h | 8 +++----- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/colnod/databasemanager.cpp b/src/colnod/databasemanager.cpp index eba3f10..e2a6059 100644 --- a/src/colnod/databasemanager.cpp +++ b/src/colnod/databasemanager.cpp @@ -16,7 +16,7 @@ DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, con } // add or update subject to db -int DatabaseManager::saveSubject(std::shared_ptr subject, const QString& table) +int DatabaseManager::saveSubject(const std::shared_ptr& subject, const QString& table) { QSqlQuery query; QString id = subject->idToStringWithoutBraces(); @@ -42,7 +42,7 @@ int DatabaseManager::saveSubject(std::shared_ptr subject, const QString } // add or update token to DB -int DatabaseManager::saveToken(std::shared_ptr token, const QString& table) +int DatabaseManager::saveToken(const std::shared_ptr& token, const QString& table) { QSqlQuery query; QString id = token->idToStringWithoutBraces(); @@ -75,7 +75,7 @@ int DatabaseManager::saveToken(std::shared_ptr token, const QString& tabl } // add of update subject attributes -void DatabaseManager::saveSubjectAttributes(std::shared_ptr subject, const QString& table) +void DatabaseManager::saveSubjectAttributes(const std::shared_ptr& subject, const QString& table) { QSqlQuery query; auto attributes = subject->getAtr(); diff --git a/src/colnod/databasemanager.h b/src/colnod/databasemanager.h index 3d3fef6..1ce4b50 100644 --- a/src/colnod/databasemanager.h +++ b/src/colnod/databasemanager.h @@ -19,9 +19,9 @@ class DatabaseManager : public QObject public: DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false); - int saveSubject(std::shared_ptr subject, const QString& table); - int saveToken(std::shared_ptr token, const QString& table); - void saveSubjectAttributes(std::shared_ptr subject, const QString& table); + int saveSubject(const std::shared_ptr& subject, const QString& table); + int saveToken(const std::shared_ptr& token, const QString& table); + void saveSubjectAttributes(const std::shared_ptr& subject, const QString& table); void setDeleted(const QString& id, const QString& table, quint64 time); void dropTables(); diff --git a/src/colnod/logger.cpp b/src/colnod/logger.cpp index b06d2ef..1326479 100644 --- a/src/colnod/logger.cpp +++ b/src/colnod/logger.cpp @@ -1,5 +1,7 @@ #include "logger.h" +#include + std::shared_ptr Logger::dbMan = nullptr; Logger *Logger::logger = nullptr; @@ -28,7 +30,7 @@ void Logger::logToDb(const QString &msg) void Logger::setDBMan(std::shared_ptr dbMan) { - Logger::dbMan = dbMan; + Logger::dbMan = std::move(dbMan); } QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source) diff --git a/src/colnod/token.cpp b/src/colnod/token.cpp index fad1461..fcf2856 100644 --- a/src/colnod/token.cpp +++ b/src/colnod/token.cpp @@ -23,8 +23,7 @@ Token::Token(const QString &name) } Token::~Token() -{ -} += default; void Token::fromJSON(const QJsonObject &json) { @@ -57,7 +56,7 @@ QJsonObject Token::toJSON() const { return json; } -void Token::fromSQLRecord(QSqlQuery query) +void Token::fromSQLRecord(const QSqlQuery& query) { setId(query.value(0).toUuid()); authErrors = query.value(1).toInt(); diff --git a/src/colnod/token.h b/src/colnod/token.h index 953561f..abc7ff5 100644 --- a/src/colnod/token.h +++ b/src/colnod/token.h @@ -23,7 +23,7 @@ public: return lToken.getLastModified() > rToken.getLastUpdate(); } friend bool operator==(const Token &lToken, const Token &rToken){ - if ( lToken.getId() == rToken.getId() && + return lToken.getId() == rToken.getId() && lToken.getName() == rToken.getName() && lToken.getDescription() == rToken.getDescription() && lToken.getLastUpdate() == rToken.getLastUpdate() && @@ -33,9 +33,7 @@ public: lToken.timeToLive == rToken.timeToLive && lToken.authErrors == rToken.authErrors && lToken.flags == rToken.flags && - lToken.subjectId == rToken.subjectId) - return true; - return false; + lToken.subjectId == rToken.subjectId; } @@ -57,7 +55,7 @@ public: QString subjectIdToStringWithoutBraces(); - void fromSQLRecord(QSqlQuery query); + void fromSQLRecord(const QSqlQuery& query); void fromJSON(const QJsonObject &json) override; QJsonObject toJSON() const override; From 3a09a291da73f9b669c186042add4a905f376f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Wed, 6 Nov 2019 17:13:42 +0100 Subject: [PATCH 22/23] change tests --- test/unitTests/UnitTest.cpp | 37 ++++--- test/unitTests/complextest.cpp | 170 ++++++++++++++++----------------- test/unitTests/unittest.h | 2 + 3 files changed, 110 insertions(+), 99 deletions(-) diff --git a/test/unitTests/UnitTest.cpp b/test/unitTests/UnitTest.cpp index f245487..0093e95 100644 --- a/test/unitTests/UnitTest.cpp +++ b/test/unitTests/UnitTest.cpp @@ -204,20 +204,10 @@ void UnitTest::getAccessGroupMembershipDeleted() void UnitTest::setTokens() { - QFile jsonData(QDir::current().filePath("tokens.json")); - QVERIFY2(jsonData.open(QIODevice::ReadOnly), "Couldn't open config file tokens.json"); - QJsonDocument doc = QJsonDocument::fromJson(jsonData.readAll()); - QJsonObject obj = doc.object(); - QJsonArray arr = obj["items"].toArray(); - qDebug() << arr; QHash> tokens; - for (auto object : arr) - { - auto token = std::shared_ptr(); - token->fromJSON(object.toObject()); - tokens.insert(token->idToStringWithoutBraces(), token); - } + auto token = getTestToken(); + tokens.insert(token->idToStringWithoutBraces(), token); auto testAccess = new RequestManager(); QSignalSpy spy(testAccess, SIGNAL(responseReady())); Response* response = testAccess->setTokens(tokens); @@ -353,6 +343,25 @@ void UnitTest::getUuid() QCOMPARE(1,1); } +std::shared_ptr UnitTest::getTestToken() +{ + QJsonObject jsonToken; + jsonToken.insert("id", "062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); + jsonToken.insert("name", "test"); + jsonToken.insert("description", "mobile"); + jsonToken.insert("tokenType", "Token"); + jsonToken.insert("tokenBits", 32); + jsonToken.insert("tokenData", "7B9D32"); + jsonToken.insert("timeToLive", 255); + jsonToken.insert("authErrors", 255); + QJsonArray flags; + flags.push_back("Enabled"); + flags.push_back("NoValidity"); + jsonToken.insert("flags", flags); + jsonToken.insert("subjectId", "72b37f7e-5761-4e6c-8e87-20c0bed0d904"); + auto token = std::make_shared(); + token->fromJSON(jsonToken); + return token; +} - -//QTEST_MAIN(UnitTest) +QTEST_MAIN(UnitTest) diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 36ee3e5..6e7ae9d 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -34,88 +34,88 @@ void ComplexTest::cleanupTestCase() void ComplexTest::complexTest() { - // LOGIN_BEGIN - reqMan = new RequestManager; - QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); - auto loginResp = reqMan->login(); - QSignalSpy loginRespSpy(loginResp.get(), &Response::ready); - QCOMPARE(loginSpy.count(), 0); - QCOMPARE(loginRespSpy.count(), 0); - loginSpy.wait(timeout); - QCOMPARE(loginResp->getStatusCode(), 200); // HTTP status code check - QCOMPARE(loginSpy.count(), 1); // Checking multiple calls - QCOMPARE(loginRespSpy.count(), 1); - auto doc0 = getJsonDoc(loginResp->getJson()); - QVERIFY(doc0.object()["id"].isString()); - // LOGIN_END +// // LOGIN_BEGIN +// reqMan = new RequestManager; +// QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); +// auto loginResp = reqMan->login(); +// QSignalSpy loginRespSpy(loginResp.get(), &Response::ready); +// QCOMPARE(loginSpy.count(), 0); +// QCOMPARE(loginRespSpy.count(), 0); +// loginSpy.wait(timeout); +// QCOMPARE(loginResp->getStatusCode(), 200); // HTTP status code check +// QCOMPARE(loginSpy.count(), 1); // Checking multiple calls +// QCOMPARE(loginRespSpy.count(), 1); +// auto doc0 = getJsonDoc(loginResp->getJson()); +// QVERIFY(doc0.object()["id"].isString()); +// // LOGIN_END - // NUMBER_OF_SUBJECTS_AND_TOKENS_BEGIN - int numOfSubjects = getNumOfSubjects(); - QCOMPARE(numOfSubjects, 2893); // should be still the same, if false db has been changed - int numOfTokens = getNumOfTokens(); - QCOMPARE(numOfTokens, 2881); // should be still the same, if false db has been changed, or deleteTokens didnt work in previous test - // NUMBER_OF_SUBJECTS_AND_TOKENS_END +// // NUMBER_OF_SUBJECTS_AND_TOKENS_BEGIN +// int numOfSubjects = getNumOfSubjects(); +// QCOMPARE(numOfSubjects, 2893); // should be still the same, if false db has been changed +// int numOfTokens = getNumOfTokens(); +// QCOMPARE(numOfTokens, 2881); // should be still the same, if false db has been changed, or deleteTokens didnt work in previous test +// // NUMBER_OF_SUBJECTS_AND_TOKENS_END - // ADD_TOKENS_CHECK_BEGIN - QHash> tokens; - auto token = getTestToken(); - tokens.insert(token->idToStringWithoutBraces(), token); - Response* setTokensResp = reqMan->setTokens(tokens); - QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); - QCOMPARE(setTokensRespSpy.count(), 0); - setTokensRespSpy.wait(timeout); - QCOMPARE(setTokensRespSpy.count(), 1); - QCOMPARE(setTokensResp->getStatusCode(), 200); - QCOMPARE(getNumOfTokens(), numOfTokens + 1); - // ADD_TOKENS_CHEK_END +// // ADD_TOKENS_CHECK_BEGIN +// QHash> tokens; +// auto token = getTestToken(); +// tokens.insert(token->idToStringWithoutBraces(), token); +// Response* setTokensResp = reqMan->setTokens(tokens); +// QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); +// QCOMPARE(setTokensRespSpy.count(), 0); +// setTokensRespSpy.wait(timeout); +// QCOMPARE(setTokensRespSpy.count(), 1); +// QCOMPARE(setTokensResp->getStatusCode(), 200); +// QCOMPARE(getNumOfTokens(), numOfTokens + 1); +// // ADD_TOKENS_CHEK_END - // CHECK_UPDATED_TOKENS_BEGIN - Response* getTokensUpdatedResp = reqMan->getTokensUpdated(start); - //start = QDateTime::currentMSecsSinceEpoch(); - QSignalSpy getTokensUpdatedRespSpy(getTokensUpdatedResp, &Response::ready); - QCOMPARE(getTokensUpdatedRespSpy.count(), 0); - getTokensUpdatedRespSpy.wait(timeout); - QCOMPARE(getTokensUpdatedResp->getStatusCode(), 200); - QCOMPARE(getTokensUpdatedRespSpy.count(), 1); - auto doc1 = getJsonDoc(getTokensUpdatedResp->getJson()); - QCOMPARE(doc1.object()["items"].toArray().size(), 1); - // CHECK_UPDATED_TOKENS_END +// // CHECK_UPDATED_TOKENS_BEGIN +// Response* getTokensUpdatedResp = reqMan->getTokensUpdated(start); +// //start = QDateTime::currentMSecsSinceEpoch(); +// QSignalSpy getTokensUpdatedRespSpy(getTokensUpdatedResp, &Response::ready); +// QCOMPARE(getTokensUpdatedRespSpy.count(), 0); +// getTokensUpdatedRespSpy.wait(timeout); +// QCOMPARE(getTokensUpdatedResp->getStatusCode(), 200); +// QCOMPARE(getTokensUpdatedRespSpy.count(), 1); +// auto doc1 = getJsonDoc(getTokensUpdatedResp->getJson()); +// QCOMPARE(doc1.object()["items"].toArray().size(), 1); +// // CHECK_UPDATED_TOKENS_END - // DELETE_TOKENS_CHECK_BEGIN - QList ids; - ids.append("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); - Response* deleteTokensResp = reqMan->deleteTokens(ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(timeout); - QCOMPARE(deleteTokensRespSpy.count(), 1); - QCOMPARE(deleteTokensResp->getStatusCode(), 200); - // DELETE_TOKENS_CHECK_END +// // DELETE_TOKENS_CHECK_BEGIN +// QList ids; +// ids.append("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9"); +// Response* deleteTokensResp = reqMan->deleteTokens(ids); +// QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); +// QCOMPARE(deleteTokensRespSpy.count(), 0); +// deleteTokensRespSpy.wait(timeout); +// QCOMPARE(deleteTokensRespSpy.count(), 1); +// QCOMPARE(deleteTokensResp->getStatusCode(), 200); +// // DELETE_TOKENS_CHECK_END - // CHECK_DELETED_TOKENS_BEGIN - Response* getTokensDeletedResp = reqMan->getTokensDeleted(start); - start = QDateTime::currentMSecsSinceEpoch(); - QSignalSpy getTokensDeletedRespSpy(getTokensDeletedResp, &Response::ready); - QCOMPARE(getTokensDeletedRespSpy.count(), 0); - getTokensDeletedRespSpy.wait(timeout); - QCOMPARE(getTokensDeletedResp->getStatusCode(), 200); - QCOMPARE(getTokensDeletedRespSpy.count(), 1); - auto doc2 = getJsonDoc(getTokensDeletedResp->getJson()); - QCOMPARE(doc2.object()["items"].toArray().size(), 1); - QVERIFY(doc2.object()["items"].toArray().contains("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9")); - // CHECK_DELETED_TOKENS_END +// // CHECK_DELETED_TOKENS_BEGIN +// Response* getTokensDeletedResp = reqMan->getTokensDeleted(start); +// start = QDateTime::currentMSecsSinceEpoch(); +// QSignalSpy getTokensDeletedRespSpy(getTokensDeletedResp, &Response::ready); +// QCOMPARE(getTokensDeletedRespSpy.count(), 0); +// getTokensDeletedRespSpy.wait(timeout); +// QCOMPARE(getTokensDeletedResp->getStatusCode(), 200); +// QCOMPARE(getTokensDeletedRespSpy.count(), 1); +// auto doc2 = getJsonDoc(getTokensDeletedResp->getJson()); +// QCOMPARE(doc2.object()["items"].toArray().size(), 1); +// QVERIFY(doc2.object()["items"].toArray().contains("062c93f6-ba3e-46af-a3a6-7a2988d1f0e9")); +// // CHECK_DELETED_TOKENS_END - // LAST_TESTS (for sure) - QCOMPARE(loginSpy.count(), 1); // Checking multiple calls - QCOMPARE(loginRespSpy.count(), 1); - QCOMPARE(getNumOfSubjects(), numOfSubjects); - QCOMPARE(getNumOfTokens(), numOfTokens); +// // LAST_TESTS (for sure) +// QCOMPARE(loginSpy.count(), 1); // Checking multiple calls +// QCOMPARE(loginRespSpy.count(), 1); +// QCOMPARE(getNumOfSubjects(), numOfSubjects); +// QCOMPARE(getNumOfTokens(), numOfTokens); } void ComplexTest::fullSync() { - api->prepareDatabase(); + /* api->prepareDatabase(); api->loadDataFromColnod(); QSignalSpy spy(api, &SyncManager::dataDownloaded); spy.wait(timeout); @@ -125,23 +125,23 @@ void ComplexTest::fullSync() QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod); processSpy.wait(timeout); QSignalSpy finish(api, &SyncManager::syncFinished); - finish.wait(timeout); + finish.wait(timeout); */ } void ComplexTest::syncLastUpdated() { - Logger::log("ahoj"); - api->loadDataFromColnod(); - QSignalSpy spy(api, &SyncManager::dataDownloaded); - spy.wait(timeout); - api->loadDataFromDB(); - api->syncDataFromColnodToDB(); - api->syncDataFromDBToColnod(); - QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod); - processSpy.wait(timeout); - QSignalSpy finish(api, &SyncManager::syncFinished); - finish.wait(timeout); - qDebug() << "All right, at least should be."; +// Logger::log("ahoj"); +// api->loadDataFromColnod(); +// QSignalSpy spy(api, &SyncManager::dataDownloaded); +// spy.wait(timeout); +// api->loadDataFromDB(); +// api->syncDataFromColnodToDB(); +// api->syncDataFromDBToColnod(); +// QSignalSpy processSpy(api, &SyncManager::dataUpdatedToColnod); +// processSpy.wait(timeout); +// QSignalSpy finish(api, &SyncManager::syncFinished); +// finish.wait(timeout); +// qDebug() << "All right, at least should be."; } void ComplexTest::testingStuff() @@ -196,4 +196,4 @@ std::shared_ptr ComplexTest::getTestToken() return token; } -QTEST_MAIN(ComplexTest) +//QTEST_MAIN(ComplexTest) diff --git a/test/unitTests/unittest.h b/test/unitTests/unittest.h index 0b2b5fe..0e29652 100644 --- a/test/unitTests/unittest.h +++ b/test/unitTests/unittest.h @@ -44,6 +44,8 @@ private slots: private: + std::shared_ptr getTestToken(); + //QString host = "http://localhost:8080"; //colnod server (ssh -L 8080:192.168.254.11:8443 penta-master) QString host = "https://192.168.1.3:8443"; //local testing server QString password = "spaceti1"; From c945bccafa688e609b1d8a5787f4d8dc29cd5fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Fischer?= Date: Thu, 7 Nov 2019 09:13:25 +0100 Subject: [PATCH 23/23] repair --- src/colnod/requestmanager.cpp | 4 -- test/unitTests/complextest.cpp | 109 +-------------------------------- test/unitTests/complextest.h | 5 -- 3 files changed, 3 insertions(+), 115 deletions(-) diff --git a/src/colnod/requestmanager.cpp b/src/colnod/requestmanager.cpp index ebfdefb..5d0e79c 100644 --- a/src/colnod/requestmanager.cpp +++ b/src/colnod/requestmanager.cpp @@ -9,11 +9,7 @@ RequestManager::RequestManager() std::shared_ptr RequestManager::login() { Q_ASSERT(!loginResponse); -<<<<<<< src/colnod/requestmanager.cpp loginResponse = std::make_shared(); -======= - loginResponse = new Response; ->>>>>>> src/colnod/requestmanager.cpp QNetworkRequest request; QString hash = encryptedPassword(this->password); authHeader = getLoginHeader(this->user, hash); diff --git a/test/unitTests/complextest.cpp b/test/unitTests/complextest.cpp index 915dc90..3d84699 100644 --- a/test/unitTests/complextest.cpp +++ b/test/unitTests/complextest.cpp @@ -2,7 +2,6 @@ void ComplexTest::initTestCase() { -<<<<<<< test/unitTests/complextest.cpp // auto reqMan1 = new RequestManager; // QList ids; // ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); @@ -13,17 +12,6 @@ void ComplexTest::initTestCase() // deleteTokensRespSpy.wait(timeout); // QTest::qWait(2500); // Logger *logger = Logger::getLogger(); -======= - auto reqMan1 = new RequestManager; - QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); - Response* deleteTokensResp = reqMan1->deleteTokens(&ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); - QTest::qWait(2500); ->>>>>>> test/unitTests/complextest.cpp start = QDateTime::currentMSecsSinceEpoch()-2000; api = new SyncManager(); qDebug() << start; @@ -33,7 +21,7 @@ void ComplexTest::initTestCase() void ComplexTest::cleanupTestCase() { -<<<<<<< test/unitTests/complextest.cpp + // QList ids; // ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); // ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); @@ -43,22 +31,10 @@ void ComplexTest::cleanupTestCase() // QCOMPARE(deleteTokensRespSpy.count(), 0); // deleteTokensRespSpy.wait(timeout); // QCOMPARE(deleteTokensRespSpy.count(), 1); -======= - QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - ids.append("3ff23b41-3da3-4b33-82ce-d8e2d8c9a546"); - auto reqMan = new RequestManager; - Response* deleteTokensResp = reqMan->deleteTokens(&ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); - QCOMPARE(deleteTokensRespSpy.count(), 1); ->>>>>>> test/unitTests/complextest.cpp } void ComplexTest::complexTest() { -<<<<<<< test/unitTests/complextest.cpp // // LOGIN_BEGIN // reqMan = new RequestManager; // QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); @@ -136,87 +112,6 @@ void ComplexTest::complexTest() // QCOMPARE(loginRespSpy.count(), 1); // QCOMPARE(getNumOfSubjects(), numOfSubjects); // QCOMPARE(getNumOfTokens(), numOfTokens); -======= - // LOGIN_BEGIN - reqMan = new RequestManager; - QSignalSpy loginSpy(reqMan, &RequestManager::successLogin); - QVERIFY(reqMan); - Response* loginResp = reqMan->login(); - QSignalSpy loginRespSpy(loginResp, &Response::ready); - QCOMPARE(loginSpy.count(), 0); - QCOMPARE(loginRespSpy.count(), 0); - loginSpy.wait(10000); - QCOMPARE(loginResp->getStatusCode(), 200); // HTTP status code check - QCOMPARE(loginSpy.count(), 1); // Checking multiple calls - QCOMPARE(loginRespSpy.count(), 1); - auto doc0 = getJsonDoc(loginResp->getJson()); - QVERIFY(doc0.object()["id"].isString()); - // LOGIN_END - - // NUMBER_OF_SUBJECTS_AND_TOKENS_BEGIN - int numOfSubjects = getNumOfSubjects(); - QCOMPARE(numOfSubjects, 2893); // should be still the same, if false db has been changed - int numOfTokens = getNumOfTokens(); - QCOMPARE(numOfTokens, 2881); // should be still the same, if false db has been changed, or deleteTokens didnt work in previous test - // NUMBER_OF_SUBJECTS_AND_TOKENS_END - - - // ADD_TOKENS_CHECK_BEGIN - QList> tokens; - tokens.append(getTestToken()); - Response* setTokensResp = reqMan->setTokens(&tokens); - QSignalSpy setTokensRespSpy(setTokensResp, &Response::ready); - QCOMPARE(setTokensRespSpy.count(), 0); - setTokensRespSpy.wait(10000); - QCOMPARE(setTokensRespSpy.count(), 1); - QCOMPARE(setTokensResp->getStatusCode(), 200); - QCOMPARE(getNumOfTokens(), numOfTokens + 1); - // ADD_TOKENS_CHEK_END - - // CHECK_UPDATED_TOKENS_BEGIN - Response* getTokensUpdatedResp = reqMan->getTokensUpdated(start); - //start = QDateTime::currentMSecsSinceEpoch(); - QSignalSpy getTokensUpdatedRespSpy(getTokensUpdatedResp, &Response::ready); - QCOMPARE(getTokensUpdatedRespSpy.count(), 0); - getTokensUpdatedRespSpy.wait(10000); - QCOMPARE(getTokensUpdatedResp->getStatusCode(), 200); - QCOMPARE(getTokensUpdatedRespSpy.count(), 1); - auto doc1 = getJsonDoc(getTokensUpdatedResp->getJson()); - QCOMPARE(doc1.object()["items"].toArray().size(), 1); - // CHECK_UPDATED_TOKENS_END - - // DELETE_TOKENS_CHECK_BEGIN - QList ids; - ids.append("582c982d-6fd7-4856-8548-7ce542791c7a"); - Response* deleteTokensResp = reqMan->deleteTokens(&ids); - QSignalSpy deleteTokensRespSpy(deleteTokensResp, &Response::ready); - QCOMPARE(deleteTokensRespSpy.count(), 0); - deleteTokensRespSpy.wait(10000); - QCOMPARE(deleteTokensRespSpy.count(), 1); - QCOMPARE(deleteTokensResp->getStatusCode(), 200); - // DELETE_TOKENS_CHECK_END - - // CHECK_DELETED_TOKENS_BEGIN - Response* getTokensDeletedResp = reqMan->getTokensDeleted(start); - start = QDateTime::currentMSecsSinceEpoch(); - QSignalSpy getTokensDeletedRespSpy(getTokensDeletedResp, &Response::ready); - QCOMPARE(getTokensDeletedRespSpy.count(), 0); - getTokensDeletedRespSpy.wait(10000); - QCOMPARE(getTokensDeletedResp->getStatusCode(), 200); - QCOMPARE(getTokensDeletedRespSpy.count(), 1); - auto doc2 = getJsonDoc(getTokensDeletedResp->getJson()); - QCOMPARE(doc2.object()["items"].toArray().size(), 1); - QVERIFY(doc2.object()["items"].toArray().contains("582c982d-6fd7-4856-8548-7ce542791c7a")); - // CHECK_DELETED_TOKENS_END - - - - // LAST_TESTS (for sure) - QCOMPARE(loginSpy.count(), 1); // Checking multiple calls - QCOMPARE(loginRespSpy.count(), 1); - QCOMPARE(getNumOfSubjects(), numOfSubjects); - QCOMPARE(getNumOfTokens(), numOfTokens); ->>>>>>> test/unitTests/complextest.cpp } void ComplexTest::fullSync() @@ -260,6 +155,7 @@ void ComplexTest::testingStuff() // HELPFUL_FUNCTIONS int ComplexTest::getNumOfSubjects() { + auto reqMan = new RequestManager; Response* subjectsResp = reqMan->getSubjects(); QSignalSpy subjectsRespSpy(subjectsResp, &Response::ready); subjectsRespSpy.wait(timeout); @@ -269,6 +165,7 @@ int ComplexTest::getNumOfSubjects() int ComplexTest::getNumOfTokens() { + auto reqMan = new RequestManager; Response* tokensResp = reqMan->getTokens(); QSignalSpy tokensRespSpy(tokensResp, &Response::ready); tokensRespSpy.wait(timeout); diff --git a/test/unitTests/complextest.h b/test/unitTests/complextest.h index dff7f19..38ed1be 100644 --- a/test/unitTests/complextest.h +++ b/test/unitTests/complextest.h @@ -33,13 +33,8 @@ private: QString user = "spaceti"; QString password = "spaceti1"; uint64_t start = 0; -<<<<<<< test/unitTests/complextest.h SyncManager* api = nullptr; static constexpr qint16 timeout = 10000; -======= - RequestManager* reqMan = nullptr; - ColnodAPI* api = nullptr; ->>>>>>> test/unitTests/complextest.h };