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::setApplicationVersion("1.0");
QCommandLineParser parser;
Logger *logger = Logger::getLogger();
parser.setApplicationDescription("Colnod sync");
QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made");
QCommandLineOption dropTablesOption("dropTables", "ColnodAPI", "Delete tables with datas from Colnod");
@ -25,54 +24,11 @@ int main(int argc, char *argv[])
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, [](){
// qDebug() << "error";
// 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)
{
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);
deleteTokens(data->deletedTokens);
}
std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
@ -62,7 +63,7 @@ void ColnodAPI::getTokensUpdated(const Timestamp &time)
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
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));
request->setToken(authToken);
mReqMan->processRequest(request);
@ -110,13 +110,24 @@ void ColnodAPI::setTokens(const QHash<QUuid, Token> &tokens)
emit partOfDataProcessFinished();
}
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) {
emit downloadDataFinished(data);
newData();
}
}
void ColnodAPI::isDataProcessFinished()
{
if (++amountProccessesFinished == 2)
emit dataProcessFinished();
}
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);
auto token = std::make_shared<Token>();
token->fromJSON(item.toObject());
token->setDeleted(false);
data->updatedTokens.insert(token->getId(), token);
}
}
@ -190,10 +208,10 @@ 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);
auto subject = std::make_shared<Subject>();
subject->fromJSON(item.toObject());
subject->setDeleted(false);
data->updatedSubjects.insert(subject->getId(), subject);
}
}
@ -205,3 +223,14 @@ void ColnodAPI::saveDeletedSubjects(const QByteArray &responseData)
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
public:
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 uploadData(std::shared_ptr<Data> data);
void processData(std::shared_ptr<Data> data);
// New approach
std::shared_ptr<serversdk::Request> requestLogin();
@ -50,7 +50,7 @@ public:
void getSubjectsUpdated(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);
// Attributes
@ -64,6 +64,7 @@ public:
private:
Q_SLOT void areDataReady();
Q_SLOT void isDataProcessFinished();
private:
void saveUpdatedTokens(const QByteArray &responseData);
@ -71,6 +72,8 @@ private:
void saveDeletedTokens(const QByteArray &responseData);
void saveDeletedSubjects(const QByteArray &responseData);
void newData();
bool checkResponse(const QByteArray &responseData);
QByteArray getTimestampJson(const qint64 &time);
@ -78,8 +81,9 @@ private:
signals:
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 dataProcessFinished();
private:
serversdk::RequestManager* mReqMan = nullptr;
@ -92,5 +96,6 @@ private:
QString authToken;
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:
Data();
QHash<QUuid, Token> updatedTokens;
void clear();
QHash<QUuid, std::shared_ptr<Token>> updatedTokens;
QList<QString> deletedTokens;
QHash<QUuid, Subject> updatedSubjects;
QHash<QUuid, std::shared_ptr<Subject>> updatedSubjects;
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()
{
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));
}
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>();
while (updatedQuery.next()) {
Token token;
token.fromSQLRecord(updatedQuery);
data->updatedTokens.append(token);
auto token = std::make_shared<Token>();
token->fromSQLRecord(updatedQuery);
data->updatedTokens.insert(token->getId(), token);
}
while (deletedQuery.next()) {
data->deletedTokens.append(deletedQuery.value(0).toString());
@ -50,7 +67,18 @@ void DatabaseAPI::setLastSync(qint64 timestamp)
QSqlQuery query;
query.prepare("UPDATE config SET last_sync = :last_sync");
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()
@ -60,14 +88,65 @@ qint64 DatabaseAPI::getNow()
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
DatabaseAPI::DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode)
:dryMode(dryMode)
{
db = QSqlDatabase::addDatabase("QPSQL");
db.setDatabaseName(dbName);
db.setHostName(host);
db.setUserName(user); // home-office stuff -->> db.setPort(80);
db.setPassword(password);
if (!db.open())
{
opened = false;
Logger::log("Opening error" + db.lastError().text());
emit error();
}
else{
opened = true;
}
}
//DatabaseAPI::DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode)
// :dryMode(dryMode)
//{
// db = QSqlDatabase::addDatabase("QPSQL");
// db.setDatabaseName(dbName);
// db.setHostName(host);
// db.setUserName(user); // home-office stuff -->> db.setPort(80);
// db.setPassword(password);
// if (!db.open())
// {
// opened = false;
// Logger::log("Opening error" + db.lastError().text());
// emit error();
// }
// else{
// opened = true;
// }
//}
// add or update subject to db
int DatabaseAPI::saveSubject(const std::shared_ptr<Subject>& subject, const QString& table)
{
QSqlQuery query;
QString id = subject->idToStringWithoutBraces();
int rtn;
if (checkIfExists(id, table)){
query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = :last_update, name = :name, pin = :pin, last_modified = :last_modified, deleted = :deleted "
"WHERE id = :id").arg(table));
rtn = -1;
}else{
query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) "
"VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table));
rtn = 1;
}
query.bindValue(":id", id);
query.bindValue(":description", subject->getDescription());
query.bindValue(":name", subject->getName());
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":pin", subject->getPin());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", subject->getDeleted());
executeQuery(query);
return rtn;
}
//// add or update subject to db
//int DatabaseAPI::saveSubject(const std::shared_ptr<Subject>& subject, const QString& table)
//{
// QSqlQuery query;
// QString id = subject->idToStringWithoutBraces();
// int rtn;
// if (checkIfExists(id, table)){
// query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = :last_update, name = :name, pin = :pin, last_modified = :last_modified, deleted = :deleted "
// "WHERE id = :id").arg(table));
// rtn = -1;
// }else{
// query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) "
// "VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table));
// rtn = 1;
// }
// query.bindValue(":id", id);
// query.bindValue(":description", subject->getDescription());
// query.bindValue(":name", subject->getName());
// query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
// query.bindValue(":pin", subject->getPin());
// query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
// query.bindValue(":deleted", subject->getDeleted());
// executeQuery(query);
// return rtn;
//}
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;
}
//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
int DatabaseAPI::saveToken(const std::shared_ptr<Token>& token, const QString& table)
{
QSqlQuery query;
QString id = token->idToStringWithoutBraces();
int rtn;
if (checkIfExists(id, table)){
query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, last_update = :last_update, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified, deleted = :deleted "
"WHERE id = :id").arg(table));
rtn = -1;
}else{
query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) "
"VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table));
rtn = 1;
}
query.bindValue(":id", id);
query.bindValue(":auth_errors", token->getAuthErrors());
query.bindValue(":description", token->getDescription());
query.bindValue(":enabled", token->getFlags().contains("Enabled"));
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":name", token->getName());
query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
query.bindValue(":time_to_live", token->getTimeToLive());
query.bindValue(":token_bits", token->getTokenBits());
query.bindValue(":token_data", token->getTokenData());
query.bindValue(":token_type", token->getTokenType());
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":deleted", token->getDeleted());
executeQuery(query);
return rtn;
}
//// add or update token to DB
//int DatabaseAPI::saveToken(const std::shared_ptr<Token>& token, const QString& table)
//{
// QSqlQuery query;
// QString id = token->idToStringWithoutBraces();
// int rtn;
// if (checkIfExists(id, table)){
// query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, last_update = :last_update, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified, deleted = :deleted "
// "WHERE id = :id").arg(table));
// rtn = -1;
// }else{
// query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) "
// "VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table));
// rtn = 1;
// }
// query.bindValue(":id", id);
// query.bindValue(":auth_errors", token->getAuthErrors());
// query.bindValue(":description", token->getDescription());
// query.bindValue(":enabled", token->getFlags().contains("Enabled"));
// query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
// query.bindValue(":name", token->getName());
// query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
// query.bindValue(":time_to_live", token->getTimeToLive());
// query.bindValue(":token_bits", token->getTokenBits());
// query.bindValue(":token_data", token->getTokenData());
// query.bindValue(":token_type", token->getTokenType());
// query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
// query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
// query.bindValue(":deleted", token->getDeleted());
// executeQuery(query);
// return rtn;
//}
// add of update subject attributes
void DatabaseAPI::saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table)
{
QSqlQuery query;
auto attributes = subject->getAtr();
for (const auto& attribute : attributes){
QString id = subject->idToStringWithoutBraces() + " " + attribute.first;
if (checkIfExists(id, table)){
query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) "
"WHERE id = :id").arg(table));
}else{
query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)"
"VALUES (:id, :key, :value, :subject_id)").arg(table));
}
query.bindValue(":id", id);
query.bindValue(":key", attribute.first);
query.bindValue(":value", attribute.second);
query.bindValue(":subject_id", subject->idToStringWithoutBraces());
executeQuery(query);
}
}
//// add of update subject attributes
//void DatabaseAPI::saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table)
//{
// QSqlQuery query;
// auto attributes = subject->getAtr();
// for (const auto& attribute : attributes){
// QString id = subject->idToStringWithoutBraces() + " " + attribute.first;
// if (checkIfExists(id, table)){
// query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) "
// "WHERE id = :id").arg(table));
// }else{
// query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)"
// "VALUES (:id, :key, :value, :subject_id)").arg(table));
// }
// query.bindValue(":id", id);
// query.bindValue(":key", attribute.first);
// query.bindValue(":value", attribute.second);
// query.bindValue(":subject_id", subject->idToStringWithoutBraces());
// executeQuery(query);
// }
//}
// "delete" tokens from DB -> set deleted true
void DatabaseAPI::setDeleted(const QString& id, const QString& table, quint64 time)
{
QSqlQuery query;
QString nowString = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd hh:mm:ss.zzz");
query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table));
query.bindValue(":id", id);
query.bindValue(":now", nowString);
executeQuery(query);
}
//// "delete" tokens from DB -> set deleted true
//void DatabaseAPI::setDeleted(const QString& id, const QString& table, quint64 time)
//{
// QSqlQuery query;
// QString nowString = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd hh:mm:ss.zzz");
// query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table));
// query.bindValue(":id", id);
// query.bindValue(":now", nowString);
// executeQuery(query);
//}
bool DatabaseAPI::checkIfExists(const QString& id, const QString& table)
{
QSqlQuery query;
query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
query.bindValue(":id", id);
executeQuery(query);
query.first();
return query.value(0).toBool();
}
//bool DatabaseAPI::checkIfExists(const QString& id, const QString& table)
//{
// QSqlQuery query;
// query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
// query.bindValue(":id", id);
// executeQuery(query);
// query.first();
// return query.value(0).toBool();
//}
QString DatabaseAPI::getLastQuery(const QSqlQuery& query) const
{
QString str = query.lastQuery();
QMapIterator<QString, QVariant> it(query.boundValues());
while (it.hasNext())
{
it.next();
str.replace(it.key(),it.value().toString());
}
return str;
}
//QString DatabaseAPI::getLastQuery(const QSqlQuery& query) const
//{
// QString str = query.lastQuery();
// QMapIterator<QString, QVariant> it(query.boundValues());
// while (it.hasNext())
// {
// it.next();
// str.replace(it.key(),it.value().toString());
// }
// return str;
//}
bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
{
if (statement.isEmpty()){
if (dryMode){
QString sqlStatement = getLastQuery(query);
qDebug() << sqlStatement;
}
if (!dryMode || getLastQuery(query).startsWith("SELECT")){
if (!query.exec()){
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
Logger::logToDb(QString(msg));
emit error();
}
}
return true;
}
if (dryMode){
qDebug() << statement;
}
if (!dryMode || statement.startsWith("SELECT")){
if (!query.exec(statement)){
QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
Logger::logToDb(QString(msg));
emit error();
}
}
return true;
}
//bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
//{
// if (statement.isEmpty()){
// if (dryMode){
// QString sqlStatement = getLastQuery(query);
// qDebug() << sqlStatement;
// }
// if (!dryMode || getLastQuery(query).startsWith("SELECT")){
// if (!query.exec()){
// QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
// Logger::logToDb(QString(msg));
// emit error();
// }
// }
// return true;
// }
// if (dryMode){
// qDebug() << statement;
// }
// if (!dryMode || statement.startsWith("SELECT")){
// if (!query.exec(statement)){
// QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
// Logger::logToDb(QString(msg));
// emit error();
// }
// }
// return true;
//}
void DatabaseAPI::dropTables()
{
QSqlQuery query;
//void DatabaseAPI::dropTables()
//{
// 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
void DatabaseAPI::createTables()
{
QSqlQuery query;
//// create table after deleting, it is used for full sync
//void DatabaseAPI::createTables()
//{
// QSqlQuery query;
executeQuery(query, "CREATE TABLE colnod_subject ("
"id character(36) primary key NOT NULL,"
"description character varying(255),"
"last_update timestamp NOT NULL,"
"name character varying(255),"
"pin character varying(255),"
"last_modified timestamp,"
"deleted BOOLEAN)");
executeQuery(query, "CREATE TABLE colnod_token ("
"id CHAR(36) primary key NOT NULL,"
"auth_errors INTEGER DEFAULT 255,"
"description VARCHAR(255),"
"enabled BOOLEAN DEFAULT true,"
"last_update timestamp DEFAULT '1970-01-01 00:00:00'::timestamp without time zone,"
"name VARCHAR(255),"
"no_validity BOOLEAN DEFAULT true,"
"time_to_live INTEGER DEFAULT 255,"
"token_bits INTEGER DEFAULT 32,"
"token_data VARCHAR(255),"
"token_type VARCHAR(255) DEFAULT 'Token'::character varying,"
"subject_id CHAR(36),"
"last_modified timestamp NOT NULL,"
"deleted BOOLEAN DEFAULT false)");
executeQuery(query, "CREATE TABLE colnod_subject_attribute ("
"id VARCHAR(255) primary key,"
"attribute_key VARCHAR(255),"
"attribute_value VARCHAR(255),"
"subject_id CHAR(36))");
}
// executeQuery(query, "CREATE TABLE colnod_subject ("
// "id character(36) primary key NOT NULL,"
// "description character varying(255),"
// "last_update timestamp NOT NULL,"
// "name character varying(255),"
// "pin character varying(255),"
// "last_modified timestamp,"
// "deleted BOOLEAN)");
// executeQuery(query, "CREATE TABLE colnod_token ("
// "id CHAR(36) primary key NOT NULL,"
// "auth_errors INTEGER DEFAULT 255,"
// "description VARCHAR(255),"
// "enabled BOOLEAN DEFAULT true,"
// "last_update timestamp DEFAULT '1970-01-01 00:00:00'::timestamp without time zone,"
// "name VARCHAR(255),"
// "no_validity BOOLEAN DEFAULT true,"
// "time_to_live INTEGER DEFAULT 255,"
// "token_bits INTEGER DEFAULT 32,"
// "token_data VARCHAR(255),"
// "token_type VARCHAR(255) DEFAULT 'Token'::character varying,"
// "subject_id CHAR(36),"
// "last_modified timestamp NOT NULL,"
// "deleted BOOLEAN DEFAULT false)");
// executeQuery(query, "CREATE TABLE colnod_subject_attribute ("
// "id VARCHAR(255) primary key,"
// "attribute_key VARCHAR(255),"
// "attribute_value VARCHAR(255),"
// "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 query;
query.prepare("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
"FROM colnod_token WHERE id = :id");
query.bindValue(":id", id);
executeQuery(query);
query.next();
return query;
}
//QSqlQuery DatabaseAPI::getToken(const QString& id)
//{
// QSqlQuery query;
// query.prepare("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
// "FROM colnod_token WHERE id = :id");
// query.bindValue(":id", id);
// executeQuery(query);
// query.next();
// return query;
//}
// 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);
}
//// sync last update back to DB from Colnod after changes made to Colnod
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)
{
QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)");
query.bindValue(":tokenId", tokenId);
executeQuery(query);
if (query.next())
return query.value(0).toString();
qWarning() << "Token:" << tokenId << "is not assigned to any subject";
return "(No subject)";
}
//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::getSubjectNameById(const QString &id)
{
QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = :id");
query.bindValue(":id", id);
executeQuery(query);
if (query.next())
return query.value(0).toString();
qWarning() << "Subject:" << id << "doesn't exists";
return "(No subject)";
}
//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);
// executeQuery(query);
// if (query.next())
// return query.value(0).toString();
// qWarning() << "Token:" << tokenId << "is not assigned to any subject";
// return "(No subject)";
//}
bool DatabaseAPI::checkDeletedToken(const QString &id)
{
QSqlQuery query;
query.prepare("SELECT deleted FROM colnod_token WHERE id = :id");
query.bindValue(":id", id);
executeQuery(query);
query.next();
return query.value(0).toBool();
}
//QString DatabaseAPI::getSubjectNameById(const QString &id)
//{
// QSqlQuery query;
// query.prepare("SELECT name FROM colnod_subject WHERE id = :id");
// query.bindValue(":id", id);
// executeQuery(query);
// if (query.next())
// return query.value(0).toString();
// qWarning() << "Subject:" << id << "doesn't exists";
// return "(No subject)";
//}
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);
executeQuery(query);
return static_cast<qint16>(query.size());
}
//bool DatabaseAPI::checkDeletedToken(const QString &id)
//{
// QSqlQuery query;
// query.prepare("SELECT deleted FROM colnod_token WHERE id = :id");
// query.bindValue(":id", id);
// executeQuery(query);
// 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:
DatabaseAPI(serversdk::DatabaseManager *dbMan);
bool open();
void downloadData();
void processData(std::shared_ptr<Data> data);
qint64 getLastSync();
void setLastSync(qint64 timestamp);
void setLastUpdate(QHash<QUuid, std::shared_ptr<Token> > tokens);
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:
QSqlQuery getUpdatedTokens();
std::shared_ptr<Data> composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery);
qint16 getNumOfTokensOfSubject(const QString &id);
QString getSubjectNameByTokenId(const QString &tokenId);
signals:
void downloadDataFinished(std::shared_ptr<Data> = std::shared_ptr<Data>());
@ -50,42 +64,41 @@ private:
// 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 saveToken(const std::shared_ptr<Token>& token, const QString& table);
void saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table);
void setDeleted(const QString& id, const QString& table, quint64 time);
// int saveSubject(const std::shared_ptr<Subject>& subject, 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 setDeleted(const QString& id, const QString& table, quint64 time);
void dropTables();
void createTables();
// void dropTables();
// 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);
QString getSubjectNameByTokenId(const QString &tokenId);
QString getSubjectNameById(const QString &id);
bool checkDeletedToken(const QString &id);
qint16 getNumOfTokensOfSubject(const QString &id);
bool isOpen();
// void log(const QString &msg);
// QString getSubjectNameById(const QString &id);
// bool checkDeletedToken(const QString &id);
private:
bool checkIfExists(const QString& id, const QString& table);
bool executeQuery(QSqlQuery &query, const QString &statement = QString());
QString getLastQuery(const QSqlQuery &query) const;
signals:
void error();
// bool isOpen();
private:
QSqlDatabase db;
bool dryMode = false;
bool opened = false;
//private:
// bool checkIfExists(const QString& id, const QString& table);
// 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"
DataManager::DataManager(const bool &dryMode) :
db(std::make_shared<DatabaseAPI>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode)),
dryMode(dryMode)
{
if (db->isOpen()){
Logger::setDBMan(db);
nextLastSync = db->getNow();
lastSync = db->getLastSync();
}
connect(db.get(), &DatabaseAPI::error, this, &DataManager::error, Qt::QueuedConnection);
}
//DataManager::DataManager(const bool &dryMode) :
// db(std::make_shared<DatabaseAPI>("192.168.1.94", "deloitte", "postgres", "34rjkciea12", dryMode)),
// dryMode(dryMode)
//{
// if (db->isOpen()){
// Logger::setDBMan(db);
// nextLastSync = db->getNow();
// lastSync = db->getLastSync();
// }
// connect(db.get(), &DatabaseAPI::error, this, &DataManager::error, Qt::QueuedConnection);
//}
// load all tokens from colnod to comparing with working set from DB
void DataManager::fillFullTokensColnod(const QString& response)
{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray();
if (!items.empty())
{
for (QJsonValueRef item : items){
auto token = std::make_shared<Token>();
token->fromJSON(item.toObject());
allTokensFromColnodById.insert(token->idToStringWithoutBraces(), token);
allTokensFromColnodByName.insert(token->getName(), token);
}
}
else{
qCritical() << "Colnod is Empty";
}
}
//// load all tokens from colnod to comparing with working set from DB
//void DataManager::fillFullTokensColnod(const QString& response)
//{
// QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
// QJsonArray items = doc.object()["items"].toArray();
// if (!items.empty())
// {
// for (QJsonValueRef item : items){
// auto token = std::make_shared<Token>();
// token->fromJSON(item.toObject());
// allTokensFromColnodById.insert(token->idToStringWithoutBraces(), token);
// allTokensFromColnodByName.insert(token->getName(), token);
// }
// }
// else{
// qCritical() << "Colnod is Empty";
// }
//}
// load working set with updated tokens from Colnod
void DataManager::fillTokensToUpdateColnod(const QString& response)
{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray();
if (!items.empty())
{
for (QJsonValueRef item : items)
{
auto token = std::make_shared<Token>();
token->fromJSON(item.toObject());
token->setDeleted(false);
tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token);
}
qInfo() << "Colnod:" << tokensToUpdateFromColnodToDB.size() << "tokens to update";
}
else
{
qInfo() << "Colnod: 0 tokens to update";
}
}
//// load working set with updated tokens from Colnod
//void DataManager::fillTokensToUpdateColnod(const QString& response)
//{
// QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
// QJsonArray items = doc.object()["items"].toArray();
// if (!items.empty())
// {
// for (QJsonValueRef item : items)
// {
// auto token = std::make_shared<Token>();
// token->fromJSON(item.toObject());
// token->setDeleted(false);
// tokensToUpdateFromColnodToDB.insert(token->idToStringWithoutBraces(), token);
// }
// qInfo() << "Colnod:" << tokensToUpdateFromColnodToDB.size() << "tokens to update";
// }
// else
// {
// qInfo() << "Colnod: 0 tokens to update";
// }
//}
// load working set with updated subjects from Colnod
void DataManager::fillSubjectsToUpdateColnod(const QString& response)
{
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
QJsonArray items = doc.object()["items"].toArray();
if (!items.empty())
{
for (QJsonValueRef item : items)
{
auto subject = std::make_shared<Subject>();
subject->fromJSON(item.toObject());
subject->setDeleted(false);
subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject);
}
qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update";
}
else
{
qInfo() << "Colnod:" << "0 subjects to update";
}
}
//// load working set with updated subjects from Colnod
//void DataManager::fillSubjectsToUpdateColnod(const QString& response)
//{
// QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
// QJsonArray items = doc.object()["items"].toArray();
// if (!items.empty())
// {
// for (QJsonValueRef item : items)
// {
// auto subject = std::make_shared<Subject>();
// subject->fromJSON(item.toObject());
// subject->setDeleted(false);
// subjectsToUpdateFromColnodToDB.insert(subject->idToStringWithoutBraces(), subject);
// }
// qInfo() << "Colnod:" << subjectsToUpdateFromColnodToDB.size() << "subjects to update";
// }
// else
// {
// qInfo() << "Colnod:" << "0 subjects to update";
// }
//}
// load working sets with updated/deleted tokens from DB
void DataManager::fillTokensToChangeDB()
{
if (db->isOpen()){
QSqlQuery query = db->getUpdatedTokens();
while (query.next())
{
auto token = std::make_shared<Token>();
token->fromSQLRecord(query);
if (token->getName() == NULL){
qint16 num = db->getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces());
token->setName(db->getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1));
token->setDescription("mobile");
token->setLastUpdate(token->getLastModified());
db->saveToken(token, "colnod_token");
}
if (token->getDeleted()){ // sort to delete / to update
tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces());
}
else{
tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token);
}
}
qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update";
qDebug() << "DB:" << tokensFromDBToDeleteFromColnod.size() << "tokens to delete";
}
else
emit error();
}
//// load working sets with updated/deleted tokens from DB
//void DataManager::fillTokensToChangeDB()
//{
// if (db->isOpen()){
// QSqlQuery query = db->getUpdatedTokens();
// while (query.next())
// {
// auto token = std::make_shared<Token>();
// token->fromSQLRecord(query);
// if (token->getName() == NULL){
// qint16 num = db->getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces());
// token->setName(db->getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1));
// token->setDescription("mobile");
// token->setLastUpdate(token->getLastModified());
// db->saveToken(token, "colnod_token");
// }
// if (token->getDeleted()){ // sort to delete / to update
// tokensFromDBToDeleteFromColnod.append(token->idToStringWithoutBraces());
// }
// else{
// tokensToUpdateFromDBToColnod.insert(token->idToStringWithoutBraces(), token);
// }
// }
// qDebug() << "DB:" << tokensToUpdateFromDBToColnod.size() << "tokens to update";
// qDebug() << "DB:" << tokensFromDBToDeleteFromColnod.size() << "tokens to delete";
// }
// else
// emit error();
//}
void DataManager::fillSubjectsToUpdateDB()
{
// Not needed yet
}
//void DataManager::fillSubjectsToUpdateDB()
//{
// // Not needed yet
//}
// load working set with subjest to delete from Colnod
void DataManager::fillSubjectsToDeleteColnod(const QString& json)
{
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
QJsonArray items = doc.object()["items"].toArray();
if (!items.empty())
{
for (QJsonValueRef item : items) {
subjectsFromColnodToDeleteFromDB.append(item.toString());
}
qInfo() << "Colnod:" << subjectsFromColnodToDeleteFromDB.size() << "subjects to delete";
}
else {
qInfo() << "Colnod: 0 subjects to delete";
}
}
//// load working set with subjest to delete from Colnod
//void DataManager::fillSubjectsToDeleteColnod(const QString& json)
//{
// QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
// QJsonArray items = doc.object()["items"].toArray();
// if (!items.empty())
// {
// for (QJsonValueRef item : items) {
// subjectsFromColnodToDeleteFromDB.append(item.toString());
// }
// qInfo() << "Colnod:" << subjectsFromColnodToDeleteFromDB.size() << "subjects to delete";
// }
// else {
// qInfo() << "Colnod: 0 subjects to delete";
// }
//}
// load working set with tokens to delete from DB
void DataManager::fillTokensToDeleteColnod(const QString& json)
{
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
QJsonArray items = doc.object()["items"].toArray();
if (!items.empty())
{
for (QJsonValueRef item : items) {
tokensFromColnodToDeleteFromDB.append(item.toString());
}
qInfo() << "Colnod:" << tokensFromColnodToDeleteFromDB.size() << "tokens to delete";
}
else {
qInfo() << "Colnod: 0 tokens to delete";
}
}
//// load working set with tokens to delete from DB
//void DataManager::fillTokensToDeleteColnod(const QString& json)
//{
// QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
// QJsonArray items = doc.object()["items"].toArray();
// if (!items.empty())
// {
// for (QJsonValueRef item : items) {
// tokensFromColnodToDeleteFromDB.append(item.toString());
// }
// qInfo() << "Colnod:" << tokensFromColnodToDeleteFromDB.size() << "tokens to delete";
// }
// else {
// qInfo() << "Colnod: 0 tokens to delete";
// }
//}
void DataManager::fillSubjectsToDeleteDB()
{
// Not needed yet
}
//void DataManager::fillSubjectsToDeleteDB()
//{
// // Not needed yet
//}
// update subjects from colnod to DB
void DataManager::pushSubjectsToDB()
{
if (subjectsToUpdateFromColnodToDB.isEmpty()) {
qInfo() << "DB: 0 subjects added";
qInfo() << "DB: 0 subjects updated";
return;
}
int updated = 0;
int added = 0;
for (const auto& subject : subjectsToUpdateFromColnodToDB)
{
if (db->saveSubject(subject, "colnod_subject") > 0){
added++;
if (dryMode)
qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB";
else
Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB"));
}
else{
updated++;
if (dryMode)
qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB";
else
Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB"));
}
db->saveSubjectAttributes(subject, "colnod_subject_attribute");
}
qInfo() << "DB:" << added << "subjects added";
qInfo() << "DB:" << updated << "subjects updated";
}
//// update subjects from colnod to DB
//void DataManager::pushSubjectsToDB()
//{
// if (subjectsToUpdateFromColnodToDB.isEmpty()) {
// qInfo() << "DB: 0 subjects added";
// qInfo() << "DB: 0 subjects updated";
// return;
// }
// int updated = 0;
// int added = 0;
// for (const auto& subject : subjectsToUpdateFromColnodToDB)
// {
// if (db->saveSubject(subject, "colnod_subject") > 0){
// added++;
// if (dryMode)
// qInfo() << "Adding subject:" << subject->idToStringWithoutBraces() << "to DB";
// else
// Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"added", "DB"));
// }
// else{
// updated++;
// if (dryMode)
// qInfo() << "Updating subject:" << subject->idToStringWithoutBraces() << "to DB";
// else
// Logger::logToDb(Logger::makeSubjectMsg( subject->idToStringWithoutBraces(),"updated", "DB"));
// }
// db->saveSubjectAttributes(subject, "colnod_subject_attribute");
// }
// qInfo() << "DB:" << added << "subjects added";
// qInfo() << "DB:" << updated << "subjects updated";
//}
// update tokens from colnod to DB
void DataManager::pushTokensToDB()
{
if (tokensToUpdateFromColnodToDB.isEmpty()){
qInfo() << "DB: 0 tokens added";
qInfo() << "DB: 0 tokens updated";
return;
}
filterTokensColnod();
int updated = 0;
int added = 0;
for (const auto& token : tokensToUpdateFromColnodToDB)
{
//// update tokens from colnod to DB
//void DataManager::pushTokensToDB()
//{
// if (tokensToUpdateFromColnodToDB.isEmpty()){
// qInfo() << "DB: 0 tokens added";
// qInfo() << "DB: 0 tokens updated";
// return;
// }
// filterTokensColnod();
// int updated = 0;
// int added = 0;
// for (const auto& token : tokensToUpdateFromColnodToDB)
// {
QString text;
// 1 = adding token
// -1 = updating token
if (db->saveToken(token, "colnod_token") == 1){
added++;
text = "Added";
}
else {
updated++;
text = "Updating";
}
if (dryMode)
qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB";
else
Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB"));
}
qInfo() << "DB:" << added << "tokens added/edited";
qInfo() << "DB:" << updated << "tokens updated";
// QString text;
// // 1 = adding token
// // -1 = updating token
// if (db->saveToken(token, "colnod_token") == 1){
// added++;
// text = "Added";
// }
// else {
// updated++;
// text = "Updating";
// }
// if (dryMode)
// qInfo() << text << "token:" << token->idToStringWithoutBraces() << "to DB";
// else
// Logger::logToDb(Logger::makeTokenMsg(token->idToStringWithoutBraces(), text, "DB"));
// }
// qInfo() << "DB:" << added << "tokens added/edited";
// qInfo() << "DB:" << updated << "tokens updated";
}
//}
void DataManager::deleteSubjectsFromDB()
{
if (subjectsFromColnodToDeleteFromDB.isEmpty())
{
qInfo() << "DB: 0 subjects deleted";
return;
}
for (const auto& subjectId : subjectsFromColnodToDeleteFromDB)
{
db->setDeleted(subjectId, "colnod_subject", nextLastSync);
if (dryMode)
qInfo() << "Deleting subject:" << subjectId << "from DB";
else
Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB"));
}
qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted";
}
//void DataManager::deleteSubjectsFromDB()
//{
// if (subjectsFromColnodToDeleteFromDB.isEmpty())
// {
// qInfo() << "DB: 0 subjects deleted";
// return;
// }
// for (const auto& subjectId : subjectsFromColnodToDeleteFromDB)
// {
// db->setDeleted(subjectId, "colnod_subject", nextLastSync);
// if (dryMode)
// qInfo() << "Deleting subject:" << subjectId << "from DB";
// else
// Logger::logToDb(Logger::makeSubjectMsg(subjectId, "deleted", "DB"));
// }
// qInfo() << "DB:" << subjectsFromColnodToDeleteFromDB.size() << " subject deleted";
//}
// "delete" (set deleted true) tokens in DB depends on Colnod
void DataManager::setDeletedToTokensFromDB()
{
if (tokensFromColnodToDeleteFromDB.isEmpty())
{
qDebug() << "DB: 0 tokens deleted";
return;
}
int alreadyDeleted = 0;
for (const auto& tokenId : tokensFromColnodToDeleteFromDB)
{
if (!db->checkDeletedToken(tokenId)){
db->setDeleted(tokenId, "colnod_token", nextLastSync);
if (dryMode)
qInfo() << "Deleting token:" << tokenId << "from DB";
else
Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB"));
}
else
alreadyDeleted++;
}
qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted";
}
//// "delete" (set deleted true) tokens in DB depends on Colnod
//void DataManager::setDeletedToTokensFromDB()
//{
// if (tokensFromColnodToDeleteFromDB.isEmpty())
// {
// qDebug() << "DB: 0 tokens deleted";
// return;
// }
// int alreadyDeleted = 0;
// for (const auto& tokenId : tokensFromColnodToDeleteFromDB)
// {
// if (!db->checkDeletedToken(tokenId)){
// db->setDeleted(tokenId, "colnod_token", nextLastSync);
// if (dryMode)
// qInfo() << "Deleting token:" << tokenId << "from DB";
// else
// Logger::logToDb(Logger::makeTokenMsg(tokenId, "deleted", "DB"));
// }
// else
// alreadyDeleted++;
// }
// qDebug() << "DB:" << tokensFromColnodToDeleteFromDB.size() - alreadyDeleted << "tokens deleted";
//}
// recreate working tables
void DataManager::dropTables()
{
if (db->isOpen()){
db->dropTables();
}
else{
emit error();
}
}
//// recreate working tables
//void DataManager::dropTables()
//{
// if (db->isOpen()){
// db->dropTables();
// }
// else{
// emit error();
// }
//}
void DataManager::createTables()
{
if (db->isOpen()){
db->createTables();
db->updateLastSync(0);
}
else{
emit error();
}
}
//void DataManager::createTables()
//{
// if (db->isOpen()){
// db->createTables();
// db->updateLastSync(0);
// }
// else{
// emit error();
// }
//}
quint64 DataManager::getLastModifiedOfToken(const QString &id)
{
auto record = db->getToken(id);
auto token = std::make_shared<Token>();
token->fromSQLRecord(record);
return token->getLastModified();
}
//quint64 DataManager::getLastModifiedOfToken(const QString &id)
//{
// auto record = db->getToken(id);
// auto token = std::make_shared<Token>();
// token->fromSQLRecord(record);
// return token->getLastModified();
//}
//clear all structures
void DataManager::clear()
{
subjectsToUpdateFromColnodToDB.clear();
subjectsFromColnodToDeleteFromDB.clear();
tokensToUpdateFromColnodToDB.clear();
tokensFromColnodToDeleteFromDB.clear();
//subjectsDB.clear(); // not need yet
// subjectsToDeleteDB.clear(); // not need yet
tokensToUpdateFromDBToColnod.clear();
tokensFromDBToDeleteFromColnod.clear();
allTokensFromColnodById.clear();
}
////clear all structures
//void DataManager::clear()
//{
// subjectsToUpdateFromColnodToDB.clear();
// subjectsFromColnodToDeleteFromDB.clear();
// tokensToUpdateFromColnodToDB.clear();
// tokensFromColnodToDeleteFromDB.clear();
// //subjectsDB.clear(); // not need yet
// // subjectsToDeleteDB.clear(); // not need yet
// tokensToUpdateFromDBToColnod.clear();
// tokensFromDBToDeleteFromColnod.clear();
// allTokensFromColnodById.clear();
//}
// on the very end of sync update last sync time to begin time of this sync
void DataManager::updateLastSync()
{
if (db->isOpen())
db->updateLastSync(nextLastSync);
}
//// on the very end of sync update last sync time to begin time of this sync
//void DataManager::updateLastSync()
//{
// if (db->isOpen())
// 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)
void DataManager::filterTokensDB()
{
QList<QString> idsToDelete;
for (const auto& token : tokensToUpdateFromDBToColnod)
{
QString id = token->idToStringWithoutBraces();
Q_ASSERT(token != allTokensFromColnodById.value(id)); // if working sets are loading correctly equels should never happend
if (allTokensFromColnodById.contains(id) && *token < *allTokensFromColnodById.value(id))
idsToDelete.append(id);
if (allTokensFromColnodById.contains(id) && token->getLastModified() == allTokensFromColnodById.value(id)->getLastUpdate()){
idsToDelete.append(id);
qWarning() << "Same token has been edited in colnod and db in same time. Change from Colnod has been used";
}
if (allTokensFromColnodByName.contains(token->getName())){
qWarning() << "Token:" << token->idToStringWithoutBraces() << "won't be added to Colnod, because token with the same name already exists, please change it manually";
if (!dryMode){
QString message = QString("Error: Token: %1 won't be added to Colnod, because token with the same name already exists, please change it manually").arg(token->idToStringWithoutBraces());
Logger::logToDb(Logger::makeErrorMsg("Db", message));
}
}
}
for (const auto &id : idsToDelete)
tokensToUpdateFromDBToColnod.remove(id);
}
//// these to filter functions solve colision tokens -> remove when change on this token is earlier then change on the same token on the other side (Colnod/DB)
//void DataManager::filterTokensDB()
//{
// QList<QString> idsToDelete;
// for (const auto& token : tokensToUpdateFromDBToColnod)
// {
// QString id = token->idToStringWithoutBraces();
// Q_ASSERT(token != allTokensFromColnodById.value(id)); // if working sets are loading correctly equels should never happend
// if (allTokensFromColnodById.contains(id) && *token < *allTokensFromColnodById.value(id))
// idsToDelete.append(id);
// if (allTokensFromColnodById.contains(id) && token->getLastModified() == allTokensFromColnodById.value(id)->getLastUpdate()){
// idsToDelete.append(id);
// qWarning() << "Same token has been edited in colnod and db in same time. Change from Colnod has been used";
// }
// if (allTokensFromColnodByName.contains(token->getName())){
// qWarning() << "Token:" << token->idToStringWithoutBraces() << "won't be added to Colnod, because token with the same name already exists, please change it manually";
// if (!dryMode){
// QString message = QString("Error: Token: %1 won't be added to Colnod, because token with the same name already exists, please change it manually").arg(token->idToStringWithoutBraces());
// Logger::logToDb(Logger::makeErrorMsg("Db", message));
// }
// }
// }
// for (const auto &id : idsToDelete)
// tokensToUpdateFromDBToColnod.remove(id);
//}
void DataManager::filterTokensColnod()
{
QList<QString> idsToDelete;
for (const auto &token : tokensToUpdateFromColnodToDB)
{
QString id = token->idToStringWithoutBraces();
auto record = db->getToken(id);
if (!record.isValid())
continue;
auto tokenDB = std::make_shared<Token>();
tokenDB->fromSQLRecord(record);
if (*tokenDB == *token || *tokenDB > *token){
idsToDelete.append(id);
}
}
for (const auto &id : idsToDelete)
tokensToUpdateFromColnodToDB.remove(id);
}
//void DataManager::filterTokensColnod()
//{
// QList<QString> idsToDelete;
// for (const auto &token : tokensToUpdateFromColnodToDB)
// {
// QString id = token->idToStringWithoutBraces();
// auto record = db->getToken(id);
// if (!record.isValid())
// continue;
// auto tokenDB = std::make_shared<Token>();
// tokenDB->fromSQLRecord(record);
// if (*tokenDB == *token || *tokenDB > *token){
// idsToDelete.append(id);
// }
// }
// for (const auto &id : idsToDelete)
// tokensToUpdateFromColnodToDB.remove(id);
//}
// sync last update from colnod to DB
void DataManager::setLastUpdate()
{
if (!tokensToUpdateFromColnodToDB.isEmpty())
for (const auto &token : tokensToUpdateFromColnodToDB)
db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate());
}
//// sync last update from colnod to DB
//void DataManager::setLastUpdate()
//{
// if (!tokensToUpdateFromColnodToDB.isEmpty())
// for (const auto &token : tokensToUpdateFromColnodToDB)
// db->setLastUpdate(token->idToStringWithoutBraces(), token->getLastUpdate());
//}
void DataManager::setLastUpdate(const QString &id)
{
db->setLastUpdate(id, nextLastSync);
}
//void DataManager::setLastUpdate(const QString &id)
//{
// db->setLastUpdate(id, nextLastSync);
//}

