WIP: possible to build, not implemented yet: upload data to DB

This commit is contained in:
Ondřej Fischer 2019-11-14 11:31:19 +01:00
parent 9bf2eb05e8
commit c96832f4b8
17 changed files with 1137 additions and 1032 deletions

View File

@ -14,7 +14,6 @@ int main(int argc, char *argv[])
QCoreApplication::setApplicationName("colnod-connector"); QCoreApplication::setApplicationName("colnod-connector");
QCoreApplication::setApplicationVersion("1.0"); QCoreApplication::setApplicationVersion("1.0");
QCommandLineParser parser; QCommandLineParser parser;
Logger *logger = Logger::getLogger();
parser.setApplicationDescription("Colnod sync"); parser.setApplicationDescription("Colnod sync");
QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made"); QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made");
QCommandLineOption dropTablesOption("dropTables", "ColnodAPI", "Delete tables with datas from Colnod"); QCommandLineOption dropTablesOption("dropTables", "ColnodAPI", "Delete tables with datas from Colnod");
@ -25,54 +24,11 @@ int main(int argc, char *argv[])
parser.process(app); parser.process(app);
SyncManager api(parser.isSet(dryModeOption)); SyncManager api;
api.init();
api.run();
serversdk::RequestManager requestManager;
ColnodAPI colnod(&requestManager);
// Get data
colnod.downloadData();
QObject::connect(&colnod, &ColnodAPI::downloadDataFinished, [=](std::shared_ptr<ColnodData> data) {
qDebug() << "now i must have data";
qDebug() << "Tokens:" << data->deletedTokens.count();
QCoreApplication::exit();
});
// Process data
// Sync data
//
//
// QObject::connect(&api, &SyncManager::error, &app, [](){ // QObject::connect(&api, &SyncManager::error, &app, [](){
// qDebug() << "error"; // qDebug() << "error";
// QCoreApplication::exit(1); // QCoreApplication::exit(1);

View File

@ -4,7 +4,7 @@ ColnodAPI::ColnodAPI()
{ {
} }
ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, QString userName, QString password, qint64 lastSync) ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, qint64 lastSync, QString userName, QString password)
:mReqMan(reqMan), mUserName(userName), mPassword(password) :mReqMan(reqMan), mUserName(userName), mPassword(password)
{ {
mLastSync.set_timestamp(lastSync); mLastSync.set_timestamp(lastSync);
@ -29,9 +29,10 @@ void ColnodAPI::downloadData()
}); });
} }
void ColnodAPI::uploadData(std::shared_ptr<Data> data) void ColnodAPI::processData(std::shared_ptr<Data> data)
{ {
setTokens(data->updatedTokens); setTokens(data->updatedTokens);
deleteTokens(data->deletedTokens);
} }
std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin() std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
@ -62,7 +63,7 @@ void ColnodAPI::getTokensUpdated(const Timestamp &time)
mReqMan->processRequest(request); mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){ connect(request.get(), &serversdk::Request::finished, [=](){
saveUpdatedTokens(request->responseData()); saveUpdatedTokens(request->responseData());
emit partOfDataReady(); emit partOfDataReady(data);
}); });
} }
@ -99,9 +100,8 @@ void ColnodAPI::getSubjectsDeleted(const Timestamp &time)
}); });
} }
void ColnodAPI::setTokens(const QHash<QUuid, Token> &tokens) void ColnodAPI::setTokens(const QHash<QUuid, std::shared_ptr<Token>> &tokens)
{ {
auto request = composeRequest("/TokenManager/setTokens", Token::tokensToJSON(tokens)); auto request = composeRequest("/TokenManager/setTokens", Token::tokensToJSON(tokens));
request->setToken(authToken); request->setToken(authToken);
mReqMan->processRequest(request); mReqMan->processRequest(request);
@ -110,13 +110,24 @@ void ColnodAPI::setTokens(const QHash<QUuid, Token> &tokens)
emit partOfDataProcessFinished(); emit partOfDataProcessFinished();
} }
else { else {
// TODO: error: data wasnt upload to colnod
} }
}); });
} }
void ColnodAPI::deleteTokens(const QList<QString> &tokenIds) void ColnodAPI::deleteTokens(const QList<QString> &ids)
{ {
auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids));
request->setToken(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
if (checkResponse(request->responseData())) {
emit partOfDataProcessFinished();
}
else {
// TODO: error: data wasnt upload to colnod
}
});
} }
@ -161,18 +172,25 @@ void ColnodAPI::areDataReady()
{ {
if (++amountData == 4) { if (++amountData == 4) {
emit downloadDataFinished(data); emit downloadDataFinished(data);
newData();
} }
} }
void ColnodAPI::isDataProcessFinished()
{
if (++amountProccessesFinished == 2)
emit dataProcessFinished();
}
void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData) void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData)
{ {
QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray(); QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) { for (QJsonValueRef item : items) {
Token token; auto token = std::make_shared<Token>();
token.fromJSON(item.toObject()); token->fromJSON(item.toObject());
token.setDeleted(false); token->setDeleted(false);
data->updatedTokens.insert(token.getId(), token); data->updatedTokens.insert(token->getId(), token);
} }
} }
@ -190,10 +208,10 @@ void ColnodAPI::saveUpdatedSubjects(const QByteArray &responseData)
QJsonDocument doc = QJsonDocument::fromJson(responseData); QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray(); QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) { for (QJsonValueRef item : items) {
Subject subject; auto subject = std::make_shared<Subject>();
subject.fromJSON(item.toObject()); subject->fromJSON(item.toObject());
subject.setDeleted(false); subject->setDeleted(false);
data->updatedSubjects.insert(subject.getId(), subject); data->updatedSubjects.insert(subject->getId(), subject);
} }
} }
@ -205,3 +223,14 @@ void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData)
data->deletedSubjects.append(item.toString()); data->deletedSubjects.append(item.toString());
} }
} }
void ColnodAPI::newData()
{
data = std::make_shared<Data>();
}
bool ColnodAPI::checkResponse(const QByteArray &responseData)
{
QJsonDocument doc = QJsonDocument::fromJson(responseData);
return doc.object().contains("items");
}

View File

@ -36,10 +36,10 @@ class ColnodAPI: public QObject
Q_OBJECT Q_OBJECT
public: public:
ColnodAPI(); ColnodAPI();
ColnodAPI(serversdk::RequestManager* reqMan, QString userName = "spaceti", QString password = "spaceti1", qint64 lastSync = 0); ColnodAPI(serversdk::RequestManager* reqMan, qint64 lastSync = 0, QString userName = "spaceti", QString password = "spaceti1");
void downloadData(); void downloadData();
void uploadData(std::shared_ptr<Data> data); void processData(std::shared_ptr<Data> data);
// New approach // New approach
std::shared_ptr<serversdk::Request> requestLogin(); std::shared_ptr<serversdk::Request> requestLogin();
@ -50,7 +50,7 @@ public:
void getSubjectsUpdated(const Timestamp &time); void getSubjectsUpdated(const Timestamp &time);
void getSubjectsDeleted(const Timestamp &time); void getSubjectsDeleted(const Timestamp &time);
void setTokens(const QHash<QUuid, Token> &tokens); void setTokens(const QHash<QUuid, std::shared_ptr<Token>> &tokens);
void deleteTokens(const QList<QString> &tokenIds); void deleteTokens(const QList<QString> &tokenIds);
// Attributes // Attributes
@ -64,6 +64,7 @@ public:
private: private:
Q_SLOT void areDataReady(); Q_SLOT void areDataReady();
Q_SLOT void isDataProcessFinished();
private: private:
void saveUpdatedTokens(const QByteArray &responseData); void saveUpdatedTokens(const QByteArray &responseData);
@ -71,6 +72,8 @@ private:
void saveDeletedTokens(const QByteArray &responseData); void saveDeletedTokens(const QByteArray &responseData);
void saveDeletedSubjects(const QByteArray &responseData); void saveDeletedSubjects(const QByteArray &responseData);
void newData();
bool checkResponse(const QByteArray &responseData); bool checkResponse(const QByteArray &responseData);
QByteArray getTimestampJson(const qint64 &time); QByteArray getTimestampJson(const qint64 &time);
@ -78,8 +81,9 @@ private:
signals: signals:
void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>()); void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>());
void partOfDataReady(); void partOfDataReady(std::shared_ptr<Data> = std::shared_ptr<Data>());
void partOfDataProcessFinished(); void partOfDataProcessFinished();
void dataProcessFinished();
private: private:
serversdk::RequestManager* mReqMan = nullptr; serversdk::RequestManager* mReqMan = nullptr;
@ -92,5 +96,6 @@ private:
QString authToken; QString authToken;
qint16 amountData = 0; qint16 amountData = 0;
qint16 amountProccessesFinished = 0;
}; };

View File

@ -4,3 +4,11 @@ Data::Data()
{ {
} }
void Data::clear()
{
updatedTokens.clear();
updatedSubjects.clear();
deletedTokens.clear();
deletedSubjects.clear();
}

View File

@ -9,9 +9,11 @@ class Data
public: public:
Data(); Data();
QHash<QUuid, Token> updatedTokens; void clear();
QHash<QUuid, std::shared_ptr<Token>> updatedTokens;
QList<QString> deletedTokens; QList<QString> deletedTokens;
QHash<QUuid, Subject> updatedSubjects; QHash<QUuid, std::shared_ptr<Subject>> updatedSubjects;
QList<QString> deletedSubjects; QList<QString> deletedSubjects;
}; };

View File

