WIP: cant compile, structure

This commit is contained in:
Ondřej Fischer 2019-11-13 17:13:38 +01:00
parent fcbb030ce9
commit 9bf2eb05e8
16 changed files with 601 additions and 164 deletions

View File

@ -1,30 +1,32 @@
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
CONFIG += c++14 CONFIG += c++14
SOURCES += \ SOURCES += \
$$PWD/colnodapi.cpp \ $$PWD/colnodapi.cpp \
$$PWD/databasemanager.cpp \ $$PWD/data.cpp \
$$PWD/datamanager.cpp \ $$PWD/databaseapi.cpp \
$$PWD/entity.cpp \ $$PWD/datamanager.cpp \
$$PWD/logger.cpp \ $$PWD/entity.cpp \
$$PWD/requestmanager.cpp \ $$PWD/logger.cpp \
$$PWD/response.cpp \ $$PWD/requestmanager.cpp \
$$PWD/subject.cpp \ $$PWD/response.cpp \
$$PWD/syncmanager.cpp \ $$PWD/subject.cpp \
$$PWD/token.cpp $$PWD/syncmanager.cpp \
$$PWD/token.cpp
HEADERS += \
$$PWD/colnodapi.h \ HEADERS += \
$$PWD/databasemanager.h \ $$PWD/colnodapi.h \
$$PWD/datamanager.h \ $$PWD/data.h \
$$PWD/entity.h \ $$PWD/databaseapi.h \
$$PWD/logger.h \ $$PWD/datamanager.h \
$$PWD/requestmanager.h \ $$PWD/entity.h \
$$PWD/response.h \ $$PWD/logger.h \
$$PWD/subject.h \ $$PWD/requestmanager.h \
$$PWD/syncmanager.h \ $$PWD/response.h \
$$PWD/token.h $$PWD/subject.h \
$$PWD/syncmanager.h \
include(../../server-sdk/serversdk.pri) $$PWD/token.h
include(../../server-sdk/serversdk.pri)

View File

