mirror of
https://gitlab.com/spaceti-app/integrations/acs/colnod-connector.git
synced 2026-07-12 13:10:45 +02:00
WIP: possible to build, not implemented yet: upload data to DB
This commit is contained in:
parent
9bf2eb05e8
commit
c96832f4b8
@ -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);
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -4,3 +4,11 @@ Data::Data()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Data::clear()
|
||||
{
|
||||
updatedTokens.clear();
|
||||
updatedSubjects.clear();
|
||||
deletedTokens.clear();
|
||||
deletedSubjects.clear();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
//}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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{};
|
||||
};
|
||||
|
||||
@ -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);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user