@ -8,6 +8,15 @@ DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan)
} }
bool DatabaseAPI::open()
{
return mDbMan->openPostgres(QStringLiteral("192.168.1.94"), // move to databaseAPi
QStringLiteral("deloitte"),
QStringLiteral("postgres"),
QStringLiteral("34rjkciea12"),
QStringLiteral("postgres-connection"));
}
void DatabaseAPI::downloadData() void DatabaseAPI::downloadData()
{ {
QSqlQuery 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 " QSqlQuery 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 "
@ -17,6 +26,14 @@ void DatabaseAPI::downloadData()
emit downloadDataFinished(composeData(updatedQuery, deletedQuery)); emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
} }
void DatabaseAPI::processData(std::shared_ptr<Data> data)
{
uploadTokens(data->updatedTokens);
uploadSubjects(data->updatedSubjects);
deleteTokens(data->deletedTokens);
deleteSubjects(data->deletedSubjects);
}
@ -24,9 +41,9 @@ std::shared_ptr<Data> DatabaseAPI::composeData(QSqlQuery updatedQuery, QSqlQuery
{ {
auto data = std::make_shared<Data>(); auto data = std::make_shared<Data>();
while (updatedQuery.next()) { while (updatedQuery.next()) {
Token token; auto token = std::make_shared<Token>();
token.fromSQLRecord(updatedQuery); token->fromSQLRecord(updatedQuery);
data->updatedTokens.append(token); data->updatedTokens.insert(token->getId(), token);
} }
while (deletedQuery.next()) { while (deletedQuery.next()) {
data->deletedTokens.append(deletedQuery.value(0).toString()); data->deletedTokens.append(deletedQuery.value(0).toString());
@ -50,7 +67,18 @@ void DatabaseAPI::setLastSync(qint64 timestamp)
QSqlQuery query; QSqlQuery query;
query.prepare("UPDATE config SET last_sync = :last_sync"); query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", timestamp); query.bindValue(":last_sync", timestamp);
executeQuery(query); mDbMan->executeQuery(query);
}
void DatabaseAPI::setLastUpdate(QHash<QUuid, std::shared_ptr<Token>> tokens)
{
QSqlQuery query;
for (const auto &token : tokens){
query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id");
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":id", token->idToStringWithoutBraces());
mDbMan->executeQuery(query);
}
} }
qint64 DatabaseAPI::getNow() qint64 DatabaseAPI::getNow()
@ -60,14 +88,65 @@ qint64 DatabaseAPI::getNow()
return query.value(0).toLongLong(); return query.value(0).toLongLong();
} }
void DatabaseAPI::initNewTokens()
{
QSqlQuery query = 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 name IS NULL");
QHash<QUuid, std::shared_ptr<Token>> tokensToInit;
while (query.next()){
auto token = std::make_shared<Token>();
token->fromSQLRecord(query);
qint16 num = getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces());
token->setName(getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1));
token->setDescription("mobile");
tokensToInit.insert(token->getId(), token);
}
uploadTokens(tokensToInit);
}
void DatabaseAPI::uploadTokens(QHash<QUuid, std::shared_ptr<Token>> tokens)
{
// TODO:
}
void DatabaseAPI::uploadSubjects(QHash<QUuid, std::shared_ptr<Subject>> subjects)
{
// TODO:
}
void DatabaseAPI::deleteTokens(QList<QString> ids)
{
// TODO:
}
void DatabaseAPI::deleteSubjects(QList<QString> ids)
{
// TODO:
}
qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
{
QSqlQuery query;
query.prepare("SELECT 1 FROM colnod_token WHERE subject_id = :id AND deleted = false");
query.bindValue(":id", id);
return static_cast<qint16>(mDbMan->executeQuery(query).size());
}
QString DatabaseAPI::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);
if (mDbMan->executeQuery(query).next())
return query.value(0).toString();
qWarning() << "Token:" << tokenId << "is not assigned to any subject";
return "(No subject)";
}
@ -93,302 +172,287 @@ qint64 DatabaseAPI::getNow()
// OLD // OLD
DatabaseAPI::DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode) //DatabaseAPI::DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode)
:dryMode(dryMode) // :dryMode(dryMode)
{ //{
db = QSqlDatabase::addDatabase("QPSQL"); // db = QSqlDatabase::addDatabase("QPSQL");
db.setDatabaseName(dbName); // db.setDatabaseName(dbName);
db.setHostName(host); // db.setHostName(host);
db.setUserName(user); // home-office stuff -->> db.setPort(80); // db.setUserName(user); // home-office stuff -->> db.setPort(80);
db.setPassword(password); // db.setPassword(password);
if (!db.open()) // if (!db.open())
{ // {
opened = false; // opened = false;
Logger::log("Opening error" + db.lastError().text()); // Logger::log("Opening error" + db.lastError().text());
emit error(); // emit error();
} // }
else{ // else{
opened = true; // opened = true;
} // }
} //}
// add or update subject to db //// add or update subject to db
int DatabaseAPI::saveSubject(const std::shared_ptr<Subject>& subject, const QString& table) //int DatabaseAPI::saveSubject(const std::shared_ptr<Subject>& subject, const QString& table)
{ //{
QSqlQuery query; // QSqlQuery query;
QString id = subject->idToStringWithoutBraces(); // QString id = subject->idToStringWithoutBraces();
int rtn; // int rtn;
if (checkIfExists(id, table)){ // 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 " // 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)); // "WHERE id = :id").arg(table));
rtn = -1; // rtn = -1;
}else{ // }else{
query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) " // 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; // rtn = 1;
} // }
query.bindValue(":id", id); // query.bindValue(":id", id);
query.bindValue(":description", subject->getDescription()); // query.bindValue(":description", subject->getDescription());
query.bindValue(":name", subject->getName()); // query.bindValue(":name", subject->getName());
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); // query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":pin", subject->getPin()); // query.bindValue(":pin", subject->getPin());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); // query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", subject->getDeleted()); // query.bindValue(":deleted", subject->getDeleted());
executeQuery(query); // executeQuery(query);
return rtn; // return rtn;
} //}
QSqlQuery DatabaseAPI::getUpdatedTokens() //QSqlQuery DatabaseAPI::getUpdatedTokens()
{ //{
QSqlQuery query; // 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 " // 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 AND deleted = false"); // "FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = false");
return query; // return query;
} //}
// add or update token to DB //// add or update token to DB
int DatabaseAPI::saveToken(const std::shared_ptr<Token>& token, const QString& table) //int DatabaseAPI::saveToken(const std::shared_ptr<Token>& token, const QString& table)
{ //{
QSqlQuery query; // QSqlQuery query;
QString id = token->idToStringWithoutBraces(); // QString id = token->idToStringWithoutBraces();
int rtn; // int rtn;
if (checkIfExists(id, table)){ // 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 " // 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; // rtn = -1;
}else{ // }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) " // 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; // rtn = 1;
} // }
query.bindValue(":id", id); // query.bindValue(":id", id);
query.bindValue(":auth_errors", token->getAuthErrors()); // query.bindValue(":auth_errors", token->getAuthErrors());
query.bindValue(":description", token->getDescription()); // query.bindValue(":description", token->getDescription());
query.bindValue(":enabled", token->getFlags().contains("Enabled")); // 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(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":name", token->getName()); // query.bindValue(":name", token->getName());
query.bindValue(":no_validity", token->getFlags().contains("NoValidity")); // query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
query.bindValue(":time_to_live", token->getTimeToLive()); // query.bindValue(":time_to_live", token->getTimeToLive());
query.bindValue(":token_bits", token->getTokenBits()); // query.bindValue(":token_bits", token->getTokenBits());
query.bindValue(":token_data", token->getTokenData()); // query.bindValue(":token_data", token->getTokenData());
query.bindValue(":token_type", token->getTokenType()); // query.bindValue(":token_type", token->getTokenType());
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces()); // query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz")); // query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", token->getDeleted()); // query.bindValue(":deleted", token->getDeleted());
executeQuery(query); // executeQuery(query);
return rtn; // return rtn;
} //}
// add of update subject attributes //// add of update subject attributes
void DatabaseAPI::saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table) //void DatabaseAPI::saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table)
{ //{
QSqlQuery query; // QSqlQuery query;
auto attributes = subject->getAtr(); // auto attributes = subject->getAtr();
for (const auto& attribute : attributes){ // for (const auto& attribute : attributes){
QString id = subject->idToStringWithoutBraces() + " " + attribute.first; // 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) " // query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) "
"WHERE id = :id").arg(table)); // "WHERE id = :id").arg(table));
}else{ // }else{
query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)" // query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)"
"VALUES (:id, :key, :value, :subject_id)").arg(table)); // "VALUES (:id, :key, :value, :subject_id)").arg(table));
} // }
query.bindValue(":id", id); // query.bindValue(":id", id);
query.bindValue(":key", attribute.first); // query.bindValue(":key", attribute.first);
query.bindValue(":value", attribute.second); // query.bindValue(":value", attribute.second);
query.bindValue(":subject_id", subject->idToStringWithoutBraces()); // query.bindValue(":subject_id", subject->idToStringWithoutBraces());
executeQuery(query); // executeQuery(query);
} // }
} //}
// "delete" tokens from DB -> set deleted true //// "delete" tokens from DB -> set deleted true
void DatabaseAPI::setDeleted(const QString& id, const QString& table, quint64 time) //void DatabaseAPI::setDeleted(const QString& id, const QString& table, quint64 time)
{ //{
QSqlQuery query; // QSqlQuery query;
QString nowString = QDateTime::fromMSecsSinceEpoch(time).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.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table));
query.bindValue(":id", id); // query.bindValue(":id", id);
query.bindValue(":now", nowString); // query.bindValue(":now", nowString);
executeQuery(query); // executeQuery(query);
} //}
bool DatabaseAPI::checkIfExists(const QString& id, const QString& table) //bool DatabaseAPI::checkIfExists(const QString& id, const QString& table)
{ //{
QSqlQuery query; // QSqlQuery query;
query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table)); // query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
query.bindValue(":id", id); // query.bindValue(":id", id);
executeQuery(query); // executeQuery(query);
query.first(); // query.first();
return query.value(0).toBool(); // return query.value(0).toBool();
} //}
QString DatabaseAPI::getLastQuery(const QSqlQuery& query) const //QString DatabaseAPI::getLastQuery(const QSqlQuery& query) const
{ //{
QString str = query.lastQuery(); // QString str = query.lastQuery();
QMapIterator<QString, QVariant> it(query.boundValues()); // QMapIterator<QString, QVariant> it(query.boundValues());
while (it.hasNext()) // while (it.hasNext())
{ // {
it.next(); // it.next();
str.replace(it.key(),it.value().toString()); // str.replace(it.key(),it.value().toString());
} // }
return str; // return str;
} //}
bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement) //bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
{ //{
if (statement.isEmpty()){ // if (statement.isEmpty()){
if (dryMode){ // if (dryMode){
QString sqlStatement = getLastQuery(query); // QString sqlStatement = getLastQuery(query);
qDebug() << sqlStatement; // qDebug() << sqlStatement;
} // }
if (!dryMode || getLastQuery(query).startsWith("SELECT")){ // if (!dryMode || getLastQuery(query).startsWith("SELECT")){
if (!query.exec()){ // if (!query.exec()){
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); // QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
Logger::logToDb(QString(msg)); // Logger::logToDb(QString(msg));
emit error(); // emit error();
} // }
} // }
return true; // return true;
} // }
if (dryMode){ // if (dryMode){
qDebug() << statement; // qDebug() << statement;
} // }
if (!dryMode || statement.startsWith("SELECT")){ // if (!dryMode || statement.startsWith("SELECT")){
if (!query.exec(statement)){ // if (!query.exec(statement)){
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); // QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
Logger::logToDb(QString(msg)); // Logger::logToDb(QString(msg));
emit error(); // emit error();
} // }
} // }
return true; // return true;
} //}
void DatabaseAPI::dropTables() //void DatabaseAPI::dropTables()
{ //{
QSqlQuery query; // QSqlQuery query;
executeQuery(query, "DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute"); // executeQuery(query, "DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute");
} //}
// create table after deleting, it is used for full sync //// create table after deleting, it is used for full sync
void DatabaseAPI::createTables() //void DatabaseAPI::createTables()
{ //{
QSqlQuery query; // QSqlQuery query;
executeQuery(query, "CREATE TABLE colnod_subject (" // executeQuery(query, "CREATE TABLE colnod_subject ("
"id character(36) primary key NOT NULL," // "id character(36) primary key NOT NULL,"
"description character varying(255)," // "description character varying(255),"
"last_update timestamp NOT NULL," // "last_update timestamp NOT NULL,"
"name character varying(255)," // "name character varying(255),"
"pin character varying(255)," // "pin character varying(255),"
"last_modified timestamp," // "last_modified timestamp,"
"deleted BOOLEAN)"); // "deleted BOOLEAN)");
executeQuery(query, "CREATE TABLE colnod_token (" // executeQuery(query, "CREATE TABLE colnod_token ("
"id CHAR(36) primary key NOT NULL," // "id CHAR(36) primary key NOT NULL,"
"auth_errors INTEGER DEFAULT 255," // "auth_errors INTEGER DEFAULT 255,"
"description VARCHAR(255)," // "description VARCHAR(255),"
"enabled BOOLEAN DEFAULT true," // "enabled BOOLEAN DEFAULT true,"
"last_update timestamp DEFAULT '1970-01-01 00:00:00'::timestamp without time zone," // "last_update timestamp DEFAULT '1970-01-01 00:00:00'::timestamp without time zone,"
"name VARCHAR(255)," // "name VARCHAR(255),"
"no_validity BOOLEAN DEFAULT true," // "no_validity BOOLEAN DEFAULT true,"
"time_to_live INTEGER DEFAULT 255," // "time_to_live INTEGER DEFAULT 255,"
"token_bits INTEGER DEFAULT 32," // "token_bits INTEGER DEFAULT 32,"
"token_data VARCHAR(255)," // "token_data VARCHAR(255),"
"token_type VARCHAR(255) DEFAULT 'Token'::character varying," // "token_type VARCHAR(255) DEFAULT 'Token'::character varying,"
"subject_id CHAR(36)," // "subject_id CHAR(36),"
"last_modified timestamp NOT NULL," // "last_modified timestamp NOT NULL,"
"deleted BOOLEAN DEFAULT false)"); // "deleted BOOLEAN DEFAULT false)");
executeQuery(query, "CREATE TABLE colnod_subject_attribute (" // executeQuery(query, "CREATE TABLE colnod_subject_attribute ("
"id VARCHAR(255) primary key," // "id VARCHAR(255) primary key,"
"attribute_key VARCHAR(255)," // "attribute_key VARCHAR(255),"
"attribute_value VARCHAR(255)," // "attribute_value VARCHAR(255),"
"subject_id CHAR(36))"); // "subject_id CHAR(36))");
} //}
// on the very end of sync set new Last_sync time (begin of this sync) //// on the very end of sync set new Last_sync time (begin of this sync)
// return set of tokens to update form DB //// return set of tokens to update form DB
QSqlQuery DatabaseAPI::getToken(const QString& id) //QSqlQuery DatabaseAPI::getToken(const QString& id)
{ //{
QSqlQuery query; // 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 " // 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"); // "FROM colnod_token WHERE id = :id");
query.bindValue(":id", id); // query.bindValue(":id", id);
executeQuery(query); // executeQuery(query);
query.next(); // query.next();
return query; // return query;
} //}
// sync last update back to DB from Colnod after changes made to Colnod //// sync last update back to DB from Colnod after changes made to Colnod
void DatabaseAPI::setLastUpdate(const QString& id, quint64 lastUpdate)
{
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(":last_update", lsatUpdateString);
executeQuery(query);
}
void DatabaseAPI::log(const QString &msg)
{
QSqlQuery query;
query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)");
query.bindValue(":msg", msg);
query.exec();
}
QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId) //void DatabaseAPI::log(const QString &msg)
{ //{
QSqlQuery query; // QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)"); // query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)");
query.bindValue(":tokenId", tokenId); // query.bindValue(":msg", msg);
executeQuery(query); // query.exec();
if (query.next()) //}
return query.value(0).toString();
qWarning() << "Token:" << tokenId << "is not assigned to any subject";
return "(No subject)";
}
QString DatabaseAPI::getSubjectNameById(const QString &id) //QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
{ //{
QSqlQuery query; // QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = :id"); // query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)");
query.bindValue(":id", id); // query.bindValue(":tokenId", tokenId);
executeQuery(query); // executeQuery(query);
if (query.next()) // if (query.next())
return query.value(0).toString(); // return query.value(0).toString();
qWarning() << "Subject:" << id << "doesn't exists"; // qWarning() << "Token:" << tokenId << "is not assigned to any subject";
return "(No subject)"; // return "(No subject)";
} //}
bool DatabaseAPI::checkDeletedToken(const QString &id) //QString DatabaseAPI::getSubjectNameById(const QString &id)
{ //{
QSqlQuery query; // QSqlQuery query;
query.prepare("SELECT deleted FROM colnod_token WHERE id = :id"); // query.prepare("SELECT name FROM colnod_subject WHERE id = :id");
query.bindValue(":id", id); // query.bindValue(":id", id);
executeQuery(query); // executeQuery(query);
query.next(); // if (query.next())
return query.value(0).toBool(); // return query.value(0).toString();
} // qWarning() << "Subject:" << id << "doesn't exists";
// return "(No subject)";
//}
qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id) //bool DatabaseAPI::checkDeletedToken(const QString &id)
{ //{
QSqlQuery query; // QSqlQuery query;
query.prepare("SELECT 1 FROM colnod_token WHERE subject_id = :id AND deleted = false"); // query.prepare("SELECT deleted FROM colnod_token WHERE id = :id");
query.bindValue(":id", id); // query.bindValue(":id", id);
executeQuery(query); // executeQuery(query);
return static_cast<qint16>(query.size()); // query.next();
} // return query.value(0).toBool();
//}
bool DatabaseAPI::isOpen()
{
return opened; //bool DatabaseAPI::isOpen()
} //{
// return opened;
//}

