forked from ondra/colnod-connector
WIP: error handling
This commit is contained in:
parent
a9852b88c1
commit
f1f14bfd3e
@ -39,7 +39,15 @@ void ColnodAPI::downloadData()
|
|||||||
|
|
||||||
void ColnodAPI::processData(const std::shared_ptr<Data> &data)
|
void ColnodAPI::processData(const std::shared_ptr<Data> &data)
|
||||||
{
|
{
|
||||||
|
for (const auto &token : data->updatedTokens) {
|
||||||
|
qInfo(colnod).noquote() << Message::massageTemplate("Updating", "token", "colnod", token->name());
|
||||||
|
}
|
||||||
|
for (const auto &id : data->deletedTokens) {
|
||||||
|
qInfo(colnod).noquote() << Message::massageTemplate("Deleting", "token", "colnod", id);
|
||||||
|
}
|
||||||
|
if (!data->updatedTokens.isEmpty() || !data->deletedTokens.isEmpty()) {
|
||||||
|
qInfo(colnod) << dash;
|
||||||
|
}
|
||||||
qInfo(colnod) << tab << "-> DATA PROCESSED TO COLNOD:";
|
qInfo(colnod) << tab << "-> DATA PROCESSED TO COLNOD:";
|
||||||
qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS UPDATED";
|
qInfo(colnod) << tab << tab << data->updatedTokens.size() << "TOKENS UPDATED";
|
||||||
qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED";
|
qInfo(colnod) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED";
|
||||||
|
|||||||
@ -34,26 +34,35 @@ bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAPI::downloadData()
|
bool DatabaseAPI::downloadData()
|
||||||
{
|
{
|
||||||
|
bool res = true;
|
||||||
auto updatedQuery = mDbMan->createQuery();
|
auto updatedQuery = mDbMan->createQuery();
|
||||||
auto deletedQuery = mDbMan->createQuery();
|
auto deletedQuery = mDbMan->createQuery();
|
||||||
if (!executeQuery(updatedQuery, "SELECT * FROM colnod_token WHERE last_modified > last_update AND deleted = false")) {
|
if (!executeQuery(updatedQuery, "SELECT * FROM colnod_token WHERE last_modified > last_update AND deleted = false")) {
|
||||||
qWarning(database) << "ERROR during geting new/updated tokens from db.";
|
qWarning(database) << "ERROR during geting new/updated tokens from db.";
|
||||||
|
res = false;
|
||||||
}
|
}
|
||||||
if (!executeQuery(deletedQuery, "SELECT id FROM colnod_token WHERE last_modified > last_update AND deleted = true")) {
|
if (!executeQuery(deletedQuery, "SELECT id FROM colnod_token WHERE last_modified > last_update AND deleted = true")) {
|
||||||
qWarning(database) << "ERROR during geting marked tokens for deletion from db.";
|
qWarning(database) << "ERROR during geting marked tokens for deletion from db.";
|
||||||
|
res = false;
|
||||||
}
|
}
|
||||||
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
|
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAPI::processData(const std::shared_ptr<Data> &data)
|
bool DatabaseAPI::processData(const std::shared_ptr<Data> &data)
|
||||||
{
|
{
|
||||||
uploadTokens(data->updatedTokens);
|
uploadTokens(data->updatedTokens);
|
||||||
uploadSubjects(data->updatedSubjects);
|
uploadSubjects(data->updatedSubjects);
|
||||||
deleteItems(data->deletedTokens, "colnod_token");
|
deleteItems(data->deletedTokens, "colnod_token");
|
||||||
deleteItems(data->deletedSubjects, "colnod_subject");
|
deleteItems(data->deletedSubjects, "colnod_subject");
|
||||||
|
if ( !data->updatedTokens.isEmpty() ||
|
||||||
|
!data->updatedSubjects.isEmpty() ||
|
||||||
|
!data->deletedTokens.isEmpty() ||
|
||||||
|
!data->deletedSubjects.isEmpty()) {
|
||||||
|
qInfo(database) << dash;
|
||||||
|
}
|
||||||
qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:";
|
qInfo(database) << tab << "-> DATA PROCESSED TO DATABASE:";
|
||||||
qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED";
|
qInfo(database) << tab << tab << data->updatedTokens.size() << "TOKENS ADDED/UPDATED";
|
||||||
qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED";
|
qInfo(database) << tab << tab << data->deletedTokens.size() << "TOKENS DELETED";
|
||||||
@ -147,6 +156,8 @@ qint64 DatabaseAPI::getNow()
|
|||||||
emit error();
|
emit error();
|
||||||
}
|
}
|
||||||
query.next();
|
query.next();
|
||||||
|
qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||||
|
qDebug() << "Current time:" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||||
return query.value(0).toLongLong();
|
return query.value(0).toLongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +181,7 @@ void DatabaseAPI::initNewTokens()
|
|||||||
uploadTokens(tokensToInit);
|
uploadTokens(tokensToInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAPI::uploadTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
|
bool DatabaseAPI::uploadTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
|
||||||
{
|
{
|
||||||
auto query = mDbMan->createQuery();
|
auto query = mDbMan->createQuery();
|
||||||
for (const auto &token : tokens) {
|
for (const auto &token : tokens) {
|
||||||
@ -185,11 +196,13 @@ void DatabaseAPI::uploadTokens(const QHash<QString, std::shared_ptr<Token>> &tok
|
|||||||
if (!query.isActive()) {
|
if (!query.isActive()) {
|
||||||
mValid = false;
|
mValid = false;
|
||||||
qWarning(database) << "ERROR durning inserting/updating of token:" << token->name();
|
qWarning(database) << "ERROR durning inserting/updating of token:" << token->name();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAPI::uploadSubjects(const QHash<QString, std::shared_ptr<Subject>> &subjects)
|
bool DatabaseAPI::uploadSubjects(const QHash<QString, std::shared_ptr<Subject>> &subjects)
|
||||||
{
|
{
|
||||||
auto query = mDbMan->createQuery();
|
auto query = mDbMan->createQuery();
|
||||||
for (const auto &subject : subjects) {
|
for (const auto &subject : subjects) {
|
||||||
@ -217,11 +230,13 @@ void DatabaseAPI::uploadSubjects(const QHash<QString, std::shared_ptr<Subject>>
|
|||||||
if (!query.isActive()) {
|
if (!query.isActive()) {
|
||||||
mValid = false;
|
mValid = false;
|
||||||
qWarning(database) << "ERROR durning inserting/updating of subject attribute:" << subject->name();
|
qWarning(database) << "ERROR durning inserting/updating of subject attribute:" << subject->name();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseAPI::deleteItems(const QList<QString> &ids, const QString &tableName)
|
bool DatabaseAPI::deleteItems(const QList<QString> &ids, const QString &tableName)
|
||||||
{
|
{
|
||||||
auto query = mDbMan->createQuery();
|
auto query = mDbMan->createQuery();
|
||||||
QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||||
@ -233,18 +248,22 @@ void DatabaseAPI::deleteItems(const QList<QString> &ids, const QString &tableNam
|
|||||||
query.bindValue(":now", nowString);
|
query.bindValue(":now", nowString);
|
||||||
if (!executeQuery(query)) {
|
if (!executeQuery(query)) {
|
||||||
qWarning(database) << "ERROR during marking token as deleted:" << id;
|
qWarning(database) << "ERROR during marking token as deleted:" << id;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Token> DatabaseAPI::getToken(const QString &id)
|
std::shared_ptr<Token> DatabaseAPI::getToken(QString &id)
|
||||||
{
|
{
|
||||||
auto query = mDbMan->createQuery();
|
auto query = mDbMan->createQuery();
|
||||||
query.prepare("SELECT * FROM colnod_token WHERE id = :id");
|
query.prepare("SELECT * FROM colnod_token WHERE d = :id");
|
||||||
query.bindValue(":id", id);
|
query.bindValue(":id", id);
|
||||||
if (!executeQuery(query)) {
|
if (!executeQuery(query)) {
|
||||||
qCritical(database) << "ERROR during accessing existing tokens";
|
qCritical(database) << "ERROR during accessing existing tokens. EXIT";
|
||||||
emit error();
|
emit error();
|
||||||
|
id = QString();
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto list = utils->tableFromQuery<Token>(query);
|
auto list = utils->tableFromQuery<Token>(query);
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
@ -252,10 +271,13 @@ std::shared_ptr<Token> DatabaseAPI::getToken(const QString &id)
|
|||||||
return list.at(0);
|
return list.at(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseAPI::isAlreadyDeleted(const QString &id)
|
bool DatabaseAPI::isAlreadyDeleted(QString &id)
|
||||||
{
|
{
|
||||||
auto token = getToken(id);
|
auto token = getToken(id);
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
if (id.isEmpty()) {
|
||||||
|
|
||||||
|
}
|
||||||
qWarning(database) << "Token deleted in colnod doesn't exists in db, will be noted as already deleted in stats";
|
qWarning(database) << "Token deleted in colnod doesn't exists in db, will be noted as already deleted in stats";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -270,14 +292,14 @@ bool DatabaseAPI::isValid()
|
|||||||
return mValid;
|
return mValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseAPI::exists(const QString &id, const QString &tableName)
|
int DatabaseAPI::exists(const QString &id, const QString &tableName)
|
||||||
{
|
{
|
||||||
auto query = mDbMan->createQuery();
|
auto query = mDbMan->createQuery();
|
||||||
query.prepare(QString("SELECT 1 FROM %1 WHERE id = :id").arg(tableName));
|
query.prepare(QString("SELECT 1 FROM %1 WHERE id = :id").arg(tableName));
|
||||||
query.bindValue(":id", id);
|
query.bindValue(":id", id);
|
||||||
if (!executeQuery(query)) {
|
if (!executeQuery(query)) {
|
||||||
qCritical(database) << "ERROR during accessing existing tokens. EXIT(1)";
|
qCritical(database) << "ERROR during accessing existing tokens. EXIT(1)";
|
||||||
emit error();
|
return -1;
|
||||||
}
|
}
|
||||||
return query.next();
|
return query.next();
|
||||||
}
|
}
|
||||||
@ -289,7 +311,7 @@ qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
|
|||||||
query.bindValue(":id", id);
|
query.bindValue(":id", id);
|
||||||
if (!executeQuery(query)) {
|
if (!executeQuery(query)) {
|
||||||
qCritical(database) << "ERROR during accessing existing tokens. EXIT(1)";
|
qCritical(database) << "ERROR during accessing existing tokens. EXIT(1)";
|
||||||
emit error();
|
return -1;
|
||||||
}
|
}
|
||||||
return static_cast<qint16>(query.size());
|
return static_cast<qint16>(query.size());
|
||||||
}
|
}
|
||||||
@ -301,7 +323,7 @@ QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
|
|||||||
query.bindValue(":tokenId", tokenId);
|
query.bindValue(":tokenId", tokenId);
|
||||||
if (!executeQuery(query)) {
|
if (!executeQuery(query)) {
|
||||||
qCritical(database) << "ERROR during accessing existing subject. EXIT(1)";
|
qCritical(database) << "ERROR during accessing existing subject. EXIT(1)";
|
||||||
emit error();
|
return "error";
|
||||||
}
|
}
|
||||||
if (query.next())
|
if (query.next())
|
||||||
return query.value(0).toString();
|
return query.value(0).toString();
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "serversdk/databasetable.h"
|
#include "serversdk/databasetable.h"
|
||||||
#include "serversdk/databaseutils.h"
|
#include "serversdk/databaseutils.h"
|
||||||
#include "serversdk/logger.h"
|
#include "serversdk/logger.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(database)
|
Q_DECLARE_LOGGING_CATEGORY(database)
|
||||||
|
|
||||||
@ -21,8 +22,8 @@ public:
|
|||||||
|
|
||||||
bool executeQuery(QSqlQuery &query, const QString &statement = QString());
|
bool executeQuery(QSqlQuery &query, const QString &statement = QString());
|
||||||
|
|
||||||
void downloadData();
|
bool downloadData();
|
||||||
void processData(const std::shared_ptr<Data> &data);
|
bool processData(const std::shared_ptr<Data> &data);
|
||||||
qint64 getLastSync();
|
qint64 getLastSync();
|
||||||
void setLastSync(qint64 timestamp);
|
void setLastSync(qint64 timestamp);
|
||||||
void setLastUpdate(const QHash<QString, std::shared_ptr<Token> > &tokens);
|
void setLastUpdate(const QHash<QString, std::shared_ptr<Token> > &tokens);
|
||||||
@ -32,18 +33,18 @@ public:
|
|||||||
void initNewTokens();
|
void initNewTokens();
|
||||||
|
|
||||||
// process data
|
// process data
|
||||||
void uploadTokens(const QHash<QString, std::shared_ptr<Token> > &tokens);
|
bool uploadTokens(const QHash<QString, std::shared_ptr<Token> > &tokens);
|
||||||
void uploadSubjects(const QHash<QString, std::shared_ptr<Subject> > &subjects);
|
bool uploadSubjects(const QHash<QString, std::shared_ptr<Subject> > &subjects);
|
||||||
void deleteItems(const QList<QString> &ids, const QString &tableName);
|
bool deleteItems(const QList<QString> &ids, const QString &tableName);
|
||||||
|
|
||||||
std::shared_ptr<Token> getToken(const QString &id);
|
std::shared_ptr<Token> getToken(QString &id);
|
||||||
|
|
||||||
bool isAlreadyDeleted(const QString &id);
|
bool isAlreadyDeleted(QString &id);
|
||||||
|
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool exists(const QString &id, const QString &tableName);
|
int exists(const QString &id, const QString &tableName);
|
||||||
|
|
||||||
QSqlQuery getUpdatedTokens();
|
QSqlQuery getUpdatedTokens();
|
||||||
std::shared_ptr<Data> composeData(const QSqlQuery &updatedQuery, QSqlQuery &deletedQuery);
|
std::shared_ptr<Data> composeData(const QSqlQuery &updatedQuery, QSqlQuery &deletedQuery);
|
||||||
|
|||||||
@ -37,7 +37,7 @@ bool SyncManager::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SyncManager::run()
|
bool SyncManager::run()
|
||||||
{
|
{
|
||||||
qint64 syncBegin = database->getNow();
|
qint64 syncBegin = database->getNow();
|
||||||
|
|
||||||
@ -79,8 +79,9 @@ void SyncManager::run()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncManager::downloadData()
|
bool SyncManager::downloadData()
|
||||||
{
|
{
|
||||||
|
bool res = true;
|
||||||
qInfo(syncmanager) << equals;
|
qInfo(syncmanager) << equals;
|
||||||
qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN";
|
qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN";
|
||||||
qInfo(syncmanager) << dash;
|
qInfo(syncmanager) << dash;
|
||||||
@ -89,12 +90,17 @@ void SyncManager::downloadData()
|
|||||||
|
|
||||||
connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
|
connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
|
||||||
connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
|
connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
|
||||||
database->downloadData();
|
if (!database->downloadData()) {
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
|
||||||
colnod->downloadData();
|
colnod->downloadData();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
|
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
|
||||||
void SyncManager::prepareData()
|
bool SyncManager::prepareData()
|
||||||
{
|
{
|
||||||
qInfo(syncmanager) << equals;
|
qInfo(syncmanager) << equals;
|
||||||
qInfo(syncmanager) << "PREPARING DATA -> BEGIN";
|
qInfo(syncmanager) << "PREPARING DATA -> BEGIN";
|
||||||
@ -176,9 +182,10 @@ void SyncManager::prepareData()
|
|||||||
|
|
||||||
qInfo(syncmanager) << "PREPARING DATA -> FINISHED";
|
qInfo(syncmanager) << "PREPARING DATA -> FINISHED";
|
||||||
qInfo(syncmanager) << equals;
|
qInfo(syncmanager) << equals;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncManager::processData()
|
bool SyncManager::processData()
|
||||||
{
|
{
|
||||||
qInfo(syncmanager) << equals;
|
qInfo(syncmanager) << equals;
|
||||||
qInfo(syncmanager) << "PROCESSING DATA -> BEGIN";
|
qInfo(syncmanager) << "PROCESSING DATA -> BEGIN";
|
||||||
@ -189,6 +196,7 @@ void SyncManager::processData()
|
|||||||
database->processData(colnodDataToProcess);
|
database->processData(colnodDataToProcess);
|
||||||
connect(colnod.get(), &ColnodAPI::dataProcessFinished, this, &SyncManager::dataProcessFinished);
|
connect(colnod.get(), &ColnodAPI::dataProcessFinished, this, &SyncManager::dataProcessFinished);
|
||||||
colnod->processData(databaseDataToProcess);
|
colnod->processData(databaseDataToProcess);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncManager::updateLastUpdate(qint64 syncBegin)
|
void SyncManager::updateLastUpdate(qint64 syncBegin)
|
||||||
|
|||||||
@ -8,17 +8,16 @@ Q_DECLARE_LOGGING_CATEGORY(syncmanager)
|
|||||||
class SyncManager : public QObject
|
class SyncManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SyncManager(bool dryMode);
|
explicit SyncManager(bool dryMode, const std::function<void()> &onError = nullptr);
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
void run();
|
bool run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void downloadData();
|
bool downloadData();
|
||||||
void prepareData();
|
bool prepareData();
|
||||||
void processData();
|
bool processData();
|
||||||
void updateLastUpdate(qint64 syncBegin);
|
void updateLastUpdate(qint64 syncBegin);
|
||||||
|
|
||||||
|
|
||||||
@ -32,6 +31,8 @@ signals:
|
|||||||
void dataProcessFinished();
|
void dataProcessFinished();
|
||||||
void syncFinished();
|
void syncFinished();
|
||||||
|
|
||||||
|
void error();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<ColnodAPI> colnod;
|
std::shared_ptr<ColnodAPI> colnod;
|
||||||
std::shared_ptr<DatabaseAPI> database;
|
std::shared_ptr<DatabaseAPI> database;
|
||||||
@ -47,4 +48,6 @@ private:
|
|||||||
|
|
||||||
int dataAmount = 0;
|
int dataAmount = 0;
|
||||||
bool mDryMode;
|
bool mDryMode;
|
||||||
|
|
||||||
|
std::function<void()> onError = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user