Fixed bugs, first working version

This commit is contained in:
Ondřej Fischer 2019-11-06 16:46:49 +01:00
parent c0a016f87b
commit 8364523839
12 changed files with 320 additions and 262 deletions

View File

@ -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();
}

View File

@ -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> 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> 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> 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);

View File

@ -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;
};

View File

@ -1,13 +1,13 @@
#include "datamanager.h"
DataManager::DataManager(const bool &dryMode)
:dryMode(dryMode)
{
db = std::make_shared<DatabaseManager>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode);
//db = std::make_shared<DatabaseManager>("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>();
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<Token>("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<Token>("empty");
tokensToUpdateFromColnodToDB.insert(token->getName(), token);
}
}
@ -66,6 +63,7 @@ void DataManager::fillSubjectsToUpdateColnod(const QString& response)
{
auto subject = std::make_shared<Subject>();
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<Subject>("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>();
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>();
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<QString> 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<QString> 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<Token>();
auto tokenDB = std::make_shared<Token>();
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);
}

View File

@ -38,13 +38,13 @@ public:
void updateLastSync();
bool haveChangedData();
void emptyDatabase();
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateColnod() {return tokensToUpdateFromColnodToDB;}
quint64 getLastModifiedOfToken(const QString &id);
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateFromColnod() {return tokensToUpdateFromColnodToDB;}
QList<QString> getTokensToDeleteColnod() {return tokensFromColnodToDeleteFromDB;}
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateDB() {return tokensToUpdateFromDBToColnod;}
QHash<QString, std::shared_ptr<Token>> getTokensToUpdateFromDB() {return tokensToUpdateFromDBToColnod;}
QList<QString> 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<QString, std::shared_ptr<Token>> allTokensFromColnodById;
QHash<QString, std::shared_ptr<Token>> allTokensFromColnodByName;
QHash<QString, std::shared_ptr<Subject>> subjectsToUpdateFromColnodToDB;
QHash<QString, std::shared_ptr<Token>> tokensToUpdateFromColnodToDB;
QHash<QString, std::shared_ptr<Token>> allTokensFromColnod;
QHash<QString, std::shared_ptr<Subject>> subjectsDB; // in future
QHash<QString, std::shared_ptr<Token>> tokensToUpdateFromDBToColnod;

View File

@ -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;

View File

@ -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{};
};

View File

@ -24,8 +24,6 @@ public:
void setPin(const QString &pin);
const QSet<QString> &getPinFlags() const;
void setPinFlags(const QSet<QString> &pinFlags);
// const QList<QPointer<Attribute>> &getAtr() const;
// void setAtr(const QList<QPointer<Attribute>> &atr);
const QList<QPair<QString, QString>> &getAtr() const;
void setAtr(const QList<QPair<QString, QString>> &atr);
@ -37,7 +35,6 @@ private:
QSet<QString> tokenFlags;
QString pin;
QSet<QString> pinFlags;
//QList<QPointer<Attribute>> atr;
QList<QPair<QString, QString>> atr;
const QList<QString> attributeTypes = {"Jmeno", "Prijmeni", "ProfilParking", "Spolecnost", "Profil", "spz"};

View File

@ -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();
}

View File

@ -52,5 +52,6 @@ private:
bool dryMode = false;
bool updateFinished = false;
bool deleteFinished = false;
int dataCounter = 0;
};

View File

@ -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<QString> 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;
}

View File

@ -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<QString> &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<QString> flags;
QUuid subjectId;
quint64 lastModified{};
bool deleted{};
};