View File

@ -26,14 +26,28 @@ class DatabaseAPI : public QObject
public: public:
DatabaseAPI(serversdk::DatabaseManager *dbMan); DatabaseAPI(serversdk::DatabaseManager *dbMan);
bool open();
void downloadData(); void downloadData();
void processData(std::shared_ptr<Data> data);
qint64 getLastSync(); qint64 getLastSync();
void setLastSync(qint64 timestamp); void setLastSync(qint64 timestamp);
void setLastUpdate(QHash<QUuid, std::shared_ptr<Token> > tokens);
qint64 getNow(); qint64 getNow();
void initNewTokens();
// process data
void uploadTokens(QHash<QUuid, std::shared_ptr<Token>> tokens);
void uploadSubjects(QHash<QUuid, std::shared_ptr<Subject>> subjects);
void deleteTokens(QList<QString> ids);
void deleteSubjects(QList<QString> ids);
private: private:
QSqlQuery getUpdatedTokens(); QSqlQuery getUpdatedTokens();
std::shared_ptr<Data> composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery); std::shared_ptr<Data> composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery);
qint16 getNumOfTokensOfSubject(const QString &id);
QString getSubjectNameByTokenId(const QString &tokenId);
signals: signals:
void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>()); void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>());
@ -50,42 +64,41 @@ private:
// old // old
DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false); // DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false);
int saveSubject(const std::shared_ptr<Subject>& subject, const QString& table); // int saveSubject(const std::shared_ptr<Subject>& subject, const QString& table);
int saveToken(const std::shared_ptr<Token>& token, const QString& table); // int saveToken(const std::shared_ptr<Token>& token, const QString& table);
void saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table); // void saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table);
void setDeleted(const QString& id, const QString& table, quint64 time); // void setDeleted(const QString& id, const QString& table, quint64 time);
void dropTables(); // void dropTables();
void createTables(); // void createTables();
void updateLastSync(quint64 lastSync); // void updateLastSync(quint64 lastSync);
QSqlQuery getToken(const QString& id); // QSqlQuery getToken(const QString& id);
void setLastUpdate(const QString& id, quint64 lastUpdate); // void setLastUpdate(const QString& id, quint64 lastUpdate);
void log(const QString &msg); // void log(const QString &msg);
QString getSubjectNameByTokenId(const QString &tokenId); // QString getSubjectNameById(const QString &id);
QString getSubjectNameById(const QString &id); // bool checkDeletedToken(const QString &id);
bool checkDeletedToken(const QString &id);
qint16 getNumOfTokensOfSubject(const QString &id);
bool isOpen();
private:
bool checkIfExists(const QString& id, const QString& table);
bool executeQuery(QSqlQuery &query, const QString &statement = QString());
QString getLastQuery(const QSqlQuery &query) const;
signals: // bool isOpen();
void error();
private:
QSqlDatabase db; //private:
bool dryMode = false; // bool checkIfExists(const QString& id, const QString& table);
bool opened = false; // bool executeQuery(QSqlQuery &query, const QString &statement = QString());
// QString getLastQuery(const QSqlQuery &query) const;
//signals:
// void error();
//private:
// QSqlDatabase db;
// bool dryMode = false;
// bool opened = false;
}; };