View File

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

View File

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

View File

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

View File

@ -6,48 +6,48 @@
std::shared_ptr<DatabaseAPI> Logger::dbMan = nullptr;
Logger *Logger::logger = nullptr;
Logger::Logger()
{
dbMan = nullptr;
}
//Logger::Logger()
//{
// dbMan = nullptr;
//}
Logger *Logger::getLogger()
{
if (!logger)
logger = new Logger;
return logger;
}
//Logger *Logger::getLogger()
//{
// if (!logger)
// logger = new Logger;
// return logger;
//}
void Logger::log(const QString& msg)
{
qDebug() << msg;
}
//void Logger::log(const QString& msg)
//{
// qDebug() << msg;
//}
void Logger::logToDb(const QString &msg)
{
if (dbMan)
Logger::dbMan->log(msg);
}
//void Logger::logToDb(const QString &msg)
//{
// if (dbMan)
// // Logger::dbMan->log(msg);
//}
void Logger::setDBMan(std::shared_ptr<DatabaseAPI> dbMan)
{
Logger::dbMan = std::move(dbMan);
}
//void Logger::setDBMan(std::shared_ptr<DatabaseAPI> dbMan)
//{
// Logger::dbMan = std::move(dbMan);
//}
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);
}
//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);
//}
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);
}
//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);
//}
QString Logger::makeErrorMsg(const QString &source, const QString &errMsg)
{
return QString("Source: %1, Error: %2").arg(source, errMsg);
}
//QString Logger::makeErrorMsg(const QString &source, const QString &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, [=]() {
if (reply->error())
{
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
//Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
loginStatus = false;
reply->deleteLater();
emit error();
@ -53,7 +53,7 @@ QNetworkReply* RequestManager::postRequest(const QString& endpoint, const QByteA
QObject::connect(reply, &QNetworkReply::finished, [=]() {
if (reply->error())
{
Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
//Logger::logToDb(Logger::makeErrorMsg("Request Manager", reply->errorString()));
loginStatus = false;
reply->deleteLater();
emit error();

View File

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

View File

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

View File

@ -53,13 +53,13 @@ QJsonObject Token::toJSON() const {
return json;
}
QByteArray Token::tokensToJSON(const QHash<QUuid, Token> &tokens)
QByteArray Token::tokensToJSON(const QHash<QUuid, std::shared_ptr<Token>> &tokens)
{
QJsonObject items;
QJsonArray jsonTokens;
for (const auto& token : tokens)
{
jsonTokens.push_back(token.toJSON());
jsonTokens.push_back(token->toJSON());
}
items.insert("items", jsonTokens);
QJsonDocument doc;
@ -67,6 +67,20 @@ QByteArray Token::tokensToJSON(const QHash<QUuid, Token> &tokens)
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)
{
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");
explicit Token(const QString& name);
~Token() override;
@ -69,7 +69,8 @@ public:
void fromJSON(const QJsonObject &json) 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:
QString tokenType = "Token";