@ -4,26 +4,36 @@ ColnodAPI::ColnodAPI()
{ {
} }
ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan) ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, QString userName, QString password, qint64 lastSync)
:mReqMan(reqMan) :mReqMan(reqMan), mUserName(userName), mPassword(password)
{ {
mLastSync.set_timestamp(lastSync);
} }
void ColnodAPI::downloadData() void ColnodAPI::downloadData()
{ {
// Have to get Login // Have to get Login
auto login = requestLogin(); auto login = requestLogin();
connect(login.get(), &serversdk::Request::finished, this, [=](){ connect(login.get(), &serversdk::Request::finished, this, [=](){ // TODO: error handling
// Get token // Get token
AuthToken token; AuthToken token;
token.fromJson(login->responseData()); token.fromJson(login->responseData());
authToken = token.idWithoutCurlyBraces();
auto data = std::make_shared<ColnodData>(); // if I have all data emit downloadDataFinished
emit downloadDataFinished(); connect(this, &ColnodAPI::partOfDataReady, this, &ColnodAPI::areDataReady);
getTokensUpdated(mLastSync);
getTokensDeleted(mLastSync);
getSubjectsUpdated(mLastSync);
getSubjectsDeleted(mLastSync);
}); });
} }
void ColnodAPI::uploadData(std::shared_ptr<Data> data)
{
setTokens(data->updatedTokens);
}
std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin() std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
{ {
Q_ASSERT(mReqMan); Q_ASSERT(mReqMan);
@ -38,7 +48,6 @@ std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
login.set_password(encodedPassword); login.set_password(encodedPassword);
auto loginRequest = composeRequest("/AaaManager/authSession", login.jsonData()); auto loginRequest = composeRequest("/AaaManager/authSession", login.jsonData());
// auto loginRequest = std::make_shared<serversdk::Request>("POST", "https://192.168.1.3:8443/AaaManager/authSession", login->jsonData());
loginRequest->setUserName(login.username()); loginRequest->setUserName(login.username());
loginRequest->setPassword(login.password()); loginRequest->setPassword(login.password());
mReqMan->processRequest(loginRequest); mReqMan->processRequest(loginRequest);
@ -46,50 +55,74 @@ std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
return loginRequest; return loginRequest;
} }
QList<Token> ColnodAPI::getTokensUpdated(const qint64 &time) void ColnodAPI::getTokensUpdated(const Timestamp &time)
{ {
// AuthToken token; auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData());
// token.fromJson(data); request->setToken(authToken);
// serversdk::Request request("POST", host + "/TokenManager/getTokensUpdated", getTimestampJson(time)); mReqMan->processRequest(request);
// request.setToken(mToken); connect(request.get(), &serversdk::Request::finished, [=](){
// mReqMan->processRequest(); saveUpdatedTokens(request->responseData());
} emit partOfDataReady();
QString ColnodAPI::login(const QString &username, const QString &password)
{
auto login = std::make_unique<LoginResp>();
login->set_username(username);
login->set_password(QCryptographicHash::hash(QString(password).toLocal8Bit(), QCryptographicHash::Sha512).toHex().toUpper());
serversdk::RequestManager reqMan;
reqMan.setIgnoreSsl(true);
auto loginRequest = std::make_shared<serversdk::Request>("POST", "https://192.168.1.3:8443/AaaManager/authSession", login->jsonData());
loginRequest->setUserName(login->username());
loginRequest->setPassword(login->password());
reqMan.processRequest(loginRequest);
QObject::connect(loginRequest.get(), &serversdk::Request::finished, [=](){
auto data = loginRequest->responseData();
AuthToken token;
token.fromJson(data);
return token.idWithoutCurlyBraces();
}); });
} }
QByteArray ColnodAPI::getTimestampJson(const qint64 &time) void ColnodAPI::getTokensDeleted(const Timestamp &time)
{ {
QJsonObject reqBody = {{"timestamp",QJsonValue(time)}}; auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData());
QJsonDocument doc; request->setToken(authToken);
doc.setObject(reqBody); mReqMan->processRequest(request);
return doc.toJson(); connect(request.get(), &serversdk::Request::finished, [=](){
saveDeletedTokens(request->responseData());
emit partOfDataReady();
});
}
void ColnodAPI::getSubjectsUpdated(const Timestamp &time)
{
auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData());
request->setToken(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveUpdatedSubjects(request->responseData());
emit partOfDataReady();
});
}
void ColnodAPI::getSubjectsDeleted(const Timestamp &time)
{
auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData());
request->setToken(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveDeletedSubjects(request->responseData());
emit partOfDataReady();
});
}
void ColnodAPI::setTokens(const QHash<QUuid, Token> &tokens)
{
auto request = composeRequest("/TokenManager/setTokens", Token::tokensToJSON(tokens));
request->setToken(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
if (checkResponse(request->responseData())) {
emit partOfDataProcessFinished();
}
else {
}
});
}
void ColnodAPI::deleteTokens(const QList<QString> &tokenIds)
{
} }
std::shared_ptr<serversdk::Request> ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data) std::shared_ptr<serversdk::Request> ColnodAPI::composeRequest(const QString &endpoint, const QByteArray &data)
{ {
QString url = host + endpoint; QString url = mHost + endpoint;
return std::make_shared<serversdk::Request>("POST", url, data); return std::make_shared<serversdk::Request>("POST", url, data);
} }
@ -103,6 +136,17 @@ void ColnodAPI::setPassword(const QString &password)
mPassword = password; mPassword = password;
} }
qint64 ColnodAPI::lastSync() const
{
return mLastSync.timestamp();
}
void ColnodAPI::setlastSync(const qint64 &lastSync)
{
mLastSync.set_timestamp(lastSync);
}
QString ColnodAPI::userName() const QString ColnodAPI::userName() const
{ {
return mUserName; return mUserName;
@ -112,3 +156,52 @@ void ColnodAPI::setUserName(const QString &userName)
{ {
mUserName = userName; mUserName = userName;
} }
void ColnodAPI::areDataReady()
{
if (++amountData == 4) {
emit downloadDataFinished(data);
}
}
void ColnodAPI::saveUpdatedTokens(const QByteArray &responseData)
{
QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) {
Token token;
token.fromJSON(item.toObject());
token.setDeleted(false);
data->updatedTokens.insert(token.getId(), token);
}
}
void ColnodAPI::saveDeletedTokens(const QByteArray &responseData)
{
QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) {
data->deletedTokens.append(item.toString());
}
}
void ColnodAPI::saveUpdatedSubjects(const QByteArray &responseData)
{
QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) {
Subject subject;
subject.fromJSON(item.toObject());
subject.setDeleted(false);
data->updatedSubjects.insert(subject.getId(), subject);
}
}
void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData)
{
QJsonDocument doc = QJsonDocument::fromJson(responseData);
QJsonArray items = doc.object()["items"].toArray();
for (QJsonValueRef item : items) {
data->deletedSubjects.append(item.toString());
}
}