View File

@ -1,372 +1,372 @@
#include "datamanager.h" #include "datamanager.h"
DataManager::DataManager(const bool &dryMode) : //DataManager::DataManager(const bool &dryMode) :
db(std::make_shared<DatabaseAPI>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode)), // db(std::make_shared<DatabaseAPI>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode)),
dryMode(dryMode) // dryMode(dryMode)
{ //{
if (db->isOpen()){ // if (db->isOpen()){
Logger::setDBMan(db); // Logger::setDBMan(db);
nextLastSync = db->getNow(); // nextLastSync = db->getNow();
lastSync = db->getLastSync(); // lastSync = db->getLastSync();
} // }
connect(db.get(), &DatabaseAPI::error, this, &DataManager::error, Qt::QueuedConnection); // connect(db.get(), &DatabaseAPI::error, this, &DataManager::error, Qt::QueuedConnection);
} //}
// load all tokens from colnod to comparing with working set from DB //// load all tokens from colnod to comparing with working set from DB
void DataManager::fillFullTokensColnod(const QString& response) //void DataManager::fillFullTokensColnod(const QString& response)
{ //{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); // QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray(); // QJsonArray items = doc.object()["items"].toArray();
if (!items.empty()) // if (!items.empty())
{ // {
for (QJsonValueRef item : items){ // for (QJsonValueRef item : items){
auto token = std::make_shared<Token>(); // auto token = std::make_shared<Token>();
token->fromJSON(item.toObject()); // token->fromJSON(item.toObject());
allTokensFromColnodById.insert(token->idToStringWithoutBraces(), token); // allTokensFromColnodById.insert(token->idToStringWithoutBraces(), token);
allTokensFromColnodByName.insert(token->getName(), token); // allTokensFromColnodByName.insert(token->getName(), token);
} // }
} // }
else{ // else{
qCritical() << "Colnod is Empty"; // qCritical() << "Colnod is Empty";
} // }
} //}
// load working set with updated tokens from Colnod //// load working set with updated tokens from Colnod
void DataManager::fillTokensToUpdateColnod(const QString& response) //void DataManager::fillTokensToUpdateColnod(const QString& response)
{ //{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); // QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray(); // QJsonArray items = doc.object()["items"].toArray();
if (!items.empty()) // if (!items.empty())
{ // {
for (QJsonValueRef item : items) // for (QJsonValueRef item : items)
{ // {
auto token = std::make_shared<Token>(); // auto token = std::make_shared<Token>();
token->fromJSON(item.toObject()); // token->fromJSON(item.toObject());
token->setDeleted(false); // token->setDeleted(false);
tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token); // tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token);
} // }
qInfo() << "Colnod:" << tokensToUpdateFromColnodToDB.size() << "tokens to update"; // qInfo() << "Colnod:" << tokensToUpdateFromColnodToDB.size() << "tokens to update";
} // }
else // else
{ // {
qInfo() << "Colnod: 0 tokens to update"; // qInfo() << "Colnod: 0 tokens to update";
} // }
} //}
// load working set with updated subjects from Colnod //// load working set with updated subjects from Colnod
void DataManager::fillSubjectsToUpdateColnod(const QString& response) //void DataManager::fillSubjectsToUpdateColnod(const QString& response)
{ //{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8()); // QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray(); // QJsonArray items = doc.object()["items"].toArray();
if (!items.empty()) // if (!items.empty())
{ // {
for (QJsonValueRef item : items) // for (QJsonValueRef item : items)
{ // {
auto subject = std::make_shared<Subject>(); // auto subject = std::make_shared<Subject>();
subject->fromJSON(item.toObject()); // subject->fromJSON(item.toObject());
subject->setDeleted(false); // subject->setDeleted(false);
subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject); // subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject);
} // }
qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update"; // qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update";
} // }
else // else
{ // {
qInfo() << "Colnod:" << "0 subjects to update"; // qInfo() << "Colnod:" << "0 subjects to update";
} // }
} //}
// load working sets with updated/deleted tokens from DB //// load working sets with updated/deleted tokens from DB
void DataManager::fillTokensToChangeDB() //void DataManager::fillTokensToChangeDB()
{ //{
if (db->isOpen()){ // if (db->isOpen()){
QSqlQuery query = db->getUpdatedTokens(); // QSqlQuery query = db->getUpdatedTokens();
while (query.next()) // while (query.next())
{ // {
auto token = std::make_shared<Token>(); // auto token = std::make_shared<Token>();
token->fromSQLRecord(query); // token->fromSQLRecord(query);
if (token->getName() == NULL){ // if (token->getName() == NULL){
qint16 num = db->getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces()); // qint16 num = db->getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces());
token->setName(db->getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1)); // token->setName(db->getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1));
token->setDescription("mobile"); // token->setDescription("mobile");
token->setLastUpdate(token->getLastModified()); // token->setLastUpdate(token->getLastModified());
db->saveToken(token, "colnod_token"); // db->saveToken(token, "colnod_token");
} // }
if (token->getDeleted()){ // sort to delete / to update // if (token->getDeleted()){ // sort to delete / to update
tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces()); // tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces());
} // }
else{ // else{
tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token); // tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token);
} // }
} // }
qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update"; // qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update";
qDebug() << "DB:" << tokensFromDBToDeleteFromColnod.size() << "tokens to delete"; // qDebug() << "DB:" << tokensFromDBToDeleteFromColnod.size() << "tokens to delete";
} // }
else // else
emit error(); // emit error();
} //}
void DataManager::fillSubjectsToUpdateDB() //void DataManager::fillSubjectsToUpdateDB()
{ //{
// Not needed yet // // Not needed yet
} //}
// load working set with subjest to delete from Colnod //// load working set with subjest to delete from Colnod
void DataManager::fillSubjectsToDeleteColnod(const QString& json) //void DataManager::fillSubjectsToDeleteColnod(const QString& json)
{ //{
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); // QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
QJsonArray items = doc.object()["items"].toArray(); // QJsonArray items = doc.object()["items"].toArray();
if (!items.empty()) // if (!items.empty())
{ // {
for (QJsonValueRef item : items) { // for (QJsonValueRef item : items) {
subjectsFromColnodToDeleteFromDB.append(item.toString()); // subjectsFromColnodToDeleteFromDB.append(item.toString());
} // }
qInfo() << "Colnod:" << subjectsFromColnodToDeleteFromDB.size() << "subjects to delete"; // qInfo() << "Colnod:" << subjectsFromColnodToDeleteFromDB.size() << "subjects to delete";
} // }
else { // else {
qInfo() << "Colnod: 0 subjects to delete"; // qInfo() << "Colnod: 0 subjects to delete";
} // }
} //}
// load working set with tokens to delete from DB //// load working set with tokens to delete from DB
void DataManager::fillTokensToDeleteColnod(const QString& json) //void DataManager::fillTokensToDeleteColnod(const QString& json)
{ //{
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); // QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
QJsonArray items = doc.object()["items"].toArray(); // QJsonArray items = doc.object()["items"].toArray();
if (!items.empty()) // if (!items.empty())
{ // {
for (QJsonValueRef item : items) { // for (QJsonValueRef item : items) {
tokensFromColnodToDeleteFromDB.append(item.toString()); // tokensFromColnodToDeleteFromDB.append(item.toString());
} // }
qInfo() << "Colnod:" << tokensFromColnodToDeleteFromDB.size() << "tokens to delete"; // qInfo() << "Colnod:" << tokensFromColnodToDeleteFromDB.size() << "tokens to delete";
} // }
else { // else {
qInfo() << "Colnod: 0 tokens to delete"; // qInfo() << "Colnod: 0 tokens to delete";
} // }
} //}
void DataManager::fillSubjectsToDeleteDB() //void DataManager::fillSubjectsToDeleteDB()
{ //{
// Not needed yet // // Not needed yet
} //}
// update subjects from colnod to DB //// update subjects from colnod to DB
void DataManager::pushSubjectsToDB() //void DataManager::pushSubjectsToDB()
{ //{
if (subjectsToUpdateFromColnodToDB.isEmpty()) { // if (subjectsToUpdateFromColnodToDB.isEmpty()) {
qInfo() << "DB: 0 subjects added"; // qInfo() << "DB: 0 subjects added";
qInfo() << "DB: 0 subjects updated"; // qInfo() << "DB: 0 subjects updated";
return; // return;
} // }
int updated = 0; // int updated = 0;
int added = 0; // int added = 0;
for (const auto& subject : subjectsToUpdateFromColnodToDB) // for (const auto& subject : subjectsToUpdateFromColnodToDB)
{ // {
if (db->saveSubject(subject, "colnod_subject") > 0){ // if (db->saveSubject(subject, "colnod_subject") > 0){
added++; // added++;
if (dryMode) // if (dryMode)
qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB"; // qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB";
else // else
Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB")); // Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB"));
} // }
else{ // else{
updated++; // updated++;
if (dryMode) // if (dryMode)
qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB"; // qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB";
else // else
Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB")); // Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB"));
} // }
db->saveSubjectAttributes(subject, "colnod_subject_attribute"); // db->saveSubjectAttributes(subject, "colnod_subject_attribute");
} // }
qInfo() << "DB:" << added << "subjects added"; // qInfo() << "DB:" << added << "subjects added";
qInfo() << "DB:" << updated << "subjects updated"; // qInfo() << "DB:" << updated << "subjects updated";
} //}
// update tokens from colnod to DB //// update tokens from colnod to DB
void DataManager::pushTokensToDB() //void DataManager::pushTokensToDB()
{ //{
if (tokensToUpdateFromColnodToDB.isEmpty()){ // if (tokensToUpdateFromColnodToDB.isEmpty()){
qInfo() << "DB: 0 tokens added"; // qInfo() << "DB: 0 tokens added";
qInfo() << "DB: 0 tokens updated"; // qInfo() << "DB: 0 tokens updated";
return; // return;
} // }
filterTokensColnod(); // filterTokensColnod();
int updated = 0; // int updated = 0;
int added = 0; // int added = 0;
for (const auto& token : tokensToUpdateFromColnodToDB) // for (const auto& token : tokensToUpdateFromColnodToDB)
{ // {
QString text; // QString text;
// 1 = adding token // // 1 = adding token
// -1 = updating token // // -1 = updating token
if (db->saveToken(token, "colnod_token") == 1){ // if (db->saveToken(token, "colnod_token") == 1){
added++; // added++;
text = "Added"; // text = "Added";
} // }
else { // else {
updated++; // updated++;
text = "Updating"; // text = "Updating";
} // }
if (dryMode) // if (dryMode)
qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB"; // qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB";
else // else
Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB")); // Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB"));
} // }
qInfo() << "DB:" << added << "tokens added/edited"; // qInfo() << "DB:" << added << "tokens added/edited";
qInfo() << "DB:" << updated << "tokens updated"; // qInfo() << "DB:" << updated << "tokens updated";
} //}
void DataManager::deleteSubjectsFromDB() //void DataManager::deleteSubjectsFromDB()
{ //{
if (subjectsFromColnodToDeleteFromDB.isEmpty()) // if (subjectsFromColnodToDeleteFromDB.isEmpty())
{ // {
qInfo() << "DB: 0 subjects deleted"; // qInfo() << "DB: 0 subjects deleted";
return; // return;
} // }
for (const auto& subjectId : subjectsFromColnodToDeleteFromDB) // for (const auto& subjectId : subjectsFromColnodToDeleteFromDB)
{ // {
db->setDeleted(subjectId, "colnod_subject", nextLastSync); // db->setDeleted(subjectId, "colnod_subject", nextLastSync);
if (dryMode) // if (dryMode)
qInfo() << "Deleting subject:" << subjectId << "from DB"; // qInfo() << "Deleting subject:" << subjectId << "from DB";
else // else
Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB")); // Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB"));
} // }
qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted"; // qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted";
} //}
// "delete" (set deleted true) tokens in DB depends on Colnod //// "delete" (set deleted true) tokens in DB depends on Colnod
void DataManager::setDeletedToTokensFromDB() //void DataManager::setDeletedToTokensFromDB()
{ //{
if (tokensFromColnodToDeleteFromDB.isEmpty()) // if (tokensFromColnodToDeleteFromDB.isEmpty())
{ // {
qDebug() << "DB: 0 tokens deleted"; // qDebug() << "DB: 0 tokens deleted";
return; // return;
} // }
int alreadyDeleted = 0; // int alreadyDeleted = 0;
for (const auto& tokenId : tokensFromColnodToDeleteFromDB) // for (const auto& tokenId : tokensFromColnodToDeleteFromDB)
{ // {
if (!db->checkDeletedToken(tokenId)){ // if (!db->checkDeletedToken(tokenId)){
db->setDeleted(tokenId, "colnod_token", nextLastSync); // db->setDeleted(tokenId, "colnod_token", nextLastSync);
if (dryMode) // if (dryMode)
qInfo() << "Deleting token:" << tokenId << "from DB"; // qInfo() << "Deleting token:" << tokenId << "from DB";
else // else
Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB")); // Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB"));
} // }
else // else
alreadyDeleted++; // alreadyDeleted++;
} // }
qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted"; // qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted";
} //}
// recreate working tables //// recreate working tables
void DataManager::dropTables() //void DataManager::dropTables()
{ //{
if (db->isOpen()){ // if (db->isOpen()){
db->dropTables(); // db->dropTables();
} // }
else{ // else{
emit error(); // emit error();
} // }
} //}
void DataManager::createTables() //void DataManager::createTables()
{ //{
if (db->isOpen()){ // if (db->isOpen()){
db->createTables(); // db->createTables();
db->updateLastSync(0); // db->updateLastSync(0);
} // }
else{ // else{
emit error(); // emit error();
} // }
} //}
quint64 DataManager::getLastModifiedOfToken(const QString &id) //quint64 DataManager::getLastModifiedOfToken(const QString &id)
{ //{
auto record = db->getToken(id); // auto record = db->getToken(id);
auto token = std::make_shared<Token>(); // auto token = std::make_shared<Token>();
token->fromSQLRecord(record); // token->fromSQLRecord(record);
return token->getLastModified(); // return token->getLastModified();
} //}
//clear all structures ////clear all structures
void DataManager::clear() //void DataManager::clear()
{ //{
subjectsToUpdateFromColnodToDB.clear(); // subjectsToUpdateFromColnodToDB.clear();
subjectsFromColnodToDeleteFromDB.clear(); // subjectsFromColnodToDeleteFromDB.clear();
tokensToUpdateFromColnodToDB.clear(); // tokensToUpdateFromColnodToDB.clear();
tokensFromColnodToDeleteFromDB.clear(); // tokensFromColnodToDeleteFromDB.clear();
//subjectsDB.clear(); // not need yet // //subjectsDB.clear(); // not need yet
// subjectsToDeleteDB.clear(); // not need yet // // subjectsToDeleteDB.clear(); // not need yet
tokensToUpdateFromDBToColnod.clear(); // tokensToUpdateFromDBToColnod.clear();
tokensFromDBToDeleteFromColnod.clear(); // tokensFromDBToDeleteFromColnod.clear();
allTokensFromColnodById.clear(); // allTokensFromColnodById.clear();
} //}
// on the very end of sync update last sync time to begin time of this sync //// on the very end of sync update last sync time to begin time of this sync
void DataManager::updateLastSync() //void DataManager::updateLastSync()
{ //{
if (db->isOpen()) // if (db->isOpen())
db->updateLastSync(nextLastSync); // 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) //// 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() //void DataManager::filterTokensDB()
{ //{
QList<QString> idsToDelete; // QList<QString> idsToDelete;
for (const auto& token : tokensToUpdateFromDBToColnod) // for (const auto& token : tokensToUpdateFromDBToColnod)
{ // {
QString id = token->idToStringWithoutBraces(); // QString id = token->idToStringWithoutBraces();
Q_ASSERT(token != allTokensFromColnodById.value(id)); // if working sets are loading correctly equels should never happend // Q_ASSERT(token != allTokensFromColnodById.value(id)); // if working sets are loading correctly equels should never happend
if (allTokensFromColnodById.contains(id) && *token < *allTokensFromColnodById.value(id)) // if (allTokensFromColnodById.contains(id) && *token < *allTokensFromColnodById.value(id))
idsToDelete.append(id); // idsToDelete.append(id);
if (allTokensFromColnodById.contains(id) && token->getLastModified() == allTokensFromColnodById.value(id)->getLastUpdate()){ // if (allTokensFromColnodById.contains(id) && token->getLastModified() == allTokensFromColnodById.value(id)->getLastUpdate()){
idsToDelete.append(id); // idsToDelete.append(id);
qWarning() << "Same token has been edited in colnod and db in same time. Change from Colnod has been used"; // qWarning() << "Same token has been edited in colnod and db in same time. Change from Colnod has been used";
} // }
if (allTokensFromColnodByName.contains(token->getName())){ // 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"; // qWarning() << "Token:" << token->idToStringWithoutBraces() << "won't be added to Colnod, because token with the same name already exists, please change it manually";
if (!dryMode){ // 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()); // 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)); // Logger::logToDb(Logger::makeErrorMsg("Db", message));
} // }
} // }
} // }
for (const auto &id : idsToDelete) // for (const auto &id : idsToDelete)
tokensToUpdateFromDBToColnod.remove(id); // tokensToUpdateFromDBToColnod.remove(id);
} //}
void DataManager::filterTokensColnod() //void DataManager::filterTokensColnod()
{ //{
QList<QString> idsToDelete; // QList<QString> idsToDelete;
for (const auto &token : tokensToUpdateFromColnodToDB) // for (const auto &token : tokensToUpdateFromColnodToDB)
{ // {
QString id = token->idToStringWithoutBraces(); // QString id = token->idToStringWithoutBraces();
auto record = db->getToken(id); // auto record = db->getToken(id);
if (!record.isValid()) // if (!record.isValid())
continue; // continue;
auto tokenDB = std::make_shared<Token>(); // auto tokenDB = std::make_shared<Token>();
tokenDB->fromSQLRecord(record); // tokenDB->fromSQLRecord(record);
if (*tokenDB == *token || *tokenDB > *token){ // if (*tokenDB == *token || *tokenDB > *token){
idsToDelete.append(id); // idsToDelete.append(id);
} // }
} // }
for (const auto &id : idsToDelete) // for (const auto &id : idsToDelete)
tokensToUpdateFromColnodToDB.remove(id); // tokensToUpdateFromColnodToDB.remove(id);
} //}
// sync last update from colnod to DB //// sync last update from colnod to DB
void DataManager::setLastUpdate() //void DataManager::setLastUpdate()
{ //{
if (!tokensToUpdateFromColnodToDB.isEmpty()) // if (!tokensToUpdateFromColnodToDB.isEmpty())
for (const auto &token : tokensToUpdateFromColnodToDB) // for (const auto &token : tokensToUpdateFromColnodToDB)
db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate()); // db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate());
} //}
void DataManager::setLastUpdate(const QString &id) //void DataManager::setLastUpdate(const QString &id)
{ //{
db->setLastUpdate(id, nextLastSync); // db->setLastUpdate(id, nextLastSync);
} //}

