Finished Info output

This commit is contained in:
Ondřej Fischer 2019-11-21 10:39:55 +01:00
parent 2ce5a025a9
commit 80c550ff03
8 changed files with 121 additions and 46 deletions

View File

@ -126,6 +126,7 @@ void ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
emit partOfDataProcessFinished();
}
else {
qWarning(colnod) << "Tokens wasn't updated";
// TODO: error: data wasnt upload to colnod
}
});
@ -141,6 +142,7 @@ void ColnodAPI::deleteTokens(const QList<QString> &ids)
emit partOfDataProcessFinished();
}
else {
qWarning(colnod) << "Tokens wasn't deleted";
// TODO: error: data wasnt upload to colnod
}
});
@ -188,12 +190,12 @@ void ColnodAPI::areDataReady()
{
if (++amountData == 4) {
qDebug(colnod) << "COLNOD DATA:";
qDebug(colnod) << TAB << data->updatedTokens.size() << "TOKENS TO UPDATE";
qDebug(colnod) << TAB << data->deletedTokens.size() << "TOKENS TO DELETE";
qDebug(colnod) << TAB << data->updatedSubjects.size() << "SUBJECTS TO UPDATE";
qDebug(colnod) << TAB << data->deletedSubjects.size() << "SUBJECTS TO DELETE";
qDebug(colnod) << UNDERSCORE << endl;
qInfo(colnod) << TAB << "-> COLNOD DATA:";
qInfo(colnod) << TAB << TAB << data->updatedTokens.size() << "TOKENS WERE MODIFIED";
qInfo(colnod) << TAB << TAB << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION";
qInfo(colnod) << TAB << TAB << data->updatedSubjects.size() << "SUBJECTS WERE MODIFIED";
qInfo(colnod) << TAB << TAB << data->deletedSubjects.size() << "SUBJECTS MARKED FOR DELETION";
qInfo(colnod) << DASH;
emit downloadDataFinished(data);
newData();
@ -202,9 +204,15 @@ void ColnodAPI::areDataReady()
void ColnodAPI::isDataProcessFinished()
{
if (++amountProccessesFinished == 2)
if (++amountProccessesFinished == 2) {
qInfo(colnod) << TAB << "-> DATA PROCESSED TO COLNOD:";
qInfo(colnod) << TAB << TAB << data->updatedTokens.size() << "TOKENS UPDATED";
qInfo(colnod) << TAB << TAB << data->deletedTokens.size() << "TOKENS DELETED";
qInfo(colnod) << DASH;
emit dataProcessFinished();
}
}
void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData)
{

View File

@ -27,6 +27,7 @@ class AuthToken : public serversdk::DatabaseTable {
class Timestamp : public serversdk::DatabaseTable {
Q_OBJECT
TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0)
public:
QString toDateString()
{
return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz");

View File

@ -21,10 +21,10 @@ bool DatabaseAPI::open()
void DatabaseAPI::downloadData()
{
auto updatedQuery = mDbMan->execPlainSql("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = false");
auto updatedQuery = mDbMan->execPlainSql("SELECT * "
"FROM colnod_token WHERE last_modified > last_update AND deleted = false");
auto deletedQuery = mDbMan->execPlainSql("SELECT id "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = true");
"FROM colnod_token WHERE last_modified > last_update AND deleted = true");
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
}
@ -34,24 +34,31 @@ void DatabaseAPI::processData(std::shared_ptr<Data> data)
uploadSubjects(data->updatedSubjects);
deleteItems(data->deletedTokens, "colnod_token");
deleteItems(data->deletedSubjects, "colnod_subject");
qInfo(database) << TAB << "-> DATA PROCESSED TO DATABASE:";
qInfo(database) << TAB << TAB << data->updatedTokens.size() << "TOKENS UPDATED";
qInfo(database) << TAB << TAB << data->deletedTokens.size() << "TOKENS DELETED";
qInfo(database) << TAB << TAB << data->updatedSubjects.size() << "SUBJECTS UPDATED";
qInfo(database) << TAB << TAB << data->deletedSubjects.size() << "SUBJECTS DELETED";
qInfo(database) << DASH;
}
std::shared_ptr<Data> DatabaseAPI::composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery)
{
auto data = std::make_shared<Data>();
while (updatedQuery.next()) {
auto token = std::make_shared<Token>();
token->fromSQLRecord(updatedQuery);
auto list = utils->tableFromQuery<Token>(updatedQuery);
for (const auto &token : list) {
data->updatedTokens.insert(token->id(), token);
}
while (deletedQuery.next()) {
data->deletedTokens.append(deletedQuery.value(0).toString());
}
qDebug(database) << "DATABASE DATA:";
qDebug(database) << TAB << data->updatedTokens.size() << "TOKENS TO UPDATE";
qDebug(database) << TAB << data->deletedTokens.size() << "TOKENS TO DELETE";
qDebug(database) << DASH ;
qInfo(database) << TAB << "-> DATABASE DATA:";
qInfo(database) << TAB << TAB << data->updatedTokens.size() << "TOKENS WERE MODIFIED";
qInfo(database) << TAB << TAB << data->deletedTokens.size() << "TOKENS MARKED FOR DELETION";
qInfo(database) << DASH ;
return data;
@ -85,6 +92,10 @@ void DatabaseAPI::setLastUpdate(QHash<QString, std::shared_ptr<Token>> tokens)
query.bindValue(":id", token->id());
mDbMan->executeQuery(query);
}
qInfo(database) << EQUALS;
qInfo(database) << "Synchronize last update in database with colnod";
qInfo(database) << EQUALS;
}
qint64 DatabaseAPI::getNow()
@ -112,7 +123,6 @@ void DatabaseAPI::initNewTokens()
void DatabaseAPI::uploadTokens(QHash<QString, std::shared_ptr<Token>> tokens)
{
// TODO:
auto query = mDbMan->createQuery();
for (const auto &token : tokens) {
if (exists(token->id(), "colnod_token")) {
@ -127,10 +137,17 @@ void DatabaseAPI::uploadTokens(QHash<QString, std::shared_ptr<Token>> tokens)
void DatabaseAPI::uploadSubjects(QHash<QString, std::shared_ptr<Subject>> subjects)
{
// TODO:
auto query = mDbMan->createQuery();
for (const auto &subject : subjects) {
// TODO: attributes
for (const auto &attribute : subject->getAttributes()) {
if (exists(attribute->id(), "colnod_subject_attribute")) {
query = utils->updateTable(attribute.get(), "colnod_subject_attribute");
}
else {
query = utils->insertIntoTable(attribute.get(), "colnod_subject_attribute");
}
query = mDbMan->executeQuery(query);
}
// NOTE: about actions
if (exists(subject->id(), "colnod_subject")) {
query = utils->updateTable(subject.get(), "colnod_subject");
@ -144,7 +161,6 @@ void DatabaseAPI::uploadSubjects(QHash<QString, std::shared_ptr<Subject>> subjec
void DatabaseAPI::deleteItems(QList<QString> ids, const QString &tableName)
{
// TODO:
auto query = mDbMan->createQuery();
QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz");
for (const auto &id : ids) {
@ -155,18 +171,17 @@ void DatabaseAPI::deleteItems(QList<QString> ids, const QString &tableName)
}
}
//TODO: return whole token
QDateTime DatabaseAPI::getLastUpdate(const QString &id)
std::shared_ptr<Token> DatabaseAPI::getLastUpdate(const QString &id)
{
auto query = mDbMan->createQuery();
query.prepare("SELECT last_update FROM colnod_token WHERE id = :id");
query.bindValue(":id", id);
mDbMan->executeQuery(query);
if (query.next()) {
return query.value(0).toDateTime();
return utils->tableFromQuery<Token>(query).at(0);
}
else {
return QDateTime();
return nullptr;
}
}

View File

@ -33,7 +33,7 @@ public:
void uploadSubjects(QHash<QString, std::shared_ptr<Subject> > subjects);
void deleteItems(QList<QString> ids, const QString &tableName);
QDateTime getLastUpdate(const QString &id);
std::shared_ptr<Token> getLastUpdate(const QString &id);
private:
bool exists(const QString &id, const QString &tableName);

View File

@ -14,6 +14,7 @@ bool Subject::fromJson(const QByteArray &data)
for (auto key : attr.keys()) {
auto newAtr = std::make_shared<SubjectAttribute>();
newAtr->setId(id + " " + key);
newAtr->setSubjectId(id);
newAtr->setAttributeKey(key);
newAtr->setAttributeValue(attr.value(key).toString());
@ -25,3 +26,8 @@ bool Subject::fromJson(const QByteArray &data)
bool res = fromVariantMap(variant);
return res;
}
QList<std::shared_ptr<SubjectAttribute> > Subject::getAttributes()
{
return attributes;
}

View File

@ -30,6 +30,8 @@ public:
explicit Subject(const QString& name);
bool fromJson(const QByteArray &data) override;
QList<std::shared_ptr <SubjectAttribute>> getAttributes();
private:
QList<std::shared_ptr <SubjectAttribute>> attributes;

View File

@ -25,17 +25,28 @@ bool SyncManager::init()
void SyncManager::run()
{
qint64 syncBegin = database->getNow();
qInfo(syncmanager) << EQUALS;
qInfo(syncmanager) << "SYNCHRONIZATION BEGIN";
database->initNewTokens();
downloadData();
connect(this, &SyncManager::dataReady, [=](){
qDebug(syncmanager) << "FINISH";
prepareData();
connect(this, &SyncManager::dataProcessFinished, [=](){
updateLastUpdate(syncBegin);
connect(this, &SyncManager::syncFinished, [=](){
database->setLastSync(syncBegin);
qInfo(syncmanager) << "Update last synchronization time to time of this sync ("
<< QDateTime::fromMSecsSinceEpoch(syncBegin).toString("yyyy-MM-dd hh:mm:ss.zzz")
<< ")";
qInfo(syncmanager) << EQUALS;
qInfo(syncmanager) << "SYNCHRONIZATION FINISHED";
qInfo(syncmanager) << EQUALS;
QCoreApplication::exit();
});
});
@ -46,9 +57,11 @@ void SyncManager::run()
void SyncManager::downloadData()
{
qInfo(syncmanager) << EQUALS << endl;
qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN" << endl;
qInfo(syncmanager) << UNDERSCORE;
qInfo(syncmanager) << EQUALS;
qInfo(syncmanager) << "DOWNLOADING DATA -> BEGIN";
qInfo(syncmanager) << DASH;
qInfo(syncmanager) << "Modified data since last synchronization (" << mlastSync.toDateString() << "):";
qInfo(syncmanager) << DASH;
connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
@ -59,44 +72,74 @@ void SyncManager::downloadData()
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
void SyncManager::prepareData()
{
qInfo(syncmanager) << EQUALS;
qInfo(syncmanager) << "PREPARING DATA -> BEGIN";
qInfo(syncmanager) << DASH;
qInfo(syncmanager) << "Resolve conflicts ( changes on same item on both Colnod and DB ):";
qInfo(syncmanager) << DASH;
colnodDataToProcess = std::make_shared<Data>(*colnodData);
databaseDataToProcess = std::make_shared<Data>(*databaseData);
QList<QString> idsToDelete;
QList<QString> conflicts;
QList<QString> alreadySynced;
for (const auto &colnodToken : colnodDataToProcess->updatedTokens) {
if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) {
if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) {
idsToDelete.append(colnodToken->id());
conflicts.append(colnodToken->id());
}
continue;
}
auto dbLastUpdate = database->getLastUpdate(colnodToken->id());
if ( !dbLastUpdate.isNull() )
// TODO: compare whole structure of token
if (dbLastUpdate == colnodToken->lastUpdate())
idsToDelete.append(colnodToken->id());
auto token = database->getLastUpdate(colnodToken->id());
if ( !token )
if (token == colnodToken)
alreadySynced.append(colnodToken->id());
}
for (const auto &id : idsToDelete)
for (const auto &id : conflicts)
colnodDataToProcess->updatedTokens.remove(id);
for (const auto &id : alreadySynced)
colnodDataToProcess->updatedTokens.remove(id);
idsToDelete.clear();
qInfo(syncmanager) << TAB << "-> COLNOD DATA - CHANGES:";
qInfo(syncmanager) << TAB << TAB << conflicts.size() << "TOKENS WERE MODIFIED IN DATABASE";
qInfo(syncmanager) << TAB << TAB << alreadySynced.size() << "TOKENS WERE ALREADY SYNCED";
qInfo(syncmanager) << DASH;
conflicts.clear();
for (const auto &databaseToken : databaseData->updatedTokens) {
if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) {
if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken->id()))
idsToDelete.append(databaseToken->id());
conflicts.append(databaseToken->id());
}
}
for (const auto &id : idsToDelete)
for (const auto &id : conflicts)
colnodDataToProcess->updatedTokens.remove(id);
qInfo(syncmanager) << TAB << "-> DATABASE DATA - CHANGES:";
qInfo(syncmanager) << TAB << TAB << conflicts.size() << "TOKENS WERE MODIFIED IN COLNOD";
qInfo(syncmanager) << DASH;
qInfo(syncmanager) << "PREPARING DATA -> FINISHED";
qInfo(syncmanager) << EQUALS;
}
void SyncManager::processData()
{
qInfo(syncmanager) << EQUALS;
qInfo(syncmanager) << "PROCESSING DATA -> BEGIN";
qInfo(syncmanager) << DASH;
qInfo(syncmanager) << "Push changes to both Colnod ad Database:";
qInfo(syncmanager) << DASH;
database->processData(colnodDataToProcess);
connect(colnod.get(), &ColnodAPI::dataProcessFinished, this, &SyncManager::dataProcessFinished);
colnod->processData(databaseDataToProcess);
qInfo(syncmanager) << "PROCESSING DATA -> FINISHED";
qInfo(syncmanager) << EQUALS;
}
void SyncManager::updateLastUpdate(qint64 syncBegin)
@ -112,14 +155,14 @@ void SyncManager::updateLastUpdate(qint64 syncBegin)
void SyncManager::areDataReady()
{
if (++dataAmount == 2)
if (++dataAmount == 2) {
qDebug(syncmanager) << "DOWNLOADING DATA -> FINISHED" << endl << endl;
qDebug(syncmanager) << "DOWNLOADING DATA -> FINISHED";
qDebug(syncmanager) << EQUALS;
qDebug(syncmanager) << EQUALS << endl << endl;
emit dataReady();
}
}
void SyncManager::saveColnodData(const std::shared_ptr<Data> &data)
{

View File

@ -93,7 +93,7 @@ void Token::fromSQLRecord(const QSqlQuery& query)
setNoValidity(query.value(6).toBool());
setEnabled(query.value(3).toBool());
QDateTime date = query.value(4).toDateTime();
setLastUpdate(date); // WARNING: resolve how lastUpdate should me stored
setLastUpdate(date);
setName(query.value(5).toString());
a_timeToLive = query.value(7).toInt();
a_tokenBits = query.value(8).toInt();