Merge branch 'suggest/different-approach' into 'transform-app-using-serversdk'

different approach

See merge request spaceti-app/integrations/acs/colnod-connector!22
This commit is contained in:
Filip Bucek 2019-11-27 12:18:21 +00:00
commit c57200dd0f
6 changed files with 117 additions and 47 deletions

View File

@ -12,9 +12,12 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// App setup
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName("colnod-connector"); QCoreApplication::setApplicationName("colnod-connector");
QCoreApplication::setApplicationVersion("1.0"); QCoreApplication::setApplicationVersion("1.0");
// Command line parsing
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("Colnod sync"); parser.setApplicationDescription("Colnod sync");
QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made"); QCommandLineOption dryModeOption("dryMode", "ColnodAPI", "Read-only mode, prints changes which would normally be made");
@ -26,8 +29,9 @@ int main(int argc, char *argv[])
parser.process(app); parser.process(app);
// ======== LOGGER ============== // Logger initializiaton
serversdk::initAppLogger(); // <-- then Logger::outputMessage will handle all messages serversdk::initAppLogger(); // <-- then Logger::outputMessage will handle all messages
// Log messge Filtering // Log messge Filtering
QStringList filters; QStringList filters;
filters << "qt.*=false"; filters << "qt.*=false";
@ -35,16 +39,21 @@ int main(int argc, char *argv[])
//filters << "*=false"; //filters << "*=false";
QLoggingCategory::setFilterRules(filters.join(QStringLiteral("\n"))); QLoggingCategory::setFilterRules(filters.join(QStringLiteral("\n")));
SyncManager api(parser.isSet(dryModeOption));
// TODO: handle error in init
if (api.init()) { SyncManager syncManager(parser.isSet(dryModeOption));
api.run();
} else { // Initialize database and colnod API
//error if (!syncManager.databaseInitialization()) {
qCritical("Not possible to initialize sync application");
return -1; return -1;
} }
// Synchronizaiton
if (!syncManager.startSynchronization()) {
qCritical("Not possible to start synchronization");
return -1;
}
return QCoreApplication::exec(); return QCoreApplication::exec();
} }

View File