View File

@ -52,15 +52,14 @@ public:
const quint64 &getLastSync() {return lastSync;} const quint64 &getLastSync() {return lastSync;}
const quint64 &getCurrentSync() {return nextLastSync;} const quint64 &getCurrentSync() {return nextLastSync;}
bool isDBOpened() {return db->isOpen();}
public slots: public slots:
void clear(); // void clear();
void setLastUpdate(); // void setLastUpdate();
void setLastUpdate(const QString &id); // void setLastUpdate(const QString &id);
signals: signals:
void error(); // void error();
private: private:
std::shared_ptr<DatabaseAPI> db; std::shared_ptr<DatabaseAPI> db;

View File

@ -25,19 +25,19 @@ void Entity::setDescription(const QString &description) {
Entity::description = description; Entity::description = description;
} }
quint64 Entity::getLastUpdate() const { qint64 Entity::getLastUpdate() const {
return lastUpdate; return lastUpdate;
} }
void Entity::setLastUpdate(quint64 lastUpdate) { void Entity::setLastUpdate(qint64 lastUpdate) {
this->lastUpdate = lastUpdate; this->lastUpdate = lastUpdate;
} }
quint64 Entity::getLastModified() const { qint64 Entity::getLastModified() const {
return lastModified; return lastModified;
} }
void Entity::setLastModified(const quint64 &lastModified) { void Entity::setLastModified(const qint64 &lastModified) {
this->lastModified = lastModified; this->lastModified = lastModified;
} }

