diff --git a/src/colnod/data.h b/src/colnod/data.h index 5ef4827..a0f607a 100644 --- a/src/colnod/data.h +++ b/src/colnod/data.h @@ -39,6 +39,14 @@ public: struct PreparedData { +public: + PreparedData() = default; + PreparedData(const std::shared_ptr &database, const std::shared_ptr &colnod) + :databaseData(database), colnodData(colnod) + { + } + + // TODO: make unique_ptr ( neeed because of ColnodAPI ) std::shared_ptr databaseData; std::shared_ptr colnodData; diff --git a/src/colnod/databaseapi.h b/src/colnod/databaseapi.h index 34b125d..8668b2f 100644 --- a/src/colnod/databaseapi.h +++ b/src/colnod/databaseapi.h @@ -48,13 +48,14 @@ public: bool isValid(); + qint16 getNumOfTokensOfSubject(const QString &id); + QString getSubjectNameByTokenId(const QString &tokenId); + private: int exists(const QString &id, const QString &tableName); QSqlQuery getUpdatedTokens(); std::shared_ptr composeData(const QSqlQuery &updatedQuery, QSqlQuery &deletedQuery); - qint16 getNumOfTokensOfSubject(const QString &id); - QString getSubjectNameByTokenId(const QString &tokenId); signals: void downloadDataFinished(std::shared_ptr = std::shared_ptr()); diff --git a/src/colnod/syncmanager.cpp b/src/colnod/syncmanager.cpp index 7d85b64..6e025dd 100644 --- a/src/colnod/syncmanager.cpp +++ b/src/colnod/syncmanager.cpp @@ -49,7 +49,7 @@ bool SyncManager::startSynchronization() qInfo(syncmanager) << equals; qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; - // TODO: check error + // TODO: solve this in prepare data database->initNewTokens(); @@ -63,8 +63,8 @@ bool SyncManager::startSynchronization() colnod->downloadData(Timestamp(syncBegin)); - connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr data) { - if (!data) { + connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr colnodData) { + if (!colnodData) { qCritical(syncmanager) << "Not possible to get correct data from colnod"; QCoreApplication::exit(-1); return; @@ -73,7 +73,7 @@ bool SyncManager::startSynchronization() // NOW I SHOULD HAVE VALID DATA FROM COLNOD // I can process data qDebug(syncmanager) << "I have colnod and database data"; - qDebug(syncmanager) << "updated token count" << data->updatedTokens.count(); + qDebug(syncmanager) << "updated token count" << colnodData->updatedTokens.count(); std::unique_ptr preparedData = prepareDataNew(databaseData, colnodData); if (!preparedData) { @@ -88,11 +88,6 @@ bool SyncManager::startSynchronization() return true; //downloadData(); - auto colnodDataFinished = [=](std::shared_ptr data) { - Q_UNUSED(data) - qDebug() << "Now I can check that I have all data I need"; - }; - //connect(this, &SyncManager::dataReady, processDownloadedData); @@ -104,7 +99,7 @@ bool SyncManager::startSynchronization() qInfo(syncmanager) << "PROCESSING DATA -> FINISHED"; qInfo(syncmanager) << equals; - updateLastUpdate(syncBegin); + updateLastUpdate(syncBegin); // TODO: change to update all attrinutes connect(this, &SyncManager::syncFinished, [=](){ if (database->isValid() && colnod->isValid()) { database->setLastSync(syncBegin); @@ -131,9 +126,90 @@ bool SyncManager::startSynchronization() std::unique_ptr SyncManager::prepareDataNew(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData) { - Q_UNUSED(databaseData); - Q_UNUSED(colnodData); - return nullptr; + auto preparedColnodData = std::make_shared(); + auto preparedDatabaseData = std::make_shared(); + + QList conflicts; + QList alreadySynced; + + for (const auto &colnodToken : colnodData->updatedTokens) { + + // not conflict so add to prepered tokens + if (!databaseData->updatedTokens.contains(colnodToken->id())) { + preparedColnodData->updatedTokens.insert(colnodToken->id(), colnodToken); + continue; + } + + // change in colnod is newer + if (databaseData->updatedTokens.value(colnodToken->id()) < colnodToken) { + preparedColnodData->updatedTokens.insert(colnodToken->id(), colnodToken); + } + else { + conflicts.append(colnodToken->id()); + } + + auto token = database->getToken(colnodToken->id()); + if ( token ) + // alredy synced ( tokens are same ) + if (token == colnodToken) + alreadySynced.append(colnodToken->id()); + } + + for (const auto &id : colnodData->deletedTokens) { + if (!database->isAlreadyDeleted(id)) { + preparedColnodData->deletedTokens.append(id); + } + } + + qInfo(syncmanager) << tab << "-> COLNOD DATA - CHANGES:"; + qInfo(syncmanager) << tab << tab << conflicts.size() << "TOKENS WERE ADDED/UPDATED IN DATABASE AFTER"; + qInfo(syncmanager) << tab << tab << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED"; + qInfo(syncmanager) << tab << tab << colnodData->deletedTokens.size() - preparedColnodData->deletedTokens.size() << "TOKENS WERE ALREADY DELETED"; + qInfo(syncmanager) << dash; + + for (const auto &databaseToken : databaseData->updatedTokens) { + if (databaseToken->name().isEmpty()) { + initNewToken(databaseToken); + } + + // restriction cauesed by colnod rest api + if (databaseToken->description() != "mobile") { + qCritical(syncmanager) << "Token:" << databaseToken->id() << "doesn't have 'mobile' in description, can't be "; + continue; + } + + // no conflict + if (!colnodData->updatedTokens.contains(databaseToken->id())) { + preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); + continue; + } + + // database change is newer + if (databaseToken > colnodData->updatedTokens.value(databaseToken->id())) { + preparedDatabaseData->updatedTokens.insert(databaseToken->id(), databaseToken); + } + } + + qInfo(syncmanager) << tab << "-> DATABASE DATA - CHANGES:"; + qInfo(syncmanager) << tab << tab << databaseData->updatedTokens.size() - preparedColnodData->updatedTokens.size() << "TOKENS WERE ADDED/UPDATED IN COLNOD AFTER"; + qInfo(syncmanager) << dash; + + qInfo(syncmanager) << "PREPARING DATA -> FINISHED"; + qInfo(syncmanager) << equals; + + + auto preparedData = std::make_unique(preparedDatabaseData, preparedColnodData); + return preparedData; +} + +void SyncManager::initNewToken(std::shared_ptr token) +{ + qint16 num = database->getNumOfTokensOfSubject(token->subjectId()); + token->setName(database->getSubjectNameByTokenId(token->id()) + "_mobile_" + QString::number(num + 1)); + token->setDescription("mobile"); + token->setTokenData(token->tokenData().toUpper()); + + qInfo(syncmanager).noquote() << Message::massageTemplate("Inicializing new", "token", "sync manager", token->name()); } std::unique_ptr SyncManager::prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData) diff --git a/src/colnod/syncmanager.h b/src/colnod/syncmanager.h index 21a9749..2d9478d 100644 --- a/src/colnod/syncmanager.h +++ b/src/colnod/syncmanager.h @@ -29,6 +29,8 @@ private: std::unique_ptr prepareDataUsindOld(const std::shared_ptr &databaseData, const std::shared_ptr &colnodData); private: + void initNewToken(std::shared_ptr token); + bool downloadData(); bool prepareData(); bool processData();