View File

@ -1,22 +1,10 @@
#pragma once #pragma once
#include "serversdk/requestmanager.h"
#include "serversdk/request.h"
#include "token.h"
#include "subject.h"
#include "serversdk/requestmanager.h" #include "serversdk/requestmanager.h"
#include "serversdk/request.h" #include "serversdk/request.h"
#include "serversdk/databasetable.h" #include "serversdk/databasetable.h"
#include "QDateTime"
struct ColnodData #include "data.h"
{
QList<std::shared_ptr<Token>> updatedTokens;
QList<std::shared_ptr<Token>> updatedSubjects;
QList<std::shared_ptr<Token>> deletedTokens;
QList<std::shared_ptr<Token>> deletedSubjects;
bool isValid();
};
class LoginResp : public serversdk::DatabaseTable { class LoginResp : public serversdk::DatabaseTable {
Q_OBJECT Q_OBJECT
@ -34,45 +22,75 @@ class AuthToken : public serversdk::DatabaseTable {
} }
}; };
class Timestamp : public serversdk::DatabaseTable {
Q_OBJECT
TABLE_PROPERTY(qint64, timestamp, set_timestamp, 0)
QString toDateString()
{
return QDateTime::fromMSecsSinceEpoch(a_timestamp).toString("yyyy-MM-dd hh:mm:ss.zzz");
}
};
class ColnodAPI: public QObject class ColnodAPI: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ColnodAPI(); ColnodAPI();
ColnodAPI(serversdk::RequestManager* reqMan); ColnodAPI(serversdk::RequestManager* reqMan, QString userName = "spaceti", QString password = "spaceti1", qint64 lastSync = 0);
void downloadData(); void downloadData();
void uploadData(std::shared_ptr<Data> data);
// New approach // New approach
std::shared_ptr<serversdk::Request> requestLogin(); std::shared_ptr<serversdk::Request> requestLogin();
QList<Token> getTokensUpdated(const qint64 &time); void getTokensUpdated(const Timestamp &time);
QList<QString> getTokensDeleted(const qint64 &time); void getTokensDeleted(const Timestamp &time);
QList<Subject> getSubjectsUpdated(const qint64 &time); void getSubjectsUpdated(const Timestamp &time);
QList<QString> getSubjectsDeleted(const qint64 &time); void getSubjectsDeleted(const Timestamp &time);
bool setTokens(const QList<Token> &tokens); void setTokens(const QHash<QUuid, Token> &tokens);
bool deleteTokens(const QList<QString> &tokenIds); void deleteTokens(const QList<QString> &tokenIds);
// Attributes // Attributes
QString userName() const; QString userName() const;
void setUserName(const QString &userName); void setUserName(const QString &userName);
QString password() const; QString password() const;
void setPassword(const QString &password); void setPassword(const QString &password);
qint64 lastSync() const;
void setlastSync(const qint64 &lastSync);
private: private:
QString login(const QString &username, const QString &password); Q_SLOT void areDataReady();
private:
void saveUpdatedTokens(const QByteArray &responseData);
void saveUpdatedSubjects(const QByteArray &responseData);
void saveDeletedTokens(const QByteArray &responseData);
void saveDeletedSubjects(const QByteArray &responseData);
bool checkResponse(const QByteArray &responseData);
QByteArray getTimestampJson(const qint64 &time); QByteArray getTimestampJson(const qint64 &time);
std::shared_ptr<serversdk::Request> composeRequest(const QString &endpoint, const QByteArray &data); std::shared_ptr<serversdk::Request> composeRequest(const QString &endpoint, const QByteArray &data);
signals: signals:
void downloadDataFinished(std::shared_ptr<ColnodData> = std::shared_ptr<ColnodData>()); void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>());
void partOfDataReady();
void partOfDataProcessFinished();
private: private:
serversdk::RequestManager* mReqMan = nullptr; serversdk::RequestManager* mReqMan = nullptr;
QString host = "https://192.168.1.3:8443"; QString mHost = "https://192.168.1.3:8443";
QString mUserName; QString mUserName;
QString mPassword; QString mPassword;
Timestamp mLastSync;
std::shared_ptr<Data> data;
QString authToken;
qint16 amountData = 0;
}; };