View File

@ -10,7 +10,7 @@
class Entity : public QObject { class Entity : public QObject {
Q_OBJECT Q_OBJECT
public: public:
Entity() = default; explicit Entity() = default;
using QObject::QObject; using QObject::QObject;
const QUuid &getId() const; const QUuid &getId() const;
@ -22,11 +22,11 @@ public:
const QString &getDescription() const; const QString &getDescription() const;
void setDescription(const QString &description); void setDescription(const QString &description);
quint64 getLastUpdate() const; qint64 getLastUpdate() const;
void setLastUpdate(quint64 lastUpdate); void setLastUpdate(qint64 lastUpdate);
quint64 getLastModified() const; qint64 getLastModified() const;
void setLastModified(const quint64 &lastModified); void setLastModified(const qint64 &lastModified);
bool getDeleted() const; bool getDeleted() const;
void setDeleted(const bool &deleted); void setDeleted(const bool &deleted);
@ -43,6 +43,6 @@ private:
QString name; QString name;
QString description; QString description;
qint64 lastUpdate{}; qint64 lastUpdate{};
quint64 lastModified{}; qint64 lastModified{};
bool deleted{}; bool deleted{};
}; };

View File

@ -6,48 +6,48 @@
std::shared_ptr<DatabaseAPI> Logger::dbMan = nullptr; std::shared_ptr<DatabaseAPI> Logger::dbMan = nullptr;
Logger *Logger::logger = nullptr; Logger *Logger::logger = nullptr;
Logger::Logger() //Logger::Logger()
{ //{
dbMan = nullptr; // dbMan = nullptr;
} //}
Logger *Logger::getLogger() //Logger *Logger::getLogger()
{ //{
if (!logger) // if (!logger)
logger = new Logger; // logger = new Logger;
return logger; // return logger;
} //}
void Logger::log(const QString& msg) //void Logger::log(const QString& msg)
{ //{
qDebug() << msg; // qDebug() << msg;
} //}
void Logger::logToDb(const QString &msg) //void Logger::logToDb(const QString &msg)
{ //{
if (dbMan) // if (dbMan)
Logger::dbMan->log(msg); // // Logger::dbMan->log(msg);
} //}
void Logger::setDBMan(std::shared_ptr<DatabaseAPI> dbMan) //void Logger::setDBMan(std::shared_ptr<DatabaseAPI> dbMan)
{ //{
Logger::dbMan = std::move(dbMan); // Logger::dbMan = std::move(dbMan);
} //}
QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source) //QString Logger::makeTokenMsg(const QString &tokenId, const QString &action, const QString &source)
{ //{
return QString("Token: %1 of subject: %2 %3. Source: %4").arg(tokenId,dbMan->getSubjectNameByTokenId(tokenId), action, source); // 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 Logger::makeSubjectMsg(const QString &subjectId, const QString &action, const QString &source)
{ //{
return QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source); // return QString("Subject: %1 %2. Source: %3").arg(dbMan->getSubjectNameById(subjectId), action, source);
} //}
QString Logger::makeErrorMsg(const QString &source, const QString &errMsg) //QString Logger::makeErrorMsg(const QString &source, const QString &errMsg)
{ //{
return QString("Source: %1, Error: %2").arg(source, errMsg); // return QString("Source: %1, Error: %2").arg(source, errMsg);
} //}

View File

