WIP: debuging functianality, fix issues

This commit is contained in:
Ondřej Fischer 2019-11-19 16:53:38 +01:00
parent fc52975b61
commit 900fda34e9
10 changed files with 127 additions and 71 deletions

View File

@ -8,6 +8,11 @@ ColnodAPI::ColnodAPI(serversdk::RequestManager* reqMan, qint64 lastSync, QString
:mReqMan(reqMan), mUserName(userName), mPassword(password)
{
mLastSync.set_timestamp(lastSync);
data = std::make_shared<Data>();
// -----------------------------------
mReqMan->setIgnoreSsl(true);
// -----------------------------------
}
void ColnodAPI::downloadData()
@ -31,8 +36,16 @@ void ColnodAPI::downloadData()
void ColnodAPI::processData(std::shared_ptr<Data> data)
{
setTokens(data->updatedTokens);
deleteTokens(data->deletedTokens);
if ( !data->updatedTokens.isEmpty()) {
setTokens(data->updatedTokens);
} else {
emit partOfDataProcessFinished();
}
if ( !data->deletedTokens.isEmpty()) {
deleteTokens(data->deletedTokens);
} else {
emit partOfDataProcessFinished();
}
}
std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
@ -59,7 +72,7 @@ std::shared_ptr<serversdk::Request> ColnodAPI::requestLogin()
void ColnodAPI::getTokensUpdated(const Timestamp &time)
{
auto request = composeRequest("/TokenManager/getTokensUpdated", time.jsonData());
request->setToken(authToken);
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveUpdatedTokens(request->responseData());
@ -70,7 +83,7 @@ void ColnodAPI::getTokensUpdated(const Timestamp &time)
void ColnodAPI::getTokensDeleted(const Timestamp &time)
{
auto request = composeRequest("/TokenManager/getTokensDeleted", time.jsonData());
request->setToken(authToken);
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveDeletedTokens(request->responseData());
@ -81,7 +94,7 @@ void ColnodAPI::getTokensDeleted(const Timestamp &time)
void ColnodAPI::getSubjectsUpdated(const Timestamp &time)
{
auto request = composeRequest("/SubjectManager/getSubjectsUpdated", time.jsonData());
request->setToken(authToken);
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveUpdatedSubjects(request->responseData());
@ -92,7 +105,7 @@ void ColnodAPI::getSubjectsUpdated(const Timestamp &time)
void ColnodAPI::getSubjectsDeleted(const Timestamp &time)
{
auto request = composeRequest("/SubjectManager/getSubjectsDeleted", time.jsonData());
request->setToken(authToken);
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
saveDeletedSubjects(request->responseData());
@ -102,8 +115,8 @@ void ColnodAPI::getSubjectsDeleted(const Timestamp &time)
void ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
{
auto request = composeRequest("/TokenManager/setTokens", Token::tokensToJSON(tokens));
request->setToken(authToken);
auto request = composeRequest("/TokenManager/setTokens", Token::tokensToColnodJson(tokens));
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
if (checkResponse(request->responseData())) {
@ -118,7 +131,7 @@ void ColnodAPI::setTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
void ColnodAPI::deleteTokens(const QList<QString> &ids)
{
auto request = composeRequest("/TokenManager/deleteTokens", Token::idsToJSON(ids));
request->setToken(authToken);
request->setUserName(authToken);
mReqMan->processRequest(request);
connect(request.get(), &serversdk::Request::finished, [=](){
if (checkResponse(request->responseData())) {

View File

@ -19,8 +19,9 @@ void Data::loadTokensFromJson(const QByteArray &data)
auto items = doc.object()["items"].toArray();
for (auto item : items) {
auto token = std::make_shared<Token>();
token->fromJson(item.toString().toUtf8());
token->setDeleted(false);
doc.setObject(item.toObject());
token->fromJson(doc.toJson());
//token->setDeleted(false);
updatedTokens.insert(token->id(), token);
}
}
@ -31,7 +32,8 @@ void Data::loadSubjectsFormJson(const QByteArray &data)
auto items = doc.object()["items"].toArray();
for (auto item : items) {
auto subject = std::make_shared<Subject>();
subject->fromJson(item.toString().toUtf8());
doc.setObject(item.toObject());
subject->fromJson(doc.toJson());
subject->setDeleted(false);
updatedSubjects.insert(subject->id(), subject);
}

View File

@ -19,9 +19,9 @@ bool DatabaseAPI::open()
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 "
auto updatedQuery = mDbMan->execPlainSql("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = false");
QSqlQuery deletedQuery = mDbMan->execPlainSql("SELECT id "
auto deletedQuery = mDbMan->execPlainSql("SELECT id "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = true");
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
}
@ -65,7 +65,7 @@ qint64 DatabaseAPI::getLastSync()
void DatabaseAPI::setLastSync(qint64 timestamp)
{
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", timestamp);
mDbMan->executeQuery(query);
@ -73,7 +73,7 @@ void DatabaseAPI::setLastSync(qint64 timestamp)
void DatabaseAPI::setLastUpdate(QHash<QString, std::shared_ptr<Token>> tokens)
{
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
for (const auto &token : tokens){
query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id");
query.bindValue(":last_update", token->lastUpdate());
@ -84,14 +84,14 @@ void DatabaseAPI::setLastUpdate(QHash<QString, std::shared_ptr<Token>> tokens)
qint64 DatabaseAPI::getNow()
{
QSqlQuery query = mDbMan->execPlainSql("SELECT EXTRACT(EPOCH FROM NOW())*1000");
auto query = mDbMan->execPlainSql("SELECT EXTRACT(EPOCH FROM NOW())*1000");
query.next();
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 "
auto 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<QString, std::shared_ptr<Token>> tokensToInit;
while (query.next()){
@ -108,7 +108,7 @@ void DatabaseAPI::initNewTokens()
void DatabaseAPI::uploadTokens(QHash<QString, std::shared_ptr<Token>> tokens)
{
// TODO:
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
for (const auto &token : tokens) {
if (exists(token->id(), "colnod_token")) {
query = utils->updateTable(token.get(), "colnod_token");
@ -123,7 +123,7 @@ void DatabaseAPI::uploadTokens(QHash<QString, std::shared_ptr<Token>> tokens)
void DatabaseAPI::uploadSubjects(QHash<QString, std::shared_ptr<Subject>> subjects)
{
// TODO:
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
for (const auto &subject : subjects) {
if (exists(subject->id(), "colnod_subject")) {
query = utils->updateTable(subject.get(), "colnod_subject");
@ -138,7 +138,7 @@ void DatabaseAPI::uploadSubjects(QHash<QString, std::shared_ptr<Subject>> subjec
void DatabaseAPI::deleteItems(QList<QString> ids, const QString &tableName)
{
// TODO:
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
QString nowString = QDateTime::fromMSecsSinceEpoch(getLastSync()).toString("yyyy-MM-dd hh:mm:ss.zzz");
for (const auto &id : ids) {
query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(tableName));
@ -148,10 +148,23 @@ void DatabaseAPI::deleteItems(QList<QString> ids, const QString &tableName)
}
}
QDateTime DatabaseAPI::getLastUpdate(const QString &id)
{
auto query = mDbMan->createQuery();
query.prepare("SELECT last_update FROM colnod_token WHERE id = :id");
query.bindValue(":id", id);
mDbMan->executeQuery(query);
if (query.next()) {
return query.value(0).toDateTime();
}
else {
return QDateTime();
}
}
bool DatabaseAPI::exists(const QString &id, const QString &tableName)
{
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
query.prepare(QString("SELECT 1 FROM %1 WHERE id = :id").arg(tableName));
query.bindValue(":id", id);
query = mDbMan->executeQuery(query);
@ -165,7 +178,7 @@ bool DatabaseAPI::exists(const QString &id, const QString &tableName)
qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
{
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
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());
@ -173,7 +186,7 @@ qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
{
QSqlQuery query("test", mDbMan->database());
auto query = mDbMan->createQuery();
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())

View File

@ -37,6 +37,8 @@ public:
void uploadSubjects(QHash<QString, std::shared_ptr<Subject> > subjects);
void deleteItems(QList<QString> ids, const QString &tableName);
QDateTime getLastUpdate(const QString &id);
private:
bool exists(const QString &id, const QString &tableName);

View File

@ -9,11 +9,6 @@ Subject::Subject(const QString &name)
setName(name);
}
QByteArray Subject::jsonData() const
{
}
bool Subject::fromJson(const QByteArray &data)
{
@ -37,26 +32,26 @@ bool Subject::fromJson(const QByteArray &data)
}
const QSet<QString> &Subject::getTokenFlags() const {
return tokenFlags;
}
//const QSet<QString> &Subject::getTokenFlags() const {
// return tokenFlags;
//}
void Subject::setTokenFlags(const QSet<QString> &tokenFlags) {
Subject::tokenFlags = tokenFlags;
}
//void Subject::setTokenFlags(const QSet<QString> &tokenFlags) {
// Subject::tokenFlags = tokenFlags;
//}
const QSet<QString> &Subject::getPinFlags() const {
return pinFlags;
}
//const QSet<QString> &Subject::getPinFlags() const {
// return pinFlags;
//}
void Subject::setPinFlags(const QSet<QString> &pinFlags) {
Subject::pinFlags = pinFlags;
}
//void Subject::setPinFlags(const QSet<QString> &pinFlags) {
// Subject::pinFlags = pinFlags;
//}
const QList<QPair<QString, QString>> &Subject::getAtr() const {
return atr;
}
//const QList<QPair<QString, QString>> &Subject::getAtr() const {
// return atr;
//}
void Subject::setAtr(const QList<QPair<QString, QString>> &atr) {
this->atr = atr;
}
//void Subject::setAtr(const QList<QPair<QString, QString>> &atr) {
// this->atr = atr;
//}

View File

@ -34,23 +34,24 @@ public:
Subject() = default;
explicit Subject(const QString& name);
QByteArray jsonData() const override;
bool fromJson(const QByteArray &data) override;
const QJsonObject &getAttributes() const;
void setAttributes(const QJsonObject &attributes);
const QSet<QString> &getTokenFlags() const;
void setTokenFlags(const QSet<QString> &tokenFlags);
const QString &getPin() const;
void setPin(const QString &pin);
const QSet<QString> &getPinFlags() const;
void setPinFlags(const QSet<QString> &pinFlags);
// const QJsonObject &getAttributes() const;
// void setAttributes(const QJsonObject &attributes);
// const QSet<QString> &getTokenFlags() const;
// void setTokenFlags(const QSet<QString> &tokenFlags);
// const QString &getPin() const;
// void setPin(const QString &pin);
// const QSet<QString> &getPinFlags() const;
// void setPinFlags(const QSet<QString> &pinFlags);
const QList<QPair<QString, QString>> &getAtr() const;
void setAtr(const QList<QPair<QString, QString>> &atr);
// const QList<QPair<QString, QString>> &getAtr() const;
// void setAtr(const QList<QPair<QString, QString>> &atr);
private:
QList<std::shared_ptr <SubjectAttribute>> attributes;
QSet<QString> tokenFlags;
QSet<QString> pinFlags;
QList<QPair<QString, QString>> atr;

View File

@ -37,12 +37,12 @@ void SyncManager::run()
void SyncManager::downloadData()
{
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);
colnod->downloadData();
database->downloadData();
}
// finds conflicts -> changes on both sides (colnod and DB), apply newer change
@ -55,16 +55,22 @@ void SyncManager::prepareData()
for (const auto &colnodToken : colnodDataToProcess->updatedTokens) {
if (databaseDataToProcess->updatedTokens.contains(colnodToken->id())) {
// which change was later // if last_update in Colnod and DB equels -> already synced
if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken || databaseDataToProcess->updatedTokens.value(colnodToken->id()) == colnodToken)
if (databaseDataToProcess->updatedTokens.value(colnodToken->id()) > colnodToken) {
idsToDelete.append(colnodToken->id());
}
continue;
}
auto dbLastUpdate = database->getLastUpdate(colnodToken->id());
if ( !dbLastUpdate.isNull() )
if (dbLastUpdate == colnodToken->lastUpdate())
idsToDelete.append(colnodToken->id());
}
for (const auto &id : idsToDelete)
colnodDataToProcess->updatedTokens.remove(id);
idsToDelete.clear();
for (const auto &databaseToken : databaseDataToProcess->updatedTokens) {
for (const auto &databaseToken : databaseData->updatedTokens) {
if (colnodDataToProcess->updatedTokens.contains(databaseToken->id())) {
if (databaseToken > colnodDataToProcess->updatedTokens.value(databaseToken->id()))
idsToDelete.append(databaseToken->id());

View File

@ -22,13 +22,15 @@ Token::~Token()
= default;
QByteArray Token::tokensToJSON(const QHash<QString, std::shared_ptr<Token>> &tokens)
QByteArray Token::tokensToColnodJson(const QHash<QString, std::shared_ptr<Token>> &tokens)
{
QJsonObject items;
QJsonArray jsonTokens;
for (const auto& token : tokens)
{
//jsonTokens.push_back(token->toJSON());
jsonTokens.push_back(QJsonValue(QJsonDocument::fromJson(token->jsonData()).object()));
//jsonTokens.append(QJsonValue::fromVariant(token->jsonData()));
//jsonTokens.push_back(QJsonValue::fromVariant(token->jsonData()));
}
items.insert("items", jsonTokens);
QJsonDocument doc;
@ -36,13 +38,17 @@ QByteArray Token::tokensToJSON(const QHash<QString, std::shared_ptr<Token>> &tok
return doc.toJson();
}
QByteArray Token::jsonData() const
QByteArray Token::jsonData(const QSet<QString> &filters) const
{
auto variantMap = this->toVariantMap();
auto variantMap = this->toVariantMap(filters);
auto enabled = variantMap["enabled"].toBool();
auto noValidity = variantMap["noValidity"].toBool();
variantMap.remove("enabled");
variantMap.remove("noValidity");
variantMap.remove("lastModified");
variantMap.remove("deleted");
variantMap.remove("lastUpdate");
QVariantList flags;
if ( enabled ) {
flags << "Enabled";
@ -70,7 +76,9 @@ bool Token::fromJson(const QByteArray &data)
}
}
variant.remove("flags");
auto lastUpdate = variant["lastUpdate"].toLongLong();
variant["lastUpdate"] = QDateTime::fromMSecsSinceEpoch(lastUpdate);
variant.insert("lastModified", QDateTime::fromMSecsSinceEpoch(lastUpdate));
// Populate this object data
bool res = fromVariantMap(variant);
return res;

View File

@ -10,6 +10,7 @@
#include <QJsonArray>
class Token : public serversdk::DatabaseTable {
Q_OBJECT
TABLE_PROPERTY(QString, id, setId, QString())
@ -27,6 +28,8 @@ class Token : public serversdk::DatabaseTable {
TABLE_PROPERTY(QDateTime, lastModified, setLastModified, QDateTime())
TABLE_PROPERTY(bool, deleted, setDeleted, false)
public:
/**
* # Needed values to proper sync
@ -43,7 +46,7 @@ public:
explicit Token(const QString& name);
~Token() override;
QByteArray jsonData() const override;
QByteArray jsonData(const QSet<QString> &filters = {}) const override;
bool fromJson(const QByteArray &data) override;
friend bool operator<(const Token &lToken, const Token &rToken){
@ -52,6 +55,7 @@ public:
friend bool operator>(const Token &lToken, const Token &rToken){
return lToken.lastModified() > rToken.lastUpdate();
}
friend bool operator==(const Token &lToken, const Token &rToken){
return lToken.id() == rToken.id() &&
lToken.name() == rToken.name() &&
@ -78,7 +82,7 @@ public:
void fromJSON(const QJsonObject &json);
QJsonObject toJSON() const;
static QByteArray tokensToJSON(const QHash<QString, std::shared_ptr<Token> > &tokens);
static QByteArray tokensToColnodJson(const QHash<QString, std::shared_ptr<Token> > &tokens);
static QByteArray idsToJSON(const QList<QString> &ids);
private:

View File

@ -18,6 +18,18 @@ void ComplexTest::initTestCase()
}
//void DatabaseTableTest::enum_test2()
//{
// auto test = R"({"id":"e2432439-41ed-4440-9c8e-40edb9989a15","name":"Pavel Kanka","description":"","lastUpdate":1565350519781,"attributes":{"items":{"Jmeno":"Pavel","Spolecnost":"Colsys","Prijmeni":"Kaňka"}},"tokenFlags":["NoPin"],"pin":"","pinFlags":["Access"]})";
// Subject subject;
// subject.fromJson(test);
// QCOMPARE(subject.name(), "Pavel Kanka");
// qDebug() << subject.name() << subject.lastUpdate() << QDateTime::fromString("2019-08-09 11:35:19.000", "yyyy-MM-dd hh:mm:ss.zzz");
// QCOMPARE(subject.lastUpdate(), QDateTime::fromString("2019-08-09 11:35:19", "yyyy-MM-dd hh:mm:ss.zzz"));
// qDebug() << subject.attrib.value(1)->toVariantMap();
//}
void ComplexTest::cleanupTestCase()
{