6
src/colnod/data.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "data.h"
Data::Data()
{
}

17
src/colnod/data.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "token.h"
#include "subject.h"
class Data
{
public:
Data();
QHash<QUuid, Token> updatedTokens;
QList<QString> deletedTokens;
QHash<QUuid, Subject> updatedSubjects;
QList<QString> deletedSubjects;
};

View File

@ -1,8 +1,99 @@
#include "databasemanager.h" #include "databaseapi.h"
#include "logger.h" #include "logger.h"
DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode) DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan)
:mDbMan(dbMan)
{
}
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 "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = false");
QSqlQuery deletedQuery = mDbMan->execPlainSql("SELECT id "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = true");
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
}
std::shared_ptr<Data> DatabaseAPI::composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery)
{
auto data = std::make_shared<Data>();
while (updatedQuery.next()) {
Token token;
token.fromSQLRecord(updatedQuery);
data->updatedTokens.append(token);
}
while (deletedQuery.next()) {
data->deletedTokens.append(deletedQuery.value(0).toString());
}
return data;
}
qint64 DatabaseAPI::getLastSync()
{
auto query = mDbMan->execPlainSql("SELECT last_sync FROM config");
if (query.next()){
return query.value(0).toLongLong();
}
else {
return -1;
}
}
void DatabaseAPI::setLastSync(qint64 timestamp)
{
QSqlQuery query;
query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", timestamp);
executeQuery(query);
}
qint64 DatabaseAPI::getNow()
{
QSqlQuery query = mDbMan->execPlainSql("SELECT EXTRACT(EPOCH FROM NOW())*1000");
query.next();
return query.value(0).toLongLong();
}
// OLD
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");
@ -22,7 +113,7 @@ DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, con
} }
// add or update subject to db // add or update subject to db
int DatabaseManager::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();
@ -47,8 +138,17 @@ int DatabaseManager::saveSubject(const std::shared_ptr<Subject>& subject, const
return rtn; return rtn;
} }
QSqlQuery DatabaseAPI::getUpdatedTokens()
{
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 AND deleted = false");
return query;
}
// add or update token to DB // add or update token to DB
int DatabaseManager::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();
@ -81,7 +181,7 @@ int DatabaseManager::saveToken(const std::shared_ptr<Token>& token, const QStrin
} }
// add of update subject attributes // add of update subject attributes
void DatabaseManager::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();
@ -103,7 +203,7 @@ void DatabaseManager::saveSubjectAttributes(const std::shared_ptr<Subject>& subj
} }
// "delete" tokens from DB -> set deleted true // "delete" tokens from DB -> set deleted true
void DatabaseManager::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");
@ -113,7 +213,7 @@ void DatabaseManager::setDeleted(const QString& id, const QString& table, quint6
executeQuery(query); executeQuery(query);
} }
bool DatabaseManager::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));
@ -123,7 +223,7 @@ bool DatabaseManager::checkIfExists(const QString& id, const QString& table)
return query.value(0).toBool(); return query.value(0).toBool();
} }
QString DatabaseManager::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());
@ -135,7 +235,7 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const
return str; return str;
} }
bool DatabaseManager::executeQuery(QSqlQuery &query, const QString &statement) bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
{ {
if (statement.isEmpty()){ if (statement.isEmpty()){
if (dryMode){ if (dryMode){
@ -164,7 +264,7 @@ bool DatabaseManager::executeQuery(QSqlQuery &query, const QString &statement)
return true; return true;
} }
void DatabaseManager::dropTables() void DatabaseAPI::dropTables()
{ {
QSqlQuery query; QSqlQuery query;
@ -172,7 +272,7 @@ void DatabaseManager::dropTables()
} }
// create table after deleting, it is used for full sync // create table after deleting, it is used for full sync
void DatabaseManager::createTables() void DatabaseAPI::createTables()
{ {
QSqlQuery query; QSqlQuery query;
@ -206,36 +306,14 @@ void DatabaseManager::createTables()
"subject_id CHAR(36))"); "subject_id CHAR(36))");
} }
// return last_sync time
quint64 DatabaseManager::getLastSync()
{
QSqlQuery query;
executeQuery(query, "SELECT last_sync FROM config");
query.next();
quint64 temp = query.value(0).toULongLong();
return temp;
}
// 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)
void DatabaseManager::updateLastSync(quint64 lastSync)
{
QSqlQuery query;
query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", lastSync);
executeQuery(query);
}
// return set of tokens to update form DB // return set of tokens to update form DB
QSqlQuery DatabaseManager::getUpdatedTokens()
{
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 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 "
@ -246,16 +324,10 @@ QSqlQuery DatabaseManager::getToken(const QString& id)
return query; return query;
} }
quint64 DatabaseManager::getNow()
{
QSqlQuery query;
executeQuery(query, "SELECT EXTRACT(EPOCH FROM NOW())*1000");
query.next();
return query.value(0).toULongLong();
}
// 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 DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate) void DatabaseAPI::setLastUpdate(const QString& id, quint64 lastUpdate)
{ {
QSqlQuery query; QSqlQuery query;
QString lsatUpdateString = QDateTime::fromMSecsSinceEpoch(lastUpdate).toString("yyyy-MM-dd hh:mm:ss.zzz"); QString lsatUpdateString = QDateTime::fromMSecsSinceEpoch(lastUpdate).toString("yyyy-MM-dd hh:mm:ss.zzz");
@ -265,7 +337,7 @@ void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate)
executeQuery(query); executeQuery(query);
} }
void DatabaseManager::log(const QString &msg) void DatabaseAPI::log(const QString &msg)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)"); query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)");
@ -273,7 +345,7 @@ void DatabaseManager::log(const QString &msg)
query.exec(); query.exec();
} }
QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId) QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)"); query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)");
@ -285,7 +357,7 @@ QString DatabaseManager::getSubjectNameByTokenId(const QString &tokenId)
return "(No subject)"; return "(No subject)";
} }
QString DatabaseManager::getSubjectNameById(const QString &id) QString DatabaseAPI::getSubjectNameById(const QString &id)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = :id"); query.prepare("SELECT name FROM colnod_subject WHERE id = :id");
@ -297,7 +369,7 @@ QString DatabaseManager::getSubjectNameById(const QString &id)
return "(No subject)"; return "(No subject)";
} }
bool DatabaseManager::checkDeletedToken(const QString &id) bool DatabaseAPI::checkDeletedToken(const QString &id)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT deleted FROM colnod_token WHERE id = :id"); query.prepare("SELECT deleted FROM colnod_token WHERE id = :id");
@ -307,7 +379,7 @@ bool DatabaseManager::checkDeletedToken(const QString &id)
return query.value(0).toBool(); return query.value(0).toBool();
} }
qint16 DatabaseManager::getNumOfTokensOfSubject(const QString &id) qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT 1 FROM colnod_token WHERE subject_id = :id AND deleted = false"); query.prepare("SELECT 1 FROM colnod_token WHERE subject_id = :id AND deleted = false");
@ -316,7 +388,7 @@ qint16 DatabaseManager::getNumOfTokensOfSubject(const QString &id)
return static_cast<qint16>(query.size()); return static_cast<qint16>(query.size());
} }
bool DatabaseManager::isOpen() bool DatabaseAPI::isOpen()
{ {
return opened; return opened;
} }