@ -28,7 +28,7 @@ std::shared_ptr<Response> RequestManager::login()
connect(reply, &QNetworkReply::finished, [=]() { connect(reply, &QNetworkReply::finished, [=]() {
if (reply->error()) if (reply->error())
{ {
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString())); //Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
loginStatus = false; loginStatus = false;
reply->deleteLater(); reply->deleteLater();
emit error(); emit error();
@ -53,7 +53,7 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA
QObject::connect(reply, &QNetworkReply::finished, [=]() { QObject::connect(reply, &QNetworkReply::finished, [=]() {
if (reply->error()) if (reply->error())
{ {
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString())); //Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
loginStatus = false; loginStatus = false;
reply->deleteLater(); reply->deleteLater();
emit error(); emit error();

View File

@ -2,14 +2,14 @@
bool SyncManager::init() bool SyncManager::init()
{ {
if (database.open() dbMan.openPostgres(QStringLiteral("192.168.1.94"), // move to databaseAPi
QStringLiteral("deloitte"),
QStringLiteral("postgres"),
QStringLiteral("34rjkciea12"),
QStringLiteral("postgres-connection"))){
mlastSync.set_timestamp(database.getLastSync()); if (database->open()){
mlastSync.set_timestamp(database->getLastSync());
colnod = std::make_shared<ColnodAPI>(&reqMan, mlastSync.timestamp());
database = std::make_shared<DatabaseAPI>(&dbMan);
// -1 --> some error with getting data from DB // -1 --> some error with getting data from DB
if (mlastSync.timestamp() >= 0){ if (mlastSync.timestamp() >= 0){
return true; return true;
} }
@ -19,44 +19,45 @@ bool SyncManager::init()
void SyncManager::run() void SyncManager::run()
{ {
qint64 syncBegin = database.getNow(); qint64 syncBegin = database->getNow();
database->initNewTokens();
downloadData(); downloadData();
connect(this, &SyncManager::dataReady, [=](){ connect(this, &SyncManager::dataReady, [=](){
prepareData(); prepareData();
processData(); processData();
connect(this, &SyncManager::processDataFinished, [=](){ connect(this, &SyncManager::dataProcessFinished, [=](){
updateLastUpdate(); // get last_update from colnod after seting tokens TODO: updateLastUpdate(syncBegin);
database.setLastSync(syncBegin); connect(this, &SyncManager::syncFinished, [=](){
QCoreApplication::exit(); database->setLastSync(syncBegin);
QCoreApplication::exit();
});
}); });
}); });
} }
void SyncManager::downloadData() void SyncManager::downloadData()
{ {
colnod.downloadData(); colnod->downloadData();
connect(&colnod, &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
connect(&colnod, &ColnodAPI::downloadDataFinished, this, &SyncManager::areDataReady); connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::areDataReady);
database.downloadData(); database->downloadData();
connect(&database, &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
connect(&database, &DatabaseAPI::downloadDataFinished, this, &SyncManager::areDataReady); connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::areDataReady);
} }
// 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() void SyncManager::prepareData()
{ {
colnodDataToProcess = std::make_shared<Data>(colnodData); colnodDataToProcess = std::make_shared<Data>(*colnodData);
databaseDataToProcess = std::make_shared<Data>(databaseData); databaseDataToProcess = std::make_shared<Data>(*databaseData);
QList<QUuid> idsToDelete; QList<QUuid> idsToDelete;
for (const auto &colnodToken : colnodDataToProcess->updatedTokens) { for (const auto &colnodToken : colnodDataToProcess->updatedTokens) {
if (databaseDataToProcess->updatedTokens.contains(colnodToken.getId())) { if (databaseDataToProcess->updatedTokens.contains(colnodToken->getId())) {
if (databaseDataToProcess->updatedTokens.value(colnodToken.getId()) > colnodToken) // which change was later // if last_update in Colnod and DB equels -> already synced
idsToDelete.append(colnodToken.getId()); if (databaseDataToProcess->updatedTokens.value(colnodToken->getId()) > colnodToken || databaseDataToProcess->updatedTokens.value(colnodToken->getId()) == colnodToken)
idsToDelete.append(colnodToken->getId());
} }
} }
for (const auto &id : idsToDelete) for (const auto &id : idsToDelete)
@ -64,9 +65,9 @@ void SyncManager::prepareData()
idsToDelete.clear(); idsToDelete.clear();
for (const auto &databaseToken : databaseDataToProcess->updatedTokens) { for (const auto &databaseToken : databaseDataToProcess->updatedTokens) {
if (colnodDataToProcess->updatedTokens.contains(databaseToken.getId())) { if (colnodDataToProcess->updatedTokens.contains(databaseToken->getId())) {
if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken.getId())) if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken->getId()))
idsToDelete.append(databaseToken.getId()); idsToDelete.append(databaseToken->getId());
} }
} }
for (const auto &id : idsToDelete) for (const auto &id : idsToDelete)
@ -75,7 +76,20 @@ void SyncManager::prepareData()
void SyncManager::processData() void SyncManager::processData()
{ {
// TODO: colnod->processData(databaseDataToProcess);
database->processData(colnodDataToProcess);
connect(colnod.get(), &ColnodAPI::dataProcessFinished, this, &SyncManager::dataProcessFinished);
}
void SyncManager::updateLastUpdate(qint64 syncBegin)
{
Timestamp time;
time.set_timestamp(syncBegin);
colnod->getTokensUpdated(time);
connect(colnod.get(), &ColnodAPI::partOfDataReady, [=](std::shared_ptr<Data> data){
database->setLastUpdate(data->updatedTokens);
emit syncFinished();
});
} }
void SyncManager::areDataReady() void SyncManager::areDataReady()
@ -128,214 +142,214 @@ void SyncManager::saveDatabaseData(std::shared_ptr<Data> data)
SyncManager::SyncManager(bool dryMode) : //SyncManager::SyncManager(bool dryMode) :
reqMan(std::make_unique<RequestManager>()), // reqMan(std::make_unique<RequestManager>()),
dataMan( std::make_unique<DataManager>(dryMode)), // dataMan( std::make_unique<DataManager>(dryMode)),
dryMode(dryMode) // dryMode(dryMode)
{ //{
connect(reqMan.get(), &RequestManager::error, this, &SyncManager::error, Qt::QueuedConnection); // connect(reqMan.get(), &RequestManager::error, this, &SyncManager::error, Qt::QueuedConnection);
connect(dataMan.get(), &DataManager::error, this, &SyncManager::error, Qt::QueuedConnection); // connect(dataMan.get(), &DataManager::error, this, &SyncManager::error, Qt::QueuedConnection);
} //}
void SyncManager::loadDataFromColnod() //void SyncManager::loadDataFromColnod()
{ //{
loadTokensFromColnod(); // loadTokensFromColnod();
loadUpdatedDataFromColnod(); // loadUpdatedDataFromColnod();
loadDeletedDataFromColnod(); // loadDeletedDataFromColnod();
} //}
// download all tokens form colnod for comparing with tokens to update from DB //// download all tokens form colnod for comparing with tokens to update from DB
void SyncManager::loadTokensFromColnod() //void SyncManager::loadTokensFromColnod()
{ //{
Response* resp = reqMan->getTokens(); // Response* resp = reqMan->getTokens();
connect(resp, &Response::ready, [=](){ // connect(resp, &Response::ready, [=](){
dataMan->fillFullTokensColnod(resp->getJson()); // dataMan->fillFullTokensColnod(resp->getJson());
areChangedDataReady(); // areChangedDataReady();
resp->deleteLater(); // resp->deleteLater();
}); // });
} //}
// fill tokens/subjects to update in data manager //// fill tokens/subjects to update in data manager
void SyncManager::loadUpdatedDataFromColnod() //void SyncManager::loadUpdatedDataFromColnod()
{ //{
uint64_t lastUpdate = dataMan->getLastSync(); // uint64_t lastUpdate = dataMan->getLastSync();
Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate); // Response* resp0 = reqMan->getSubjectsUpdated(lastUpdate);
connect(resp0, &Response::ready, [=](){ // connect(resp0, &Response::ready, [=](){
dataMan->fillSubjectsToUpdateColnod(resp0->getJson()); // dataMan->fillSubjectsToUpdateColnod(resp0->getJson());
areChangedDataReady(); // areChangedDataReady();
resp0->deleteLater(); // resp0->deleteLater();
}); // });
Response* resp1 = reqMan->getTokensUpdated(lastUpdate); // Response* resp1 = reqMan->getTokensUpdated(lastUpdate);
connect(resp1, &Response::ready, [=](){ // connect(resp1, &Response::ready, [=](){
dataMan->fillTokensToUpdateColnod(resp1->getJson()); // dataMan->fillTokensToUpdateColnod(resp1->getJson());
areChangedDataReady(); // areChangedDataReady();
resp1->deleteLater(); // resp1->deleteLater();
}); // });
} //}
// fill tokens/subjects to delete in data manager //// fill tokens/subjects to delete in data manager
void SyncManager::loadDeletedDataFromColnod() //void SyncManager::loadDeletedDataFromColnod()
{ //{
uint64_t lastUpdate = dataMan->getLastSync(); // uint64_t lastUpdate = dataMan->getLastSync();
Response* resp2 = reqMan->getSubjectsDeleted(lastUpdate); // Response* resp2 = reqMan->getSubjectsDeleted(lastUpdate);
connect(resp2, &Response::ready, [=](){ // connect(resp2, &Response::ready, [=](){
dataMan->fillSubjectsToDeleteColnod(resp2->getJson()); // dataMan->fillSubjectsToDeleteColnod(resp2->getJson());
areChangedDataReady(); // areChangedDataReady();
resp2->deleteLater(); // resp2->deleteLater();
}); // });
Response* resp3 = reqMan->getTokensDeleted(lastUpdate); // Response* resp3 = reqMan->getTokensDeleted(lastUpdate);
connect(resp3, &Response::ready, [=](){ // connect(resp3, &Response::ready, [=](){
dataMan->fillTokensToDeleteColnod(resp3->getJson()); // dataMan->fillTokensToDeleteColnod(resp3->getJson());
areChangedDataReady(); // areChangedDataReady();
resp3->deleteLater(); // resp3->deleteLater();
}); // });
} //}
// fill structures in data manager (tokens to updata/to delte) //// fill structures in data manager (tokens to updata/to delte)
void SyncManager::loadDataFromDB() //void SyncManager::loadDataFromDB()
{ //{
dataMan->fillTokensToChangeDB(); // dataMan->fillTokensToChangeDB();
} //}
void SyncManager::syncDataFromColnodToDB() //void SyncManager::syncDataFromColnodToDB()
{ //{
syncUpdatedDataFromColnodToDB(); // syncUpdatedDataFromColnodToDB();
if (dataMan->getLastSync() != 0) // if (dataMan->getLastSync() != 0)
syncDeletedDataFromColnodToDB(); // syncDeletedDataFromColnodToDB();
} //}
// push data from colnod to DB //// push data from colnod to DB
void SyncManager::syncUpdatedDataFromColnodToDB() //void SyncManager::syncUpdatedDataFromColnodToDB()
{ //{
dataMan->pushSubjectsToDB(); // dataMan->pushSubjectsToDB();
dataMan->pushTokensToDB(); // dataMan->pushTokensToDB();
} //}
// set deleted tokens from Colnod, delete subject //// set deleted tokens from Colnod, delete subject
void SyncManager::syncDeletedDataFromColnodToDB() //void SyncManager::syncDeletedDataFromColnodToDB()
{ //{
dataMan->deleteSubjectsFromDB(); // dataMan->deleteSubjectsFromDB();
dataMan->setDeletedToTokensFromDB(); // dataMan->setDeletedToTokensFromDB();
} //}
// push changes form DB to Colnod //// push changes form DB to Colnod
void SyncManager::syncDataFromDBToColnod() //void SyncManager::syncDataFromDBToColnod()
{ //{
connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear); // connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::clear);
//connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync); // //connect(this, &SyncManager::dataUpdatedToColnod, dataMan.get(), &DataManager::setLastSync);
if (!dryMode) // if (!dryMode)
connect(this, &SyncManager::dataUpdatedToColnod, [=](){ // connect(this, &SyncManager::dataUpdatedToColnod, [=](){
auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync()); // auto resp = reqMan->getTokensUpdated(dataMan->getCurrentSync());
connect(resp, &Response::ready, [=](){ // connect(resp, &Response::ready, [=](){
dataMan->fillTokensToUpdateColnod(resp->getJson()); // dataMan->fillTokensToUpdateColnod(resp->getJson());
dataMan->setLastUpdate(); // dataMan->setLastUpdate();
dataMan->clear(); // dataMan->clear();
dataMan->updateLastSync(); // dataMan->updateLastSync();
emit syncFinished(); // emit syncFinished();
resp->deleteLater(); // resp->deleteLater();
}); // });
}); // });
else // else
connect(this, &SyncManager::dataUpdatedToColnod, [=](){ // connect(this, &SyncManager::dataUpdatedToColnod, [=](){
dataMan->updateLastSync(); // dataMan->updateLastSync();
emit syncFinished(); // emit syncFinished();
}); // });
if (!dataMan->getTokensToUpdateFromDB().isEmpty()){ // if (!dataMan->getTokensToUpdateFromDB().isEmpty()){
syncUpdatedDataFromDBToColnod(); // syncUpdatedDataFromDBToColnod();
} // }
else // else
updateFinished = true; // updateFinished = true;
if (!dataMan->getTokensToDeleteDB().isEmpty()){ // if (!dataMan->getTokensToDeleteDB().isEmpty()){
syncDeletedDataFromDBToColnod(); // syncDeletedDataFromDBToColnod();
} // }
else{ // else{
deleteFinished = true; // deleteFinished = true;
areDataUpdatedToColnod(); // areDataUpdatedToColnod();
} // }
} //}
// add or update tokens to Colnod //// add or update tokens to Colnod
void SyncManager::syncUpdatedDataFromDBToColnod() //void SyncManager::syncUpdatedDataFromDBToColnod()
{ //{
dataMan->filterTokensDB(); // dataMan->filterTokensDB();
auto tokensToUpdate = dataMan->getTokensToUpdateFromDB(); // auto tokensToUpdate = dataMan->getTokensToUpdateFromDB();
if (dryMode){ // if (dryMode){
for (const auto &token : tokensToUpdate) // for (const auto &token : tokensToUpdate)
qInfo() << "Updating token:" << token->idToStringWithoutBraces() << "to Colnod"; // qInfo() << "Updating token:" << token->idToStringWithoutBraces() << "to Colnod";
updateFinished = true; // updateFinished = true;
areDataUpdatedToColnod(); // areDataUpdatedToColnod();
} // }
else { // else {
Response* resp0 = reqMan->setTokens(tokensToUpdate); // Response* resp0 = reqMan->setTokens(tokensToUpdate);
connect(resp0, &Response::ready, [=](){ // connect(resp0, &Response::ready, [=](){
qInfo() << "Colnod:" << tokensToUpdate.size() << "tokens updated"; // qInfo() << "Colnod:" << tokensToUpdate.size() << "tokens updated";
for(const auto &token : tokensToUpdate) // for(const auto &token : tokensToUpdate)
Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "updated", "Colnod")); // Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), "updated", "Colnod"));
updateFinished = true; // updateFinished = true;
areDataUpdatedToColnod(); // areDataUpdatedToColnod();
resp0->deleteLater(); // resp0->deleteLater();
}); // });
} // }
} //}
// delete tokens in Colnod //// delete tokens in Colnod
void SyncManager::syncDeletedDataFromDBToColnod() //void SyncManager::syncDeletedDataFromDBToColnod()
{ //{
auto tokensToDelete = dataMan->getTokensToDeleteDB(); // auto tokensToDelete = dataMan->getTokensToDeleteDB();
if (dryMode){ // if (dryMode){
for (const auto &token : tokensToDelete) // for (const auto &token : tokensToDelete)
qInfo() << "Deleting token:" << token << "from Colnod"; // qInfo() << "Deleting token:" << token << "from Colnod";
deleteFinished = true; // deleteFinished = true;
areDataUpdatedToColnod(); // areDataUpdatedToColnod();
} // }
else { // else {
Response* resp1 = reqMan->deleteTokens(tokensToDelete); // Response* resp1 = reqMan.deleteTokens(tokensToDelete);
connect(resp1, &Response::ready, [=](){ // connect(resp1, &Response::ready, [=](){
qInfo() << "Colnod:" << tokensToDelete.size() << "tokens deleted"; // qInfo() << "Colnod:" << tokensToDelete.size() << "tokens deleted";
for (const auto &id : tokensToDelete){ // for (const auto &id : tokensToDelete){
dataMan->setLastUpdate(id); // dataMan->setLastUpdate(id);
Logger::logToDb(Logger::makeTokenMsg(id, "deleted", "Colnod")); // Logger::logToDb(Logger::makeTokenMsg(id, "deleted", "Colnod"));
} // }
deleteFinished = true; // deleteFinished = true;
areDataUpdatedToColnod(); // areDataUpdatedToColnod();
resp1->deleteLater(); // resp1->deleteLater();
}); // });
} // }
} //}
// For full sync //// For full sync
void SyncManager::dropTables() //void SyncManager::dropTables()
{ //{
dataMan->dropTables(); // dataMan->dropTables();
} //}
void SyncManager::createTables() //void SyncManager::createTables()
{ //{
dataMan->createTables(); // dataMan->createTables();
} //}
bool SyncManager::isValid() //bool SyncManager::isValid()
{ //{
return dataMan->isDBOpened(); // return dataMan->isDBOpened();
} //}
// emit signal when all data is downloaded from Colnod //// emit signal when all data is downloaded from Colnod
void SyncManager::areChangedDataReady() //void SyncManager::areChangedDataReady()
{ //{
if (++dataCounter == 5) // if (++dataCounter == 5)
emit dataReady(); // emit dataReady();
} //}
// emit signal when writing to Colnod is finised //// emit signal when writing to Colnod is finised
void SyncManager::areDataUpdatedToColnod() //void SyncManager::areDataUpdatedToColnod()
{ //{
if (deleteFinished && updateFinished) // if (deleteFinished && updateFinished)
{ // {
emit dataUpdatedToColnod(); // emit dataUpdatedToColnod();
} // }
} //}

View File

@ -21,21 +21,22 @@ private:
void downloadData(); void downloadData();
void prepareData(); void prepareData();
void processData(); void processData();
void updateLastUpdate(qint64 syncBegin);
private: private:
Q_SLOTS void saveColnodData(std::shared_ptr<Data> data); Q_SLOT void saveColnodData(std::shared_ptr<Data> data);
Q_SLOTS void saveDatabaseData(std::shared_ptr<Data> data); Q_SLOT void saveDatabaseData(std::shared_ptr<Data> data);
Q_SLOTS void areDataReady(); Q_SLOT void areDataReady();
signals: signals:
void dataReady(); void dataReady();
void processDataFinished(); void dataProcessFinished();
void syncFinished();
private: private:
ColnodAPI colnod; std::shared_ptr<ColnodAPI> colnod;
DatabaseAPI database; std::shared_ptr<DatabaseAPI> database;
serversdk::RequestManager reqMan; serversdk::RequestManager reqMan;
serversdk::DatabaseManager dbMan; serversdk::DatabaseManager dbMan;
Timestamp mlastSync; Timestamp mlastSync;
@ -61,52 +62,51 @@ private:
// OLD // OLD
public: //public:
explicit SyncManager(bool dryMode = false); // explicit SyncManager(bool dryMode = false);
void syncDataFromColnodToDB(); // void syncDataFromColnodToDB();
void syncDataFromDBToColnod(); // void syncDataFromDBToColnod();
void dropTables(); // void dropTables();
void createTables(); // void createTables();
bool isValid(); // bool isValid();
public slots: //public slots:
void loadDataFromColnod(); // void loadDataFromColnod();
void loadDataFromDB(); // void loadDataFromDB();
signals: //signals:
void dataReady(); // void dataUpdatedToColnod();
void dataUpdatedToColnod();
void syncFinished();
void error();
private slots: // void error();
//private slots:
private: //private:
void loadTokensFromColnod(); // void loadTokensFromColnod();
void loadUpdatedDataFromColnod(); // void loadUpdatedDataFromColnod();
void loadDeletedDataFromColnod(); // void loadDeletedDataFromColnod();
void loadUpdatedDataFromDB(); // void loadUpdatedDataFromDB();
void loadDeletedDataFromDB(); // void loadDeletedDataFromDB();
void syncUpdatedDataFromColnodToDB(); // void syncUpdatedDataFromColnodToDB();
void syncDeletedDataFromColnodToDB(); // void syncDeletedDataFromColnodToDB();
void syncUpdatedDataFromDBToColnod(); // void syncUpdatedDataFromDBToColnod();
void syncDeletedDataFromDBToColnod(); // void syncDeletedDataFromDBToColnod();
void areChangedDataReady(); // void areChangedDataReady();
void areDataUpdatedToColnod(); // void areDataUpdatedToColnod();
private: //private:
// std::unique_ptr<RequestManager> reqMan; // // std::unique_ptr<RequestManager> reqMan;
std::unique_ptr<DataManager> dataMan; // std::unique_ptr<DataManager> dataMan;
bool dryMode = false; // bool dryMode = false;
bool updateFinished = false; // bool updateFinished = false;
bool deleteFinished = false; // bool deleteFinished = false;
int dataCounter = 0; // int dataCounter = 0;
}; };

View File

@ -53,13 +53,13 @@ QJsonObject Token::toJSON() const {
return json; return json;
} }
QByteArray Token::tokensToJSON(const QHash<QUuid, Token> &tokens) QByteArray Token::tokensToJSON(const QHash<QUuid, std::shared_ptr<Token>> &tokens)
{ {
QJsonObject items; QJsonObject items;
QJsonArray jsonTokens; QJsonArray jsonTokens;
for (const auto& token : tokens) for (const auto& token : tokens)
{ {
jsonTokens.push_back(token.toJSON()); jsonTokens.push_back(token->toJSON());
} }
items.insert("items", jsonTokens); items.insert("items", jsonTokens);
QJsonDocument doc; QJsonDocument doc;
@ -67,6 +67,20 @@ QByteArray Token::tokensToJSON(const QHash<QUuid, Token> &tokens)
return doc.toJson(); return doc.toJson();
} }
QByteArray Token::idsToJSON(const QList<QString> &ids)
{
QJsonArray jsonIds;
for (const auto& id : ids)
{
jsonIds.push_back(id);
}
QJsonObject items;
items.insert("items", jsonIds);
QJsonDocument doc;
doc.setObject(items);
return doc.toJson();
}
void Token::fromSQLRecord(const QSqlQuery& query) void Token::fromSQLRecord(const QSqlQuery& query)
{ {
setId(query.value(0).toUuid()); setId(query.value(0).toUuid());

View File

@ -21,7 +21,7 @@ public:
* *
*/ */
Token() = default; explicit Token() = default;
Token(const QString& name, QString tokenData, const QString& decription = "mobile"); Token(const QString& name, QString tokenData, const QString& decription = "mobile");
explicit Token(const QString& name); explicit Token(const QString& name);
~Token() override; ~Token() override;
@ -69,7 +69,8 @@ public:
void fromJSON(const QJsonObject &json) override; void fromJSON(const QJsonObject &json) override;
QJsonObject toJSON() const override; QJsonObject toJSON() const override;
static QByteArray tokensToJSON(const QHash<QUuid, Token> &tokens); static QByteArray tokensToJSON(const QHash<QUuid, std::shared_ptr<Token> > &tokens);
static QByteArray idsToJSON(const QList<QString> &ids);
private: private:
QString tokenType = "Token"; QString tokenType = "Token";