@ -19,9 +19,10 @@ public:
} }
}; };
class Data class Data
{ {
friend class ColnodAPI;
friend class DatabaseAPI;
public: public:
Data() = default; Data() = default;

View File

@ -2,6 +2,8 @@
Q_LOGGING_CATEGORY(database, "database.api"); Q_LOGGING_CATEGORY(database, "database.api");
DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan, bool dryMode) DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan, bool dryMode)
: mDryMode(dryMode), : mDryMode(dryMode),
mDbMan(dbMan), mDbMan(dbMan),
@ -34,21 +36,23 @@ bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
return true; return true;
} }
bool DatabaseAPI::downloadData() std::shared_ptr<Data> DatabaseAPI::downloadData()
{ {
bool res = true;
auto updatedQuery = mDbMan->createQuery(); auto updatedQuery = mDbMan->createQuery();
auto deletedQuery = mDbMan->createQuery(); auto deletedQuery = mDbMan->createQuery();
if (!executeQuery(updatedQuery, "SELECT * FROM colnod_token WHERE last_modified > last_update AND deleted = false")) { if (!executeQuery(updatedQuery, "SELECT * FROM colnod_token WHERE last_modified > last_update AND deleted = false")) {
qWarning(database) << "ERROR during geting new/updated tokens from db."; qWarning(database) << "ERROR during geting new/updated tokens from db.";
res = false; return nullptr;
} }
if (!executeQuery(deletedQuery, "SELECT id FROM colnod_token WHERE last_modified > last_update AND deleted = true")) { if (!executeQuery(deletedQuery, "SELECT id FROM colnod_token WHERE last_modified > last_update AND deleted = true")) {
qWarning(database) << "ERROR during geting marked tokens for deletion from db."; qWarning(database) << "ERROR during geting marked tokens for deletion from db.";
res = false; return nullptr;
} }
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
return res; return composeData(updatedQuery, deletedQuery);
// TODO: why emiting signal??
// this can return Strucutre
//emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
} }
bool DatabaseAPI::processData(const std::shared_ptr<Data> &data) bool DatabaseAPI::processData(const std::shared_ptr<Data> &data)
@ -153,7 +157,7 @@ qint64 DatabaseAPI::getNow()
auto query = mDbMan->createQuery(); auto query = mDbMan->createQuery();
if (!executeQuery(query, "SELECT EXTRACT(EPOCH FROM NOW())*1000")) { if (!executeQuery(query, "SELECT EXTRACT(EPOCH FROM NOW())*1000")) {
qCritical(database) << "ERROR during getting acctual time from db"; qCritical(database) << "ERROR during getting acctual time from db";
emit error(); return -1;
} }
query.next(); query.next();
qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); qDebug() << "Database time:" << QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz");
@ -183,13 +187,29 @@ void DatabaseAPI::initNewTokens()
bool DatabaseAPI::uploadTokens(const QHash<QString, std::shared_ptr<Token>> &tokens) bool DatabaseAPI::uploadTokens(const QHash<QString, std::shared_ptr<Token>> &tokens)
{ {
// TODO: first check if OK, then message
// OK -> token was updated
// ERROR -> not possible to update
auto query = mDbMan->createQuery(); auto query = mDbMan->createQuery();
for (const auto &token : tokens) { for (const auto &token : tokens) {
// Get token
QSqlQuery query;
if (exists(token->id(), "colnod_token")) { if (exists(token->id(), "colnod_token")) {
query = utils->updateTable(token.get(), "colnod_token"); query = utils->updateTable(token.get(), "colnod_token");
qInfo(database).noquote() << Message::massageTemplate("Updating", "token", "database", token->name()); qInfo(database).noquote() << Message::massageTemplate("Updating", "token", "database", token->name());
} }
else { else {
// TODO: first check if OK, then message
// OK -> token was updated
// ERROR -> not possible to update
query = utils->insertIntoTable(token.get(), "colnod_token"); query = utils->insertIntoTable(token.get(), "colnod_token");
qInfo(database).noquote() << Message::massageTemplate("Adding", "token", "database", token->name()); qInfo(database).noquote() << Message::massageTemplate("Adding", "token", "database", token->name());
} }

View File

@ -12,6 +12,8 @@
Q_DECLARE_LOGGING_CATEGORY(database) Q_DECLARE_LOGGING_CATEGORY(database)
class DatabaseAPI : public QObject class DatabaseAPI : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -22,7 +24,7 @@ public:
bool executeQuery(QSqlQuery &query, const QString &statement = QString()); bool executeQuery(QSqlQuery &query, const QString &statement = QString());
bool downloadData(); std::shared_ptr<Data> downloadData();
bool processData(const std::shared_ptr<Data> &data); bool processData(const std::shared_ptr<Data> &data);
qint64 getLastSync(); qint64 getLastSync();
void setLastSync(qint64 timestamp); void setLastSync(qint64 timestamp);

View File

@ -10,43 +10,78 @@ SyncManager::SyncManager(bool dryMode)
} }
bool SyncManager::init() bool SyncManager::databaseInitialization()
{ {
database = std::make_shared<DatabaseAPI>(&dbMan, mDryMode); database = std::make_shared<DatabaseAPI>(&dbMan, mDryMode);
connect(database.get(), &DatabaseAPI::error, [=](){ // connect(database.get(), &DatabaseAPI::error, [=](){
QCoreApplication::exit(1); // QCoreApplication::exit(1);
}); // });
if (database->open()){ // Open database
mlastSync.set_timestamp(database->getLastSync()); if (!database->open()) {
qCritical(syncmanager) << "Not possible to open database:" << dbMan.database().hostName();
colnod = std::make_shared<ColnodAPI>(&reqMan, mlastSync.timestamp(), mDryMode); return false;
connect(colnod.get(), &ColnodAPI::error, [=](){
QCoreApplication::exit(1);
});
// -1 --> some error with getting data from DB
if (mlastSync.timestamp() >= 0){
return true;
}
qCritical(syncmanager) << "Couldn't get time of last synchronization";
} }
else
qCritical(syncmanager) << "Opening database wasn't successful"; // Get last synchronizaiton date
return false; qint64 lastsync_in_ms = database->getLastSync();
if (lastsync_in_ms == -1) {
qCritical(syncmanager) << "Not possible to get last synchronization date";
return false;
}
// here -> nothing can fail
mlastSync.set_timestamp(database->getLastSync());
colnod = std::make_shared<ColnodAPI>(&reqMan, mlastSync.timestamp(), mDryMode);
return true;
} }
bool SyncManager::run() bool SyncManager::startSynchronization()
{ {
// I have to current time from database
qint64 syncBegin = database->getNow(); qint64 syncBegin = database->getNow();
if (syncBegin == -1) {
qCritical(syncmanager) << "Not possible to get last sync date";
return false;
}
qInfo(syncmanager) << equals; qInfo(syncmanager) << equals;
qInfo(syncmanager) << "SYNCHRONIZATION BEGIN"; qInfo(syncmanager) << "SYNCHRONIZATION BEGIN";
// TODO: check error
database->initNewTokens(); database->initNewTokens();
downloadData();
// GETTING DATA FROM DATABASE
auto databaseData = database->downloadData();
if (!databaseData) {
qCritical(syncmanager) << "not possible to get data from database";
return false;
}
// NOW I HAVE DATA FROM DATABASE
colnod->downloadData();
connect(colnod.get(), &ColnodAPI::downloadDataFinished, [=](std::shared_ptr<Data> data) {
// NOW I HAVE DATA FROM COLNOD
// I can process data
qDebug(syncmanager) << "I have colnod and database data";
qDebug(syncmanager) << "updated token count" << data->updatedTokens.count();
});
return true;
//downloadData();
auto colnodDataFinished = [=](std::shared_ptr<Data> data) {
qDebug() << "Now I can check that I have all data I need";
};
//connect(this, &SyncManager::dataReady, processDownloadedData);
connect(this, &SyncManager::dataReady, [=](){ connect(this, &SyncManager::dataReady, [=](){
prepareData(); prepareData();
@ -77,6 +112,7 @@ bool SyncManager::run()
processData(); processData();
}); });
return true;
} }
bool SyncManager::downloadData() bool SyncManager::downloadData()
@ -89,14 +125,11 @@ bool SyncManager::downloadData()
qInfo(syncmanager) << dash; qInfo(syncmanager) << dash;
connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData); connect(colnod.get(), &ColnodAPI::downloadDataFinished, this, &SyncManager::saveColnodData);
connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData); //connect(database.get(), &DatabaseAPI::downloadDataFinished, this, &SyncManager::saveDatabaseData);
if (!database->downloadData()) { //database->downloadData();
res = false;
}
colnod->downloadData(); colnod->downloadData();
return true; return res;
} }
// finds conflicts -> changes on both sides (colnod and DB), apply newer change // finds conflicts -> changes on both sides (colnod and DB), apply newer change
@ -109,6 +142,11 @@ bool SyncManager::prepareData()
qInfo(syncmanager) << dash; qInfo(syncmanager) << dash;
Q_ASSERT(colnodData);
Q_ASSERT(databaseData);
// TODO: why copy data?
colnodDataToProcess = std::make_shared<Data>(*colnodData); colnodDataToProcess = std::make_shared<Data>(*colnodData);
databaseDataToProcess = std::make_shared<Data>(*databaseData); databaseDataToProcess = std::make_shared<Data>(*databaseData);
@ -213,7 +251,7 @@ void SyncManager::updateLastUpdate(qint64 syncBegin)
void SyncManager::areDataReady() void SyncManager::areDataReady()
{ {
if (++dataAmount == 2) { if (++dataAmount == 1) {
qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED"; qInfo(syncmanager) << "DOWNLOADING DATA -> FINISHED";
qInfo(syncmanager) << equals; qInfo(syncmanager) << equals;

View File

@ -11,8 +11,8 @@ class SyncManager : public QObject
public: public:
explicit SyncManager(bool dryMode); explicit SyncManager(bool dryMode);
bool init(); bool databaseInitialization();
bool run(); bool startSynchronization();
private: private:
bool downloadData(); bool downloadData();