View File

@ -10,13 +10,47 @@
#include "subject.h" #include "subject.h"
#include "token.h" #include "token.h"
#include <QDateTime> #include <QDateTime>
#include "data.h"
#include "serversdk/databasemanager.h"
#include "serversdk/databasetable.h"
class DatabaseManager : public QObject
class TokenTable : public serversdk::DatabaseTable {
Q_OBJECT
};
class DatabaseAPI : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool& dryMode = false); DatabaseAPI(serversdk::DatabaseManager *dbMan);
void downloadData();
qint64 getLastSync();
void setLastSync(qint64 timestamp);
qint64 getNow();
private:
QSqlQuery getUpdatedTokens();
std::shared_ptr<Data> composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery);
signals:
void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>());
private:
serversdk::DatabaseManager *mDbMan = nullptr;
// old
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);
@ -26,11 +60,8 @@ public:
void dropTables(); void dropTables();
void createTables(); void createTables();
quint64 getLastSync();
void updateLastSync(quint64 lastSync); void updateLastSync(quint64 lastSync);
quint64 getNow();
QSqlQuery getUpdatedTokens();
QSqlQuery getToken(const QString& id); QSqlQuery getToken(const QString& id);
void setLastUpdate(const QString& id, quint64 lastUpdate); void setLastUpdate(const QString& id, quint64 lastUpdate);

View File

@ -1,7 +1,7 @@
#include "datamanager.h" #include "datamanager.h"
DataManager::DataManager(const bool &dryMode) : DataManager::DataManager(const bool &dryMode) :
db(std::make_shared<DatabaseManager>("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()){
@ -9,7 +9,7 @@ DataManager::DataManager(const bool &dryMode) :
nextLastSync = db->getNow(); nextLastSync = db->getNow();
lastSync = db->getLastSync(); lastSync = db->getLastSync();
} }
connect(db.get(), &DatabaseManager::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

View File

@ -3,7 +3,7 @@
#include "token.h" #include "token.h"
#include "subject.h" #include "subject.h"
#include "requestmanager.h" #include "requestmanager.h"
#include "databasemanager.h" #include "databaseapi.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <qjsonarray.h> #include <qjsonarray.h>
#include <logger.h> #include <logger.h>
@ -63,7 +63,7 @@ signals:
void error(); void error();
private: private:
std::shared_ptr<DatabaseManager> db; std::shared_ptr<DatabaseAPI> db;
quint64 lastSync; // time of last run quint64 lastSync; // time of last run
quint64 nextLastSync; // time of begin of this run quint64 nextLastSync; // time of begin of this run

View File

@ -1,9 +1,9 @@
#include "logger.h" #include "logger.h"
#include "databasemanager.h" #include "databaseapi.h"
#include <utility> #include <utility>
std::shared_ptr<DatabaseManager> Logger::dbMan = nullptr; std::shared_ptr<DatabaseAPI> Logger::dbMan = nullptr;
Logger *Logger::logger = nullptr; Logger *Logger::logger = nullptr;
Logger::Logger() Logger::Logger()
@ -29,7 +29,7 @@ void Logger::logToDb(const QString &msg)
Logger::dbMan->log(msg); Logger::dbMan->log(msg);
} }
void Logger::setDBMan(std::shared_ptr<DatabaseManager> dbMan) void Logger::setDBMan(std::shared_ptr<DatabaseAPI> dbMan)
{ {
Logger::dbMan = std::move(dbMan); Logger::dbMan = std::move(dbMan);
} }

View File

@ -5,7 +5,7 @@
#include <QSqlDatabase> #include <QSqlDatabase>
#include <memory> #include <memory>
class DatabaseManager; class DatabaseAPI;
class Logger class Logger
@ -15,13 +15,13 @@ class Logger
Logger(); Logger();
static std::shared_ptr<DatabaseManager> dbMan; static std::shared_ptr<DatabaseAPI> dbMan;
public: public:
static Logger *getLogger(); static Logger *getLogger();
static void log(const QString& msg); static void log(const QString& msg);
static void logToDb(const QString& msg); static void logToDb(const QString& msg);
static void setDBMan(std::shared_ptr<DatabaseManager> dbMan); static void setDBMan(std::shared_ptr<DatabaseAPI> dbMan);
static QString makeTokenMsg(const QString& tokenId, const QString& action, const QString& source); static QString makeTokenMsg(const QString& tokenId, const QString& action, const QString& source);
static QString makeSubjectMsg(const QString& subjectId, const QString& action, const QString& source); static QString makeSubjectMsg(const QString& subjectId, const QString& action, const QString& source);
static QString makeErrorMsg(const QString& source, const QString& errMsg); static QString makeErrorMsg(const QString& source, const QString& errMsg);

View File

@ -1,4 +1,132 @@
#include "syncmanager.h" #include "syncmanager.h"
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());
// -1 --> some error with getting data from DB
if (mlastSync.timestamp() >= 0){
return true;
}
}
return false;
}
void SyncManager::run()
{
qint64 syncBegin = database.getNow();
downloadData();
connect(this, &SyncManager::dataReady, [=](){
prepareData();
processData();
connect(this, &SyncManager::processDataFinished, [=](){
updateLastUpdate(); // get last_update from colnod after seting tokens TODO:
database.setLastSync(syncBegin);
QCoreApplication::exit();
});
});
}
void SyncManager::downloadData()
{
colnod.downloadData();
connect(&colnod, &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
connect(&colnod, &ColnodAPI::downloadDataFinished, this, &SyncManager::areDataReady);
database.downloadData();
connect(&database, &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
connect(&database, &DatabaseAPI::downloadDataFinished, this, &SyncManager::areDataReady);
}
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
void SyncManager::prepareData()
{
colnodDataToProcess = std::make_shared<Data>(colnodData);
databaseDataToProcess = std::make_shared<Data>(databaseData);
QList<QUuid> idsToDelete;
for (const auto &colnodToken : colnodDataToProcess->updatedTokens) {
if (databaseDataToProcess->updatedTokens.contains(colnodToken.getId())) {
if (databaseDataToProcess->updatedTokens.value(colnodToken.getId()) > colnodToken)
idsToDelete.append(colnodToken.getId());
}
}
for (const auto &id : idsToDelete)
colnodDataToProcess->updatedTokens.remove(id);
idsToDelete.clear();
for (const auto &databaseToken : databaseDataToProcess->updatedTokens) {
if (colnodDataToProcess->updatedTokens.contains(databaseToken.getId())) {
if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken.getId()))
idsToDelete.append(databaseToken.getId());
}
}
for (const auto &id : idsToDelete)
colnodDataToProcess->updatedTokens.remove(id);
}
void SyncManager::processData()
{
// TODO:
}
void SyncManager::areDataReady()
{
if (++dataAmount)
emit dataReady();
}
void SyncManager::saveColnodData(std::shared_ptr<Data> data)
{
colnodData = data;
}
void SyncManager::saveDatabaseData(std::shared_ptr<Data> data)
{
databaseData = data;
}
SyncManager::SyncManager(bool dryMode) : SyncManager::SyncManager(bool dryMode) :
reqMan(std::make_unique<RequestManager>()), reqMan(std::make_unique<RequestManager>()),
@ -199,7 +327,7 @@ bool SyncManager::isValid()
void SyncManager::areChangedDataReady() void SyncManager::areChangedDataReady()
{ {
if (++dataCounter == 5) if (++dataCounter == 5)
emit dataDownloaded(); emit dataReady();
} }
// emit signal when writing to Colnod is finised // emit signal when writing to Colnod is finised

View File

@ -1,13 +1,66 @@
#pragma once #pragma once
#include "colnodapi.h"
#include "databaseapi.h"
#include "requestmanager.h" #include "requestmanager.h"
#include "datamanager.h" #include "datamanager.h"
#include "logger.h" #include "logger.h"
#include "colnodapi.h"
#include "serversdk/databasemanager.h"
class SyncManager : public QObject class SyncManager : public QObject
{ {
Q_OBJECT Q_OBJECT
// NEW
public:
bool init();
void run();
private:
void downloadData();
void prepareData();
void processData();
private:
Q_SLOTS void saveColnodData(std::shared_ptr<Data> data);
Q_SLOTS void saveDatabaseData(std::shared_ptr<Data> data);
Q_SLOTS void areDataReady();
signals:
void dataReady();
void processDataFinished();
private:
ColnodAPI colnod;
DatabaseAPI database;
serversdk::RequestManager reqMan;
serversdk::DatabaseManager dbMan;
Timestamp mlastSync;
std::shared_ptr<Data> colnodData;
std::shared_ptr<Data> databaseData;
std::shared_ptr<Data> colnodDataToProcess;
std::shared_ptr<Data> databaseDataToProcess;
int dataAmount = 0;
// OLD
public: public:
explicit SyncManager(bool dryMode = false); explicit SyncManager(bool dryMode = false);
@ -24,7 +77,7 @@ public slots:
void loadDataFromDB(); void loadDataFromDB();
signals: signals:
void dataDownloaded(); void dataReady();
void dataUpdatedToColnod(); void dataUpdatedToColnod();
void syncFinished(); void syncFinished();
void error(); void error();
@ -49,7 +102,7 @@ private:
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;

View File

@ -1,6 +1,7 @@
#include "token.h" #include "token.h"
#include <QJsonArray> #include <QJsonArray>
#include <qjsondocument.h>
#include <utility> #include <utility>
@ -52,6 +53,20 @@ QJsonObject Token::toJSON() const {
return json; return json;
} }
QByteArray Token::tokensToJSON(const QHash<QUuid, Token> &tokens)
{
QJsonObject items;
QJsonArray jsonTokens;
for (const auto& token : tokens)
{
jsonTokens.push_back(token.toJSON());
}
items.insert("items", jsonTokens);
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

@ -69,6 +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);
private: private:
QString tokenType = "Token"; QString tokenType = "Token";
int tokenBits = 32; int tokenBits = 32;

View File

@ -5,7 +5,7 @@
#include <QSignalSpy> #include <QSignalSpy>
#include <requestmanager.h> #include <requestmanager.h>
#include "subject.h" #include "subject.h"
#include "databasemanager.h" #include "databaseapi.h"
#include <QSslSocket> #include <QSslSocket>
#include "datamanager.h" #include "datamanager.h"
#include "response.h" #include "response.h"