Files
qt5-legatus-legacy/Lts/Services/OcBaseDownload/handler_base_download.cpp
T
2026-08-13 18:33:10 +02:00

2364 lines
76 KiB
C++
Executable File

/**
* Handler for base download coordination
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 15-03-2018
*/
#include "handler_base_download.h"
#include <QStringList>
#include <QSettings>
#include <QSqlDriver>
#include <QSqlField>
#include <QSqlRecord>
#include <ngldb/dbconnection.h>
#include <ngldb/dbtransaction.h>
#include <ngldb/db_service_handler.h>
#include <ngldb/nsqlquery.h>
#include <nglsettings/nglsettings_settings.h>
#include <nglsettings/nglsettings_connections.h>
#include <ParticipantManagement/ppm_translation.h>
#include <ngltools/ngltools_filesystem.h>
#include <DDS/Core/pacemaker.h>
#include <QUuid>
#include <QDateTime>
#include "copy_database.h"
#include "main_handler.h"
#include "settings.h"
#include "WebSocketInterface/Messages/reply_message.h"
namespace OcBaseDownload
{
HandlerBaseDownload::HandlerBaseDownload(MainHandler *mainHandler, QObject *parent)
: QObject(parent)
, Interface::Fts::StartBaseDownloadRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::LifeUpdateRequestHandler(mainHandler->dds()->fts())
, m_fts(mainHandler->dds()->fts())
, m_scmDtc(mainHandler->scmDtc())
, m_scmFtc(mainHandler->scmFtc())
, m_baseDownloadReplyUpdateTimer(new QTimer(this))
, m_mainHandler(mainHandler)
, m_exerciseId(0)
, m_operatorId(9)
, m_hostname(NGL::Connections::hostName(NGL::Connections::eConnection::SCM_WEBSOCKET))
, m_currentState(NotStarted)
, m_remoteDbRetryCounter(0)
, m_copyDatabase(new CopyDatabase(getLogger("HandlerBaseDownload"), this))
, m_exTblGen(new DBAdministration::ExerciseTableGenerator(getLogger("ExerciseTableGenerator"), NGL::directory(NGL::FileType::ConfigFile, QLatin1String("xml")), this))
, m_logger(getLogger("HandlerBaseDownload"))
{
connect(m_baseDownloadReplyUpdateTimer, &QTimer::timeout,
this, &HandlerBaseDownload::updateBaseDownloadReply);
m_baseDownloadReplyUpdateTimer->setInterval(3000);
connect(m_copyDatabase, &CopyDatabase::copyDbFailed,
this, &HandlerBaseDownload::onCopyDbFailed);
connect(m_copyDatabase, &CopyDatabase::copyDbFinished,
this, &HandlerBaseDownload::onCopyDbFinished);
connect(m_copyDatabase, &CopyDatabase::dropDatabaseFailed,
this, &HandlerBaseDownload::onDropOldDatabaseFailed);
connect(m_copyDatabase, &CopyDatabase::dropDatabaseFinished,
this, &HandlerBaseDownload::onDropOldDatabaseFinished);
connect(m_exTblGen, &DBAdministration::ExerciseTableGenerator::aliveSignal,
this, &HandlerBaseDownload::updateBaseDownloadReply);
connect(m_exTblGen, &DBAdministration::ExerciseTableGenerator::aliveSignal,
mainHandler->dds()->pacemaker().get(), &Core::Pacemaker::publishState);
}
HandlerBaseDownload::~HandlerBaseDownload()
{
m_fts = nullptr;
m_scmDtc = nullptr;
m_scmFtc = nullptr;
delete m_baseDownloadReplyUpdateTimer;
}
bool HandlerBaseDownload::init()
{
// SCM DTC enable
if (!m_scmDtc->enableServiceInformation() ||
!m_scmDtc->enableGroupInformation())
{
ERROR_LOG(m_logger) << "Enabling SCM Data-Topics failed.";
return false;
}
// SCM FTC enable
if (!m_scmFtc->enableRestartGroup() ||
!m_scmFtc->enableStopGroup())
{
ERROR_LOG(m_logger) << "Enabling SCM Function-Topics failed.";
return false;
}
INFO_LOG(m_logger) << "HandlerBaseDownload initialised!";
return true;
}
void HandlerBaseDownload::handleErrorMessage(const QString &err)
{
QString text = QString::fromLatin1(tr_lts("dds", "Got ErrorMessage via web socket: %1")).arg(err);
cleanup(Core::FtReplyState::Error, text.toStdString());
}
void HandlerBaseDownload::receiveAsmData()
{
using namespace AssetManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::AsmTrainingArea))
{
QVector<Database::AsmTrainingArea> asmTrainingAreas;
if (remoteDbIfc->select(asmTrainingAreas))
{
storeToDataVecMap(DbDataType::AsmTrainingArea, std::vector<Database::AsmTrainingArea>(asmTrainingAreas.begin(), asmTrainingAreas.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::AsmTechnicalArea))
{
QVector<Database::AsmTechnicalArea> asmTechnicalAreas;
if (remoteDbIfc->select(asmTechnicalAreas))
{
storeToDataVecMap(DbDataType::AsmTechnicalArea, std::vector<Database::AsmTechnicalArea>(asmTechnicalAreas.begin(), asmTechnicalAreas.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::AsmLocation))
{
QVector<Database::AsmLocation> asmLocations;
if (remoteDbIfc->select(asmLocations))
{
storeToDataVecMap(DbDataType::AsmLocation, std::vector<Database::AsmLocation>(asmLocations.begin(), asmLocations.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::AsmAsset))
{
QVector<Database::AsmAsset> asmAssets;
if (remoteDbIfc->select(asmAssets))
{
storeToDataVecMap(DbDataType::AsmAsset, std::vector<Database::AsmAsset>(asmAssets.begin(), asmAssets.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForAsmFinished();
}
void HandlerBaseDownload::receiveExmData()
{
// handling EXM data
using namespace ExerciseManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::ExmExercise))
{
QVector<Database::ExmExercise> exmExercises;
if (remoteDbIfc->select(exmExercises))
{
storeToDataVecMap(DbDataType::ExmExercise, std::vector<Database::ExmExercise>(exmExercises.begin(), exmExercises.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::ExmExercisePhase))
{
QVector<Database::ExmExercisePhase> exmExercisePhases;
if (remoteDbIfc->select(exmExercisePhases))
{
storeToDataVecMap(DbDataType::ExmExercisePhase, std::vector<Database::ExmExercisePhase>(exmExercisePhases.begin(), exmExercisePhases.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::ExmExerciseStateChange))
{
QVector<Database::ExmExerciseStateChange> exmExerciseStateChanges;
if (remoteDbIfc->select(exmExerciseStateChanges))
{
storeToDataVecMap(DbDataType::ExmExerciseStateChange, std::vector<Database::ExmExerciseStateChange>(exmExerciseStateChanges.begin(), exmExerciseStateChanges.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForExmFinished();
}
void HandlerBaseDownload::receiveIsmData()
{
// handling ISM data
using namespace InfrastructureManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::IsmAsset))
{
QVector<Database::IsmAsset> ismAssets;
if (remoteDbIfc->select(ismAssets))
{
storeToDataVecMap(DbDataType::IsmAsset, std::vector<Database::IsmAsset>(ismAssets.begin(), ismAssets.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmSpecialArea))
{
QVector<Database::IsmSpecialArea> ismSpecialAreas;
if (remoteDbIfc->select(ismSpecialAreas))
{
storeToDataVecMap(DbDataType::IsmSpecialArea, std::vector<Database::IsmSpecialArea>(ismSpecialAreas.begin(), ismSpecialAreas.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmMainStructureElement))
{
QVector<Database::IsmMainStructureElement> ismMainStructureElements;
if (remoteDbIfc->select(ismMainStructureElements))
{
storeToDataVecMap(DbDataType::IsmMainStructureElement, std::vector<Database::IsmMainStructureElement>(ismMainStructureElements.begin(), ismMainStructureElements.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmStructureElement))
{
QVector<Database::IsmStructureElement> ismStructureElements;
if (remoteDbIfc->select(ismStructureElements))
{
storeToDataVecMap(DbDataType::IsmStructureElement, std::vector<Database::IsmStructureElement>(ismStructureElements.begin(), ismStructureElements.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmStructureElementFootprint))
{
QVector<Database::IsmStructureElementFootprint> ismStructureElementFootprints;
if (remoteDbIfc->select(ismStructureElementFootprints))
{
storeToDataVecMap(DbDataType::IsmStructureElementFootprint, std::vector<Database::IsmStructureElementFootprint>(ismStructureElementFootprints.begin(), ismStructureElementFootprints.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmMountingPointAsset))
{
QVector<Database::IsmMountingPointAsset> ismMountingPointAssets;
if (remoteDbIfc->select(ismMountingPointAssets))
{
storeToDataVecMap(DbDataType::IsmMountingPointAsset, std::vector<Database::IsmMountingPointAsset>(ismMountingPointAssets.begin(), ismMountingPointAssets.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmMountingPointSchedule))
{
QVector<Database::IsmMountingPointSchedule> ismMountingPointSchedules;
if (remoteDbIfc->select(ismMountingPointSchedules))
{
storeToDataVecMap(DbDataType::IsmMountingPointSchedule, std::vector<Database::IsmMountingPointSchedule>(ismMountingPointSchedules.begin(), ismMountingPointSchedules.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::IsmMountingPointPlan))
{
QVector<Database::IsmMountingPointPlan> ismMountingPointPlans;
if (remoteDbIfc->select(ismMountingPointPlans))
{
storeToDataVecMap(DbDataType::IsmMountingPointPlan, std::vector<Database::IsmMountingPointPlan>(ismMountingPointPlans.begin(), ismMountingPointPlans.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForIsmFinished();
}
void HandlerBaseDownload::receivePpmEx0Data()
{
// handling PPM Ex0 data
using namespace ParticipantManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::PpmEquipmentType))
{
QVector<Database::PpmEquipmentType> ppmEquipmentTypes;
if (remoteDbIfc->select(ppmEquipmentTypes))
{
storeToDataVecMap(DbDataType::PpmEquipmentType, std::vector<Database::PpmEquipmentType>(ppmEquipmentTypes.begin(), ppmEquipmentTypes.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::PpmType))
{
QVector<Database::PpmType> ppmTypes;
if (remoteDbIfc->select(ppmTypes))
{
storeToDataVecMap(DbDataType::PpmType, std::vector<Database::PpmType>(ppmTypes.begin(), ppmTypes.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForPpmEx0Finished();
}
void HandlerBaseDownload::receivePpmExNData()
{
// handling PPM ExN data
using namespace ParticipantManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(m_exerciseId, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::PpmParty))
{
QVector<Database::PpmParty> ppmParties;
if (remoteDbIfc->select(ppmParties))
{
storeToDataVecMap(DbDataType::PpmParty, std::vector<Database::PpmParty>(ppmParties.begin(), ppmParties.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::PpmParticipant))
{
QVector<Database::PpmParticipant> ppmParticipants;
if (remoteDbIfc->select(ppmParticipants))
{
storeToDataVecMap(DbDataType::PpmParticipant, std::vector<Database::PpmParticipant>(ppmParticipants.begin(), ppmParticipants.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForPpmExNFinished();
}
void HandlerBaseDownload::receiveOpmData()
{
// handling OPM data
using namespace OperatorManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
if (!m_dataVecMap.contains(DbDataType::OpmGroup))
{
QVector<Database::OpmGroup> opmGroups;
if (remoteDbIfc->select(opmGroups))
{
storeToDataVecMap(DbDataType::OpmGroup, std::vector<Database::OpmGroup>(opmGroups.begin(), opmGroups.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmGroupGroup))
{
QVector<Database::OpmGroupGroup> opmGroupGroups;
if (remoteDbIfc->select(opmGroupGroups))
{
storeToDataVecMap(DbDataType::OpmGroupGroup, std::vector<Database::OpmGroupGroup>(opmGroupGroups.begin(), opmGroupGroups.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmOperator))
{
QVector<Database::OpmOperator> opmOperators;
if (remoteDbIfc->select(opmOperators))
{
storeToDataVecMap(DbDataType::OpmOperator, std::vector<Database::OpmOperator>(opmOperators.begin(), opmOperators.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmOperatorExercise))
{
QVector<Database::OpmOperatorExercise> opmOperatorExercises;
if (remoteDbIfc->select(opmOperatorExercises))
{
storeToDataVecMap(DbDataType::OpmOperatorExercise, std::vector<Database::OpmOperatorExercise>(opmOperatorExercises.begin(), opmOperatorExercises.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmSettings))
{
QVector<Database::OpmSettings> opmSettings;
if (remoteDbIfc->select(opmSettings))
{
storeToDataVecMap(DbDataType::OpmSettings, std::vector<Database::OpmSettings>(opmSettings.begin(), opmSettings.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmAccessControlLevel))
{
QVector<Database::OpmAccessControlLevel> opmAccessControlLevel;
if (remoteDbIfc->select(opmAccessControlLevel))
{
storeToDataVecMap(DbDataType::OpmAccessControlLevel, std::vector<Database::OpmAccessControlLevel>(opmAccessControlLevel.begin(), opmAccessControlLevel.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmAclAllow))
{
QVector<Database::OpmAclAllow> opmAclAllows;
if (remoteDbIfc->select(opmAclAllows))
{
storeToDataVecMap(DbDataType::OpmAclAllow, std::vector<Database::OpmAclAllow>(opmAclAllows.begin(), opmAclAllows.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
if (!m_dataVecMap.contains(DbDataType::OpmAclDeny))
{
QVector<Database::OpmAclDeny> opmAclDenys;
if (remoteDbIfc->select(opmAclDenys))
{
storeToDataVecMap(DbDataType::OpmAclDeny, std::vector<Database::OpmAclDeny>(opmAclDenys.begin(), opmAclDenys.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForOpmFinished();
}
void HandlerBaseDownload::receiveFlmData()
{
// handling FLM data
using namespace FileManagement;
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(0, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
QVector<Database::FlmFolder> flmFolders;
if (!m_dataVecMap.contains(DbDataType::FlmFolder))
{
if (remoteDbIfc->select(flmFolders))
{
storeToDataVecMap(DbDataType::FlmFolder, std::vector<Database::FlmFolder>(flmFolders.begin(), flmFolders.end()));
m_remoteDbRetryCounter = 0;
}
else
{
retryCurrentSelect();
return;
}
}
if (flmFolders.isEmpty())
{
auto foldersDataVec = getDbDataVec<FileManagement::Database::FlmFolder>(DbDataType::FlmFolder);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
flmFolders = QVector<Database::FlmFolder>(foldersDataVec.begin(), foldersDataVec.end()); // since qt5.14
#else
flmFolders = flmFolders.fromStdVector(foldersDataVec);
#endif
}
if (!m_dataVecMap.contains(DbDataType::FlmFileContent))
{
int snapshotFolderId = getFolderId(flmFolders, QStringLiteral("Snapshots"), m_exerciseId);
//this is DONE BY HAND!!!! so very uncool
//I HATE YOU SO MUCH YOU FUCKING FUCK FUCK! still is!
const QString where = QStringLiteral(" WHERE ((exercise_id is null OR exercise_id = ") + QString::number(m_exerciseId) + QStringLiteral(") and file_type_id in (1,2,6,7,8) )");
const QString where2 = QStringLiteral(" or (exercise_id = ") + QString::number(m_exerciseId) + QStringLiteral(" and file_type_id in (4,5) and folder_id=") + QString::number(snapshotFolderId)+QStringLiteral(" )");
const QString tableName(QStringLiteral("flm.flm_file_content"));
const QString stmt(QStringLiteral("SELECT id, name, is_template, folder_id, file_category_id, file_type_id, file_status_id, exercise_id, phase_id, operator_id, content, properties, is_used_by, used_by, last_modified"
" FROM ") + tableName + where + where2);
ERROR_LOG(m_logger) << "FUCK FUCK WE ARE HERE!" << " snapshid id is= " << snapshotFolderId << " also my statement: " << stmt;
std::unique_ptr<NSqlQuery> query = std::unique_ptr<NSqlQuery>(new NSqlQuery(remoteDbIfc->database(), m_logger));
query->prepare(stmt);
QVector<Database::FlmFileContent> dataVec;
if (query->exec())
{
Database::FlmFileContent data;
while (query->next())
{
int i = 0;
data.id = query->value(i++).toLongLong();
data.name = query->value(i++).toString();
data.isTemplate = query->value(i++).toBool();
data.folderId = query->value(i++).toLongLong();
data.fileCategoryId = static_cast<FileManagement::FileCategory_def::type>(query->value(i++).toInt());
data.fileTypeId = static_cast<FileManagement::FileType_def::type>(query->value(i++).toInt());
data.fileStatusId = static_cast<FileManagement::FileStatus_def::type>(query->value(i++).toInt());
data.exerciseId = query->value(i++);
data.phaseId = query->value(i++);
data.operatorId = query->value(i++).toInt();
data.content = query->value(i++).toByteArray();
QVariant xx = query->value(i++);
data.properties = xx.isNull() ? QStringLiteral("{}") : xx.toString();
data.isUsedBy = query->value(i++).toBool();
data.usedBy = query->value(i++).toInt();
data.lastModified = query->value(i++).toLongLong();
if ((data.fileTypeId == FileManagement::FileType::Jpg ||
data.fileTypeId == FileManagement::FileType::Png)
&& data.folderId != snapshotFolderId)
{
DEBUG_LOG(m_logger) << "skip";
continue;
}
// ERROR_LOG(m_logger) << "ADD " << data.name;
dataVec.append(data);
}
}
if (!dataVec.isEmpty())
{
ERROR_LOG(m_logger) << "Data vec has sisze: " << dataVec.size();
storeToDataVecMap(DbDataType::FlmFileContent, std::vector<Database::FlmFileContent>(dataVec.begin(), dataVec.end()));
m_remoteDbRetryCounter = 0;
}
else
retryCurrentSelect();
}
checkForFlmFinished();
}
int HandlerBaseDownload::getFolderId(const QVector<FileManagement::Database::FlmFolder> &dataVec, const QString &folderName, int exerciseId) const
{
int parentFolder = 0;
if (exerciseId > 0)
{
const QString exName = QLatin1String("$EX_") + QString::number(exerciseId);
parentFolder = getFolderId(dataVec, exName, 0);
}
for (const auto &fld : dataVec)
{
if (fld.name == folderName)
{
if (exerciseId > 0 && parentFolder > 0)
{
if (fld.path().size() > 1 && fld.path().at(fld.path().size() - 2) == parentFolder)
return fld.id;
}
else
return fld.id;
}
}
return 0;
}
bool HandlerBaseDownload::openDbConnection(const QString &databaseName)
{
if (m_dbConnection.isValid())
{
m_exTblGen->close();
closeDb(m_dbConnection);
}
bool bOk;
m_dbConnection = openDb(databaseName, false, &bOk);
if (!bOk)
return false;
return m_exTblGen->init(m_dbConnection, QStringLiteral("exm"));
}
bool HandlerBaseDownload::openRemoteDbConnection(const QString &remoteDatabaseName)
{
if (m_remoteDbConnection.isValid())
closeDb(m_remoteDbConnection);
bool bOk;
m_remoteDbConnection = openDb(remoteDatabaseName, true, &bOk);
if (!bOk)
return false;
return true;
}
QSqlDatabase HandlerBaseDownload::openDb(const QString &databaseName, bool remote, bool *bOk)
{
if (bOk)
*bOk = true;
// open postgres db, read table structure, read static data
auto s = Settings::settings();
const QString dbUser(QStringLiteral("ets_exm"));
const QString dbPasswd(QStringLiteral("ets11de"));
QSqlDatabase dbConnection = DBConnection::open(m_logger,
dbUser,
dbPasswd,
s->databaseDriver(),
remote ? m_hostname : s->databaseHostname(),
remote ? Settings::remoteDbName() : databaseName);
DEBUG_LOG(m_logger) << "Trying to open database " << s->databaseHostname() << ":" << databaseName;
if (!dbConnection.isOpen())
{
ERROR_LOG(m_logger) << "Error opening database " << s->databaseHostname() << ":" << databaseName;
if (bOk)
*bOk = false;
}
else
NOTICE_LOG(m_logger) << "Opened database connection " << dbConnection.connectionName();
return dbConnection;
}
void HandlerBaseDownload::closeDb(QSqlDatabase &dbConn)
{
const QString connName = dbConn.connectionName();
NOTICE_LOG(m_logger) << "Closing database connection " << connName;
dbConn.close();
dbConn = QSqlDatabase();
QSqlDatabase::removeDatabase(connName);
}
template<typename T>
const std::vector<T> &HandlerBaseDownload::getDbDataVec(DbDataType type) const
{
return static_cast<DbData<T>*>(m_dataVecMap[type])->data();
}
template <typename T>
inline void storeVector(const QVector<T> &vec, QPair<bool, QVector<T>> &storage)
{
storage.first = true;
storage.second = vec;
}
void HandlerBaseDownload::updateBaseDownloadReply()
{
NOTICE_LOG(m_logger) << "updateBaseDownloadReply...";
m_fts->startBaseDownloadReply(m_baseDownloadCookie, m_reply);
}
void HandlerBaseDownload::onStartBaseDownloadRequest(const rti::core::SampleIdentity &cookie, const StartBaseDownloadRequest &request)
{
DEBUG_LOG(m_logger) << "Got Request, check for old one : " << request.hostname();
if (request.timeStamp() < (QDateTime::currentMSecsSinceEpoch() - 10 * 1000)) //(5Sekunden)
{
DEBUG_LOG(m_logger) << "old call? ignore! ";
m_reply.progress(0);
m_reply.errorString(std::string());
m_reply.currentStep(std::string());
m_reply.replyState(Core::FtReplyState::Error);
m_fts->startBaseDownloadReply(m_baseDownloadCookie, m_reply);
return;
}
// m_webSocket->setCurrentDownload(WebSocketInterface::CurrentDownload::BASE);
m_baseDownloadCookie = cookie;
m_exerciseId = request.exerciseId();
m_operatorId = request.loggedInOperatorId();
m_hostname = Settings::remoteDbHostName();
m_reply.progress(0);
m_reply.errorString(std::string());
m_reply.currentStep(std::string());
m_reply.replyState(Core::FtReplyState::InProgress);
m_fts->startBaseDownloadReply(m_baseDownloadCookie, m_reply);
m_baseDownloadReplyUpdateTimer->start();
m_currentState = NotStarted;
QTimer::singleShot(0, this, &HandlerBaseDownload::switchState);
}
void HandlerBaseDownload::onLifeUpdateRequest(const rti::core::SampleIdentity &cookie, const LiveUpdateRequest &request)
{
// handling PPM ExN data
using namespace ParticipantManagement;
m_exerciseId = request.timeStamp();
//m_hostname = QStringLiteral("EXCDBS01");
openRemoteDbConnection(QStringLiteral("lts_ets_pro"));
openDbConnection(currentDatabaseName());
auto remoteDb = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!remoteDb->init(m_exerciseId, m_remoteDbConnection))
return;
auto remoteDbIfc = remoteDb->db();
QVector<Database::PpmParticipant> ppmParticipants;
if (remoteDbIfc->select(ppmParticipants))
{
storeToDataVecMap(DbDataType::PpmParticipant, std::vector<Database::PpmParticipant>(ppmParticipants.begin(), ppmParticipants.end()));
insertPpmExNDbData(true);
}
//Opm & OpmExercise?
m_fts->lifeUpdateReply(cookie, Core::FunctionReplyObject());
}
void HandlerBaseDownload::switchLog(HandlerBaseDownload::State state, const std::string &currentStep)
{
NOTICE_LOG(m_logger) << "Switching state from " << m_currentState << " to " << state << " - " << currentStep;
m_currentState = state;
m_reply.currentStep(currentStep);
if (state != Finished)
{
m_reply.progress(m_reply.progress() + SingleStepSize);
updateBaseDownloadReply();
}
else
m_reply.progress(100); // updateBaseDownloadReply is called in cleanup which is executed next
m_baseDownloadReplyUpdateTimer->start();
}
void HandlerBaseDownload::stateFinished()
{
m_remoteDbRetryCounter = 0;
m_currentState = static_cast<State>(m_currentState | Finished);
QTimer::singleShot(0, this, &HandlerBaseDownload::switchState);
checkAliveTimer();
}
void HandlerBaseDownload::switchState()
{
switch (m_currentState)
{
case NotStarted:
{
m_aliveTimer.start();
switchLog(DropOldDatabaseRequest, tr_lts("dds", "Removing outdated database(s)"));
dropOldDatabase();
break;
}
case DropOldDatabaseFinished:
{
switchLog(CopyDatabaseRequest, tr_lts("dds", "Creating new database"));
copyDatabase();
break;
}
case CopyDatabaseFinished:
{
switchLog(AsmDownloadRequest, tr_lts("dds", "Requesting asset management data."));
if (openRemoteDbConnection(QStringLiteral("lts_ets_pro")))
receiveAsmData();
else
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Cannot connect to remote Database!"));
break;
}
case AsmDownloadFinished:
{
switchLog(ExmDownloadRequest, tr_lts("dds", "Requesting exercise management data."));
receiveExmData();
break;
}
case ExmDownloadFinished:
{
switchLog(IsmDownloadRequest, tr_lts("dds", "Requesting infrastructure management data."));
receiveIsmData();
break;
}
case IsmDownloadFinished:
{
switchLog(PpmDownloadEx0Request, tr_lts("dds", "Requesting participant management data."));
receivePpmEx0Data();
break;
}
case PpmDownloadEx0Finished:
{
switchLog(PpmDownloadExNRequest, tr_lts("dds", "Requesting participant management data."));
receivePpmExNData();
break;
}
case PpmDownloadExNFinished:
{
switchLog(OpmDownloadRequest, tr_lts("dds", "Requesting operator management data."));
receiveOpmData();
break;
}
case OpmDownloadFinished:
{
switchLog(FlmDownloadRequest, tr_lts("dds", "Requesting file management data."));
receiveFlmData();
break;
}
case FlmDownloadFinished:
{
closeDb(m_remoteDbConnection);
if (!openDbConnection(nextDatabaseName()))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Could not open DB."));
return;
}
removeOldExercises();
break;
}
case DeletingOldExerciseFinished:
{
replaceAsmDbData();
break;
}
case InsertingAsmDataFinished:
{
replacePpmEx0DbData();
break;
}
case InsertingPpmEx0DataFinished:
{
switchLog(InsertingExmData, tr_lts("dds", "Creating new exercise."));
createNewExercise();
replaceExmDbData();
break;
}
case InsertingExmDataFinished:
{
replaceOpmDbData();
break;
}
case InsertingOpmDataFinished:
{
replaceIsmDbData();
break;
}
case InsertingIsmDataFinished:
{
insertPpmExNDbData();
break;
}
case InsertingPpmExNDataFinished:
{
replaceFlmDbData();
break;
}
case InsertingFlmDataFinished:
{
copyFromOldDatabase();
break;
}
case CopyDataFinished:
{
updateLtsConfig();
break;
}
case UpdatingLtsConfigFinished:
{
switchLog(Finished, tr_lts("dds", "Base download finished."));
cleanup(Core::FtReplyState::Completed);
break;
}
case Finished:
break;
default:
{
ERROR_LOG(m_logger) << "State " << m_currentState << " is not handled properly.";
break;
}
}
}
void HandlerBaseDownload::dropOldDatabase()
{
QString dbNameTmpl = nextDatabaseName();
const int idx = dbNameTmpl.lastIndexOf(QLatin1Char('_'));
Q_ASSERT(idx > 0);
bool bOk;
const int curId = dbNameTmpl.midRef(idx + 1).toInt(&bOk);
if (!openDbConnection(currentDatabaseName()))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Could not open DB."));
return;
}
Q_ASSERT(bOk);
dbNameTmpl = dbNameTmpl.left(idx + 1);
QSqlQuery q(m_dbConnection);
if (!q.exec(QStringLiteral("SELECT datname FROM pg_catalog.pg_database WHERE datname LIKE '%1%'").arg(dbNameTmpl)))
{
stateFinished();
return;
}
while (q.next())
{
const QString val = q.value(0).toString();
const int revId = val.midRef(idx + 1).toInt(&bOk);
if (!bOk)
continue;
DEBUG_LOG(m_logger) << val << ", " << revId << ", " << curId;
if (revId < curId - 1 || revId >= curId)
m_databasesToDrop += val;
}
if (m_databasesToDrop.isEmpty())
{
stateFinished();
return;
}
m_copyDatabase->dropDatabase(m_databasesToDrop.takeLast());
}
void HandlerBaseDownload::onDropOldDatabaseFailed()
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Dropping old databases failed."));
}
void HandlerBaseDownload::onDropOldDatabaseFinished()
{
if (m_databasesToDrop.isEmpty())
{
stateFinished();
return;
}
m_copyDatabase->dropDatabase(m_databasesToDrop.takeLast());
}
void HandlerBaseDownload::copyDatabase()
{
m_copyDatabase->init(QStringLiteral("localhost"), currentDatabaseName(), nextDatabaseName());
m_copyDatabase->doCopy();
}
void HandlerBaseDownload::onCopyDbFailed()
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Copyping database failed."));
}
void HandlerBaseDownload::onCopyDbFinished()
{
stateFinished();
}
void HandlerBaseDownload::checkForAsmFinished()
{
DEBUG_LOG(m_logger) << "Checking if all ASM base data arrived.";
if (m_dataVecMap.contains(AsmTrainingArea) &&
m_dataVecMap.contains(AsmLocation) &&
m_dataVecMap.contains(AsmAsset) &&
m_dataVecMap.contains(AsmTechnicalArea))
{
INFO_LOG(m_logger) << "All ASM base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::checkForExmFinished()
{
DEBUG_LOG(m_logger) << "Checking if all EXM base data arrived.";
if (m_dataVecMap.contains(ExmExercise) &&
m_dataVecMap.contains(ExmExercisePhase) &&
m_dataVecMap.contains(ExmExerciseStateChange))
{
INFO_LOG(m_logger) << "All EXM base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::checkForIsmFinished()
{
DEBUG_LOG(m_logger) << "Checking if all ISM base data arrived.";
if (m_dataVecMap.contains(IsmAsset) &&
m_dataVecMap.contains(IsmMainStructureElement) &&
m_dataVecMap.contains(IsmStructureElement) &&
m_dataVecMap.contains(IsmStructureElementFootprint) &&
m_dataVecMap.contains(IsmMountingPointAsset) &&
m_dataVecMap.contains(IsmMountingPointSchedule) &&
m_dataVecMap.contains(IsmMountingPointPlan))
{
INFO_LOG(m_logger) << "All ISM base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::checkForPpmEx0Finished()
{
DEBUG_LOG(m_logger) << "Checking if all PPM Ex0 base data arrived.";
if (m_dataVecMap.contains(PpmEquipmentType) &&
m_dataVecMap.contains(PpmType))
{
INFO_LOG(m_logger) << "All PPM Ex0 base data arrived.";
stateFinished();
}
}
void HandlerBaseDownload::checkForPpmExNFinished()
{
DEBUG_LOG(m_logger) << "Checking if all PPM ExN base data arrived.";
if (m_dataVecMap.contains(PpmParty) &&
m_dataVecMap.contains(PpmParticipant))
{
INFO_LOG(m_logger) << "All PPM ExN base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::checkForOpmFinished()
{
DEBUG_LOG(m_logger) << "Checking if all OPM base data arrived.";
if (m_dataVecMap.contains(OpmGroup) &&
m_dataVecMap.contains(OpmGroupGroup) &&
m_dataVecMap.contains(OpmOperator) &&
m_dataVecMap.contains(OpmOperatorExercise) &&
m_dataVecMap.contains(OpmSettings) &&
m_dataVecMap.contains(OpmAccessControlLevel) &&
m_dataVecMap.contains(OpmAclAllow) &&
m_dataVecMap.contains(OpmAclDeny))
{
INFO_LOG(m_logger) << "All OPM base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::checkForFlmFinished()
{
DEBUG_LOG(m_logger) << "Checking if all FLM base data arrived.";
if (m_dataVecMap.contains(FlmFolder) &&
m_dataVecMap.contains(FlmFileContent))
{
INFO_LOG(m_logger) << "All FLM base data arrived.";
stateFinished();
}
checkAliveTimer();
}
void HandlerBaseDownload::removeOldExercises()
{
switchLog(DeletingOldExercise, tr_lts("dds", "Deleting previous exercise data if existing."));
auto exmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<ExerciseManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<ExerciseManagement::DatabaseInterface>());
if (!exmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise exmDbHandler"));
return;
}
QVector<ExerciseManagement::Database::ExmExercise> exercises;
exmDbHandler->db()->select(exercises);
for (const auto &ex : qAsConst(exercises))
{
if (m_exTblGen->dropExerciseSchema(ex.id, false))
continue;
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Can not remove old exercise data"));
return;
}
stateFinished();
}
void HandlerBaseDownload::replaceAsmDbData()
{
switchLog(InsertingAsmData, tr_lts("dds", "Inserting new asset management data."));
auto asmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<AssetManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<AssetManagement::DatabaseInterface>());
if (!asmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise asmDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
// clear old data
asmDbHandler->db()->truncateAsmTrainingArea();
asmDbHandler->db()->truncateAsmTechnicalArea();
asmDbHandler->db()->truncateAsmLocation();
asmDbHandler->db()->truncateAsmAsset();
checkAliveTimer();
// insert new data
auto trainingAreaData = getDbDataVec<AssetManagement::Database::AsmTrainingArea>(AsmTrainingArea);
asmDbHandler->db()->upsert(trainingAreaData);
auto technicalAreaData = getDbDataVec<AssetManagement::Database::AsmTechnicalArea>(AsmTechnicalArea);
asmDbHandler->db()->upsert(technicalAreaData);
auto locationData = getDbDataVec<AssetManagement::Database::AsmLocation>(AsmLocation);
asmDbHandler->db()->upsert(locationData);
auto assetData = getDbDataVec<AssetManagement::Database::AsmAsset>(AsmAsset);
asmDbHandler->db()->upsert(assetData);
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting ASM data into database."));
return;
}
stateFinished();
}
void HandlerBaseDownload::createNewExercise()
{
if (!m_exTblGen->createExerciseSchema(m_exerciseId) ||
!m_exTblGen->executeSql(m_exerciseId))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Can not create exercise schema"));
return;
}
}
void HandlerBaseDownload::replaceExmDbData()
{
auto exmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<ExerciseManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<ExerciseManagement::DatabaseInterface>());
if (!exmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise exmDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
// clear old data
exmDbHandler->db()->truncateExmExercisePhase();
exmDbHandler->db()->truncateExmExerciseStateChange();
checkAliveTimer();
// insert new data
for (auto exercise : getDbDataVec<ExerciseManagement::Database::ExmExercise>(ExmExercise))
{
if (exercise.id == m_exerciseId)
exmDbHandler->db()->upsert(exercise);
}
for (auto exPhase : getDbDataVec<ExerciseManagement::Database::ExmExercisePhase>(ExmExercisePhase))
{
if (exPhase.exerciseId == m_exerciseId)
exmDbHandler->db()->upsert(exPhase);
}
for (auto exStateChange : getDbDataVec<ExerciseManagement::Database::ExmExerciseStateChange>(ExmExerciseStateChange))
{
if (exStateChange.exerciseId == m_exerciseId)
exmDbHandler->db()->upsert(exStateChange);
}
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting EXM data into database."));
return;
}
stateFinished();
}
void HandlerBaseDownload::replaceIsmDbData()
{
switchLog(InsertingIsmData, tr_lts("dds", "Inserting new infrastructure management data."));
auto ismDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<InfrastructureManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<InfrastructureManagement::DatabaseInterface>());
if (!ismDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise ismDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
// clear old data
ismDbHandler->db()->truncateIsmAsset();
ismDbHandler->db()->truncateIsmMainStructureElement();
ismDbHandler->db()->truncateIsmStructureElement();
ismDbHandler->db()->truncateIsmStructureElementFootprint();
ismDbHandler->db()->truncateIsmMountingPointAsset();
ismDbHandler->db()->truncateIsmMountingPointSchedule();
ismDbHandler->db()->truncateIsmMountingPointPlan();
checkAliveTimer();
// insert new data
auto assetData = getDbDataVec<InfrastructureManagement::Database::IsmAsset>(IsmAsset);
ismDbHandler->db()->upsert(assetData);
auto mainStructureElement = getDbDataVec<InfrastructureManagement::Database::IsmMainStructureElement>(IsmMainStructureElement);
ismDbHandler->db()->upsert(mainStructureElement);
auto structureElementData = getDbDataVec<InfrastructureManagement::Database::IsmStructureElement>(IsmStructureElement);
ismDbHandler->db()->upsert(structureElementData);
auto structureElementFootprintData = getDbDataVec<InfrastructureManagement::Database::IsmStructureElementFootprint>(IsmStructureElementFootprint);
ismDbHandler->db()->upsert(structureElementFootprintData);
auto mountingPointAssetData = getDbDataVec<InfrastructureManagement::Database::IsmMountingPointAsset>(IsmMountingPointAsset);
ismDbHandler->db()->upsert(mountingPointAssetData);
auto specialAreaData = getDbDataVec<InfrastructureManagement::Database::IsmSpecialArea>(IsmSpecialArea);
ismDbHandler->db()->upsert(specialAreaData);
QSet<qint64> insertedSchedules;
for (auto schedule : getDbDataVec<InfrastructureManagement::Database::IsmMountingPointSchedule>(IsmMountingPointSchedule))
{
if (!schedule.exerciseId.isNull() && schedule.exerciseId.canConvert<int>())
{
if (schedule.exerciseId.toInt() == m_exerciseId)
{
ismDbHandler->db()->insert(schedule);
insertedSchedules.insert(schedule.id);
}
}
}
for (auto plan : getDbDataVec<InfrastructureManagement::Database::IsmMountingPointPlan>(IsmMountingPointPlan))
{
if (insertedSchedules.contains(plan.mountingPointScheduleId))
ismDbHandler->db()->upsert(plan);
}
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting ISM data into database."));
return;
}
stateFinished();
}
static inline void removePoolParty(std::vector<ParticipantManagement::Database::PpmParty> &partyData)
{
partyData.erase(std::remove_if(partyData.begin(),
partyData.end(),
[](const ParticipantManagement::Database::PpmParty & p) { return p.id == 0;}),
partyData.end());
}
void HandlerBaseDownload::replacePpmEx0DbData()
{
switchLog(InsertingPpmEx0Data, tr_lts("dds", "Inserting new participant management base data."));
auto ppmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<ParticipantManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<ParticipantManagement::DatabaseInterface>());
if (!ppmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise ppmDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
// clear old data
ppmDbHandler->db()->truncatePpmEquipmentType();
ppmDbHandler->db()->truncatePpmType();
ppmDbHandler->db()->truncatePpmParty();
checkAliveTimer();
// insert new data
auto equipmentTypeData = getDbDataVec<ParticipantManagement::Database::PpmEquipmentType>(PpmEquipmentType);
ppmDbHandler->db()->upsert(equipmentTypeData);
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "!!!!!Error while inserting PPM data for exercise 0 into database."));
return;
}
DBTransaction trans2(m_dbConnection);
auto typeData = getDbDataVec<ParticipantManagement::Database::PpmType>(PpmType);
// adding special type for flat structure (units)
ParticipantManagement::Database::PpmType newType;
// for all
newType.equipmentTypeId = QVariant();
// for the support party
newType.id = Settings::unitOffset();
newType.typeClassId = ParticipantManagement::TypeClass::SupportUnit;
newType.name = QStringLiteral("Type for flat unit structure: support");
typeData.push_back(newType);
//for the "rest"
newType.id = Settings::unitOffset() + 1;
newType.typeClassId = ParticipantManagement::TypeClass::Unit;
newType.name = QStringLiteral("Type for flat unit structure");
newType.symbol = QStringLiteral("M25D|CMPL|10011000131211000000");
newType.disEntities = LtsUtils::BigintArray::fromPgString(QStringLiteral("{4055234000000043055}")); // got from test-db
typeData.push_back(newType);
ppmDbHandler->db()->upsert(typeData);
if (!trans2.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "22222Error while inserting PPM data for exercise 0 into database."));
return;
}
DBTransaction trans3(m_dbConnection);
auto partyData = getDbDataVec<ParticipantManagement::Database::PpmParty>(PpmParty);
removePoolParty(partyData);
ppmDbHandler->db()->upsert(partyData);
if (!trans3.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "333Error while inserting PPM data for exercise 0 into database."));
return;
}
stateFinished();
}
void HandlerBaseDownload::insertPpmExNDbData(bool live)
{
if (!live)
switchLog(InsertingPpmExNData, tr_lts("dds", "Inserting new participants."));
auto ppmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<ParticipantManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<ParticipantManagement::DatabaseInterface>());
if (!ppmDbHandler->init(m_exerciseId, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise ppmDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
std::vector<ParticipantManagement::Database::PpmParticipant> participantData;
QMap<int, int> partyToUnit;
QHash<int, ParticipantManagement::TypeClass> m_type2TypeClass;
if (!live)
{
for (const auto &type : getDbDataVec<ParticipantManagement::Database::PpmType>(PpmType))
m_type2TypeClass[type.id] = type.typeClassId;
}
//we need to create parties now
// creating dummy unit for each party for a flat structure
ParticipantManagement::Database::PpmParticipant newEntry;
// adding Participants from dataVec
std::vector<ParticipantManagement::Database::PpmParticipant> newParticipants;
// unit default data
newEntry.hierarchyNumber = 1;
if (!live)
{
auto partyData = getDbDataVec<ParticipantManagement::Database::PpmParty>(PpmParty);
removePoolParty(partyData);
ppmDbHandler->db()->upsert(partyData);
#ifdef GUEZ_MODE
for (const auto &party : partyData)
{
if (party.id != 1)
{
// normal parties
newEntry.typeId = Settings::unitOffset() + 1; // typeId is created during InsertingPpmEx0Data
newEntry.symbol = QStringLiteral("M25D|CMPL|10031000131211000000");
}
else
{
// special for support
newEntry.typeId = Settings::unitOffset(); // typeId is created during InsertingPpmEx0Data
newEntry.symbol = QStringLiteral("M25D|CMPL|10214000001315060000");
}
newEntry.id = Settings::unitOffset() + party.id;
newEntry.partyId = party.id;
newEntry.name = QStringLiteral("Root unit for party: %1").arg(ParticipantManagement::trPartyName(party.name.toStdString()));
participantData.push_back(newEntry);
partyToUnit.insert(party.id, newEntry.id);
TRACE_LOG(m_logger) << "Adding: " << newEntry.name << " to participantData.";
}
// insert pseudo-units
ppmDbHandler->db()->upsert(participantData);
#endif
}
DEBUG_LOG(m_logger) << "Now add participants: " << getDbDataVec<ParticipantManagement::Database::PpmParticipant>(PpmParticipant).size();
for (const auto &participant : getDbDataVec<ParticipantManagement::Database::PpmParticipant>(PpmParticipant))
{
if (participant.partyId == 0)
continue; // no participants of party: pool
const auto typeClass = m_type2TypeClass.value(participant.typeId);
auto newParticipant = participant;
#ifdef GUEZ_MODE
if (typeClass == ParticipantManagement::TypeClass::Unit ||
typeClass == ParticipantManagement::TypeClass::SupportUnit)
continue;
newParticipant.superiorId = partyToUnit.value(participant.partyId);
newParticipant.hierarchyNumber = participant.id;
#endif
DEBUG_LOG(m_logger) << "XXXXXXXX Adding Participant: " << newParticipant.id << " typeId: " << newParticipant.typeId << " typeClass: " << typeClass << " supperioer " << newParticipant.superiorId;
newParticipants.push_back(std::move(newParticipant));
}
// insert modified participants
ppmDbHandler->db()->upsert(newParticipants);
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting new participants into database."));
return;
}
if (!live)
stateFinished();
}
void HandlerBaseDownload::replaceOpmDbData()
{
switchLog(InsertingOpmData, tr_lts("dds", "Inserting new operator management data."));
auto opmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<OperatorManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<OperatorManagement::DatabaseInterface>());
if (!opmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise opmDbHandler"));
return;
}
DBTransaction trans(m_dbConnection);
// clear old data
opmDbHandler->db()->truncateOpmGroup();
opmDbHandler->db()->truncateOpmGroupGroup();
opmDbHandler->db()->truncateOpmOperator();
opmDbHandler->db()->truncateOpmOperatorExercise();
opmDbHandler->db()->truncateOpmSettings();
opmDbHandler->db()->truncateOpmAccessControlLevel();
opmDbHandler->db()->truncateOpmAclAllow();
opmDbHandler->db()->truncateOpmAclDeny();
checkAliveTimer();
// insert new data
auto groupData = getDbDataVec<OperatorManagement::Database::OpmGroup>(OpmGroup);
opmDbHandler->db()->upsert(groupData);
auto groupGroupData = getDbDataVec<OperatorManagement::Database::OpmGroupGroup>(OpmGroupGroup);
opmDbHandler->db()->upsert(groupGroupData);
auto operatorData = getDbDataVec<OperatorManagement::Database::OpmOperator>(OpmOperator);
opmDbHandler->db()->upsert(operatorData);
checkAliveTimer();
// insert only OpmOperatorExercise with valid foreign key
for (auto opEx : getDbDataVec<OperatorManagement::Database::OpmOperatorExercise>(OpmOperatorExercise))
{
if (opEx.exerciseId == m_exerciseId)
opmDbHandler->db()->upsert(opEx);
}
auto settingsData = getDbDataVec<OperatorManagement::Database::OpmSettings>(OpmSettings);
opmDbHandler->db()->upsert(settingsData);
auto accessControlLevelData = getDbDataVec<OperatorManagement::Database::OpmAccessControlLevel>(OpmAccessControlLevel);
opmDbHandler->db()->upsert(accessControlLevelData);
auto aclAllowData = getDbDataVec<OperatorManagement::Database::OpmAclAllow>(OpmAclAllow);
opmDbHandler->db()->upsert(aclAllowData);
auto aclDenyData = getDbDataVec<OperatorManagement::Database::OpmAclDeny>(OpmAclDeny);
opmDbHandler->db()->upsert(aclDenyData);
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting OPM data into database."));
return;
}
stateFinished();
}
void HandlerBaseDownload::replaceFlmDbData()
{
switchLog(InsertingFlmData, tr_lts("dds", "Inserting new file management data."));
auto flmDbHandler = std::unique_ptr<NGLDB::DbServiceHandler<FileManagement::DatabaseInterface>>(new NGLDB::DbServiceHandler<FileManagement::DatabaseInterface>());
if (!flmDbHandler->init(0, m_dbConnection))
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Couldn't initialise flmDbHandler"));
return;
}
m_aliveTimer.start();
DBTransaction trans(m_dbConnection);
// clear old data
flmDbHandler->db()->truncateFlmFolder();
flmDbHandler->db()->truncateFlmFileContent();
checkAliveTimer();
// insert new data
auto folderData = getDbDataVec<FileManagement::Database::FlmFolder>(FlmFolder);
flmDbHandler->db()->upsert(folderData);
checkAliveTimer();
auto fileContentData = getDbDataVec<FileManagement::Database::FlmFileContent>(FlmFileContent);
flmDbHandler->db()->upsert(fileContentData);
if (!trans.commit())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while inserting FLM data into database."));
return;
}
stateFinished();
}
template<typename T>
inline void resetVector(QPair<bool, QVector<T>> &dbVector)
{
dbVector.first = false;
dbVector.second.clear();
}
void HandlerBaseDownload::cleanup(const Core::FtReplyState &replyState, const std::string &errStr)
{
if (errStr.size() > 0)
ERROR_LOG(m_logger) << "Base Download ended with error: " << errStr;
// cleanup db data
qDeleteAll(m_dataVecMap);
m_dataVecMap.clear();
// close db
m_exTblGen->close();
closeDb(m_dbConnection);
closeDb(m_remoteDbConnection);
// prepare reply
m_reply.errorString(errStr);
m_reply.replyState(replyState);
m_baseDownloadReplyUpdateTimer->stop();
m_fts->startBaseDownloadReply(m_baseDownloadCookie, m_reply);
m_currentState = NotStarted;
m_exerciseId = 0;
m_reply.progress(0);
m_reply.errorString(std::string());
m_reply.currentStep(std::string());
m_hostname = NGL::Connections::hostName(NGL::Connections::eConnection::SCM_WEBSOCKET);
}
void HandlerBaseDownload::retryCurrentSelect()
{
m_remoteDbRetryCounter++;
switchState();
}
void HandlerBaseDownload::copyFromOldDatabase()
{
switchLog(CopyDataRequest, tr_lts("dds", "Copying data from old to new database"));
bool bOk = false;
QSqlDatabase dbIn = openDb(currentDatabaseName(), false, &bOk);
if (!bOk)
{
// not nice but should not kill base download
stateFinished();
return;
}
// global schemas, one transaction for all
{
DBTransaction trans(m_dbConnection);
copyOldOpmData(dbIn, m_dbConnection);
checkAliveTimer();
copyOldFlmData(dbIn, m_dbConnection);
checkAliveTimer();
copyOldMsgData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
// exercise data, only if old ex_NN schema exists
const QString schemaName = QLatin1String("ex_") + QString::number(m_exerciseId);
if (m_exTblGen->existsSchema(schemaName, dbIn))
{
DEBUG_LOG(m_logger) << "### Copying old files from schema " << schemaName;
{
// own transaction when old ex_N schema does not exist.
DBTransaction trans(m_dbConnection);
copyOldMrkData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
{
// own transaction when old ex_N schema does not exist.
DBTransaction trans(m_dbConnection);
copyOldEvlData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
{
// own old orders when old ex_N schema does not exist.
DBTransaction trans(m_dbConnection);
copyOldEscData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
{
// own transaction when old ex_N schema does not exist.
DBTransaction trans(m_dbConnection);
copyOldFltData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
{
// Copy recording tables and some aes tables without DBInterface, own transaction
// alphabetically sorted
QStringList tableList;
// tableList << schemaName + QLatin1String(".aes_entity"); // this table has no DBInterface
// tableList << schemaName + QLatin1String(".aes_mine"); // this table has no DBInterface
// tableList << schemaName + QLatin1String(".aes_explosion"); // this table has no DBInterface
tableList << schemaName + QLatin1String(".rec_aes_filter");
tableList << schemaName + QLatin1String(".rec_aes_item_view");
tableList << schemaName + QLatin1String(".rec_b_c_contamination");
tableList << schemaName + QLatin1String(".rec_borderline");
tableList << schemaName + QLatin1String(".rec_charge_administration");
tableList << schemaName + QLatin1String(".rec_danger_area");
tableList << schemaName + QLatin1String(".rec_dus_mine_state");
tableList << schemaName + QLatin1String(".rec_dus_single_mine");
tableList << schemaName + QLatin1String(".rec_dus_single_mine_state");
tableList << schemaName + QLatin1String(".rec_dynamic_participant_data");
tableList << schemaName + QLatin1String(".rec_equipment_position"); // equipment_number negative ?
tableList << schemaName + QLatin1String(".rec_explosion_area");
tableList << schemaName + QLatin1String(".rec_explosion_single");
tableList << schemaName + QLatin1String(".rec_mine_area");
tableList << schemaName + QLatin1String(".rec_mine_corridor");
tableList << schemaName + QLatin1String(".rec_mine_triggered");
tableList << schemaName + QLatin1String(".rec_n_contamination");
tableList << schemaName + QLatin1String(".rec_participant");
tableList << schemaName + QLatin1String(".rec_participant_position");
tableList << schemaName + QLatin1String(".rec_party");
tableList << schemaName + QLatin1String(".rec_snapshot"); // not sure we need this, we have data in ex_NN.mrk_snapshot
tableList << schemaName + QLatin1String(".rec_symbol_appearance");
tableList << schemaName + QLatin1String(".rec_triggered_impacts");
//tableList << schemaName + QLatin1String(".rec_bridge_status");
//TODO: add more tables if needed, check data in these tables, z.B. in rec_equipment_position.equipment_number is always negative (?!)
DBTransaction trans(m_dbConnection);
for (const QString &table : qAsConst(tableList))
{
if (!copyTable(dbIn, m_dbConnection, table))
ERROR_LOG(m_logger) << "Failed to copy table " << table;
checkAliveTimer();
}
trans.commit();
}
{
// own transaction when old ex_N schema does not exist.
DBTransaction trans(m_dbConnection);
copyOldAesData(dbIn, m_dbConnection);
checkAliveTimer();
trans.commit();
}
}
closeDb(dbIn);
stateFinished();
}
void HandlerBaseDownload::copyOldOpmData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace OperatorManagement;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(0, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(0, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::OpmSettings> opmSettings;
dbIfcOld->select(opmSettings);
dbIfcNew->truncateOpmSettings();
for (Database::OpmSettings &s : opmSettings)
{
s.id = 0;
dbIfcNew->insert(s);
}
dbIfcNew->fixUpSequenceOpmSettings();
}
void HandlerBaseDownload::copyOldEvlData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace Evaluations;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(m_exerciseId, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(m_exerciseId, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::EvlComment> evlComment;
QVector<Database::EvlCriterium> evlCriterium;
QVector<Database::EvlElement> evlElement;
QVector<Database::EvlSchema> evlSchema;
dbIfcOld->select(evlComment);
dbIfcOld->select(evlCriterium);
dbIfcOld->select(evlElement);
dbIfcOld->select(evlSchema);
dbIfcNew->truncateEvlComment();
dbIfcNew->truncateEvlCriterium();
dbIfcNew->truncateEvlElement();
dbIfcNew->truncateEvlSchema();
// schema and criterium first
for (Database::EvlSchema &s : evlSchema)
dbIfcNew->insert(s);
for (Database::EvlCriterium &s : evlCriterium)
dbIfcNew->insert(s);
for (Database::EvlElement &s : evlElement)
dbIfcNew->insert(s);
for (Database::EvlComment &s : evlComment)
dbIfcNew->insert(s);
dbIfcNew->fixUpSequenceEvlComment();
dbIfcNew->fixUpSequenceEvlCriterium();
dbIfcNew->fixUpSequenceEvlElement();
dbIfcNew->fixUpSequenceEvlSchema();
}
void HandlerBaseDownload::copyOldMsgData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace Messaging;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(0, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(0, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::MsgMessageData> msgData;
dbIfcOld->select(msgData);
dbIfcNew->truncateMsgMessageData();
for (Database::MsgMessageData &m : msgData)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceMsgMessageData();
}
void HandlerBaseDownload::copyOldFlmData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace FileManagement;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(0, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(0, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::FlmFileContent> flmData;
dbIfcOld->select(flmData);
//dbIfcNew->truncateFlmFileContent();
std::vector<Database::FlmFileContent> flmDataToCopy;
QVector<Database::FlmFolder> flmFolderData;
dbIfcNew->select(flmFolderData);
qint64 folderId = -1;
for (const auto &folder : qAsConst(flmFolderData))
{
if (folder.name == QStringLiteral("Snapshots"))
{
folderId = folder.id;
Database::FlmFolder parentFolder;
dbIfcNew->selectFlmFolder(folder.parentId, parentFolder);
if (parentFolder.name == QLatin1String("$EX_") + QString::number(m_exerciseId))
break;
}
}
// There is a folder "Snapshots" for each exercise, getting the "right" one is done using flm dtc custom function getFolderId(folderName, exerciseId)
// or this database select parentId when flm dtc is not available
if (folderId > 0) // found Snapshots folder for the exercise id
{
for (auto data : qAsConst(flmData))
{
if (data.folderId == folderId || //snapshots
(data.fileTypeId.underlying() == FileManagement::FileType::Pdf)) //old PDF
{
data.id = 0;
flmDataToCopy.push_back(data);
}
}
}
dbIfcNew->insert(flmDataToCopy);
dbIfcNew->fixUpSequenceFlmFileContent();
}
void HandlerBaseDownload::copyOldMrkData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace MarkerManagement;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(m_exerciseId, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(m_exerciseId, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
// no longer save snapshot , copy flm instead ?
QVector<Database::MrkSnapshot> snaData;
dbIfcOld->select(snaData);
dbIfcNew->truncateMrkSnapshot();
for (Database::MrkSnapshot &m : snaData)
dbIfcNew->insert(m);
QVector<Database::MrkMarker> mrkData;
dbIfcOld->select(mrkData);
dbIfcNew->truncateMrkMarker();
for (Database::MrkMarker &m : mrkData)
dbIfcNew->insert(m);
QVector<Database::MrkMarkerDescription> mrkDatad;
dbIfcOld->select(mrkDatad);
dbIfcNew->truncateMrkMarkerDescription();
for (Database::MrkMarkerDescription &m : mrkDatad)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceMrkMarker();
dbIfcNew->fixUpSequenceMrkMarkerDescription();
dbIfcNew->fixUpSequenceMrkSnapshot();
}
void HandlerBaseDownload::copyOldEscData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace EffectShowClient;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(m_exerciseId, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(m_exerciseId, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::EscOrder> orderData;
dbIfcOld->select(orderData);
dbIfcNew->truncateEscOrder();
for (Database::EscOrder &m : orderData)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceEscOrder();
}
void HandlerBaseDownload::copyOldFltData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
using namespace FilterManagement;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(m_exerciseId, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(m_exerciseId, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::AesFilter> fltData;
dbIfcOld->select(fltData);
dbIfcNew->truncateAesFilter();
for (Database::AesFilter &m : fltData)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesFilter();
QVector<Database::SymbolAppearance> symData;
dbIfcOld->select(symData);
dbIfcNew->truncateSymbolAppearance();
for (Database::SymbolAppearance &m : symData)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceSymbolAppearance();
}
void HandlerBaseDownload::copyOldAesData(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut) const
{
//WE NEED FURTHER TESTING!!!!!
return;
using namespace AreaEffectSimulation;
auto dbOld = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbOld->init(m_exerciseId, dbIn))
return;
auto dbNew = std::unique_ptr<NGLDB::DbServiceHandler<DatabaseInterface>>(new NGLDB::DbServiceHandler<DatabaseInterface>());
if (!dbNew->init(m_exerciseId, dbOut))
return;
auto dbIfcOld = dbOld->db();
auto dbIfcNew = dbNew->db();
QVector<Database::AesAirSupportImpact> asi;
dbIfcOld->select(asi);
dbIfcNew->truncateAesAirSupportImpact();
for (Database::AesAirSupportImpact &m : asi)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesAirSupportImpact();
QVector<Database::AesBCContamination> bc;
dbIfcOld->select(bc);
dbIfcNew->truncateAesBCContamination();
for (Database::AesBCContamination &m : bc)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesBCContamination();
QVector<Database::AesBorderline> b;
dbIfcOld->select(b);
dbIfcNew->truncateAesBorderline();
for (Database::AesBorderline &m : b)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesBorderline();
QVector<Database::AesBorderlineSegment> bs;
dbIfcOld->select(bs);
dbIfcNew->truncateAesBorderlineSegment();
for (Database::AesBorderlineSegment &m : bs)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesBorderlineSegment();
QVector<Database::AesDusSingleMine> dsm;
dbIfcOld->select(dsm);
dbIfcNew->truncateAesDusSingleMine();
for (Database::AesDusSingleMine &m : dsm)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesDusSingleMine();
QVector<Database::AesDangerArea> da;
dbIfcOld->select(da);
dbIfcNew->truncateAesDangerArea();
for (Database::AesDangerArea &m : da)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesDangerArea();
QVector<Database::AesDangerSegment> ds;
dbIfcOld->select(ds);
dbIfcNew->truncateAesDangerSegment();
for (Database::AesDangerSegment &m : ds)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesDangerSegment();
QVector<Database::AesMineArea> ma;
dbIfcOld->select(ma);
dbIfcNew->truncateAesMineArea();
for (Database::AesMineArea &m : ma)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesMineArea();
QVector<Database::AesMineAreaSegment> mas;
dbIfcOld->select(mas);
dbIfcNew->truncateAesMineAreaSegment();
for (Database::AesMineAreaSegment &m : mas)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesMineAreaSegment();
QVector<Database::AesMineAreaTriggeredMines> matm;
dbIfcOld->select(matm);
dbIfcNew->truncateAesMineAreaTriggeredMines();
for (Database::AesMineAreaTriggeredMines &m : matm)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesMineAreaTriggeredMines();
QVector<Database::AesMineCorridor> mc;
dbIfcOld->select(mc);
dbIfcNew->truncateAesMineCorridor();
for (Database::AesMineCorridor &m : mc)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesMineCorridor();
QVector<Database::AesMineCorridorSegment> mcs;
dbIfcOld->select(mcs);
dbIfcNew->truncateAesMineCorridorSegment();
for (Database::AesMineCorridorSegment &m : mcs)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesMineCorridorSegment();
QVector<Database::AesGasPipe> gp;
dbIfcOld->select(gp);
dbIfcNew->truncateAesGasPipe();
for (Database::AesGasPipe &m : gp)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesGasPipe();
QVector<Database::AesGasPipeSegment> gps;
dbIfcOld->select(gps);
dbIfcNew->truncateAesGasPipeSegment();
for (Database::AesGasPipeSegment &m : gps)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesGasPipeSegment();
QVector<Database::AesNContamination> n;
dbIfcOld->select(n);
dbIfcNew->truncateAesNContamination();
for (Database::AesNContamination &m : n)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesNContamination();
QVector<Database::AesExplosionArea> ea;
dbIfcOld->select(ea);
dbIfcNew->truncateAesExplosionArea();
for (Database::AesExplosionArea &m : ea)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesExplosionArea();
QVector<Database::AesExplosionSingle> es;
dbIfcOld->select(es);
dbIfcNew->truncateAesExplosionSingle();
for (Database::AesExplosionSingle &m : es)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesExplosionSingle();
QVector<Database::AesChargeAdministration> ca;
dbIfcOld->select(ca);
dbIfcNew->truncateAesChargeAdministration();
for (Database::AesChargeAdministration &m : ca)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesChargeAdministration();
QVector<Database::AesFunctionalArea> fa;
dbIfcOld->select(fa);
dbIfcNew->truncateAesFunctionalArea();
for (Database::AesFunctionalArea &m : fa)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesFunctionalArea();
QVector<Database::AesReconArea> ra;
dbIfcOld->select(ra);
dbIfcNew->truncateAesReconArea();
for (Database::AesReconArea &m : ra)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesReconArea();
QVector<Database::AesTechnicalArea> ta;
dbIfcOld->select(ta);
dbIfcNew->truncateAesTechnicalArea();
for (Database::AesTechnicalArea &m : ta)
dbIfcNew->insert(m);
dbIfcNew->fixUpSequenceAesTechnicalArea();
}
void HandlerBaseDownload::updateLtsConfig()
{
switchLog(UpdatingLtsConfig, tr_lts("dds", "Updating local configuration file and restarting services"));
const QString conf = NGL::findProjectConfigFile();
if (conf.isEmpty())
{
cleanup(Core::FtReplyState::Error, tr_lts("dds", "Error while updating local configuration file."));
return;
}
{
QSettings s(conf, QSettings::IniFormat);
s.setValue(QStringLiteral("Global") + QStringLiteral("/DatabaseName"), nextDatabaseName());
}
m_stopGroupIds.clear();
ServiceManagement::GroupRequest request;
const QMap<int32_t, ServiceManagement::GroupInformation> groups = m_scmDtc->groupInformations();
for (const auto &group : groups)
{
if (group.type() == Core::ServiceGroupType::Master ||
group.type() == Core::ServiceGroupType::Core)
continue;
request.type(group.type());
request.domainId(group.domainId());
request.exercisePartitionId(group.exercisePartitionId());
request.replayPartitionId(group.replayPartitionId());
request.requestId(group.id());
m_stopGroupIds += group.id();
m_scmFtc->stopGroupRequest(request, this);
}
if (m_stopGroupIds.isEmpty())
restartCoreGroup();
else
QTimer::singleShot(30 * 1000, this, &HandlerBaseDownload::restartCoreGroup); // don't wait longer than 30s for the stop replies
}
void HandlerBaseDownload::onStopGroupReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
{
cleanup(Core::FtReplyState::Error, reply.str());
return;
}
if (!m_stopGroupIds.remove(reply.id()))
WARNING_LOG(m_logger) << "Got unknown reply id for stop group request: " << reply.id();
if (!m_stopGroupIds.isEmpty())
return;
restartCoreGroup();
}
void HandlerBaseDownload::restartCoreGroup()
{
// now restart CORE (which restarts EXM and therefore also starts the exercise specific services)
ServiceManagement::GroupRequest request;
const QMap<int32_t, ServiceManagement::GroupInformation> groups = m_scmDtc->groupInformations();
for (const auto &group : groups)
{
if (group.type() != Core::ServiceGroupType::Core)
continue;
request.type(group.type());
request.domainId(group.domainId());
request.exercisePartitionId(group.exercisePartitionId());
request.replayPartitionId(group.replayPartitionId());
request.requestId(group.id());
break; // only one core
}
// we are also restarted... so answer here directly with 'finished'
stateFinished();
if (request.type() != Core::ServiceGroupType::Core)
WARNING_LOG(m_logger) << "Could not find core group to restart...";
const auto restartCb = [this, request]()
{
m_scmFtc->restartGroupRequest(request, this);
};
QTimer::singleShot(5000, this, restartCb);
}
void HandlerBaseDownload::onRestartGroupReply(const Core::FunctionReplyObject &reply)
{
if (reply.error())
{
cleanup(Core::FtReplyState::Error, reply.str());
return;
}
// we won't get here since we're restarted too
ERROR_LOG(m_logger) << "onRestartGroupReply?";
stateFinished();
}
QString HandlerBaseDownload::currentDatabaseName() const
{
auto s = Settings::settings();
return s->databaseName();
}
QString HandlerBaseDownload::nextDatabaseName() const
{
const QString dbName = currentDatabaseName();
int idx = dbName.lastIndexOf(QLatin1Char('_'));
bool bOk;
int id = dbName.midRef(idx + 1).toInt(&bOk) + 1;
return bOk ? QString(dbName.left(idx + 1) + QString::number(id))
: QString(dbName + QLatin1Char('_') + QString::number(id));
}
void HandlerBaseDownload::checkAliveTimer()
{
if (m_aliveTimer.elapsed() > 2000) // longer than 2 sec -> send heartbeat
{
m_mainHandler->dds()->pacemaker()->publishState();
updateBaseDownloadReply();
m_aliveTimer.start();
}
}
bool HandlerBaseDownload::copyTable(const QSqlDatabase &dbIn, const QSqlDatabase &dbOut, QString tableName)
{
NSqlQuery qIn(dbIn);
NSqlQuery qOut(dbOut);
DEBUG_LOG(m_logger) << "Copying " << tableName << " started";
const QSqlRecord record = dbIn.record(tableName);
if (record.isEmpty())
{
ERROR_LOG(m_logger) << "Empty record for " << tableName;
return false;
}
QStringList selectTableColumns;
QStringList insertTablePlaceholder;
selectTableColumns.reserve(record.count());
insertTablePlaceholder.reserve(record.count());
for (int i = 0; i < record.count(); ++i)
{
const QSqlField &f = record.field(i);
selectTableColumns += f.name();
insertTablePlaceholder += QLatin1Char(':') + f.name();
}
const QString selectTableCommand(QStringLiteral("SELECT %1 FROM %2")
.arg(selectTableColumns.join(QStringLiteral(", ")), tableName));
const QString insertTableCommand(QStringLiteral("INSERT INTO %1 (%2) VALUES (%3)")
.arg(tableName,
selectTableColumns.join(QStringLiteral(", ")),
insertTablePlaceholder.join(QStringLiteral(", "))));
DEBUG_LOG(m_logger) << selectTableCommand;
DEBUG_LOG(m_logger) << insertTableCommand;
if (!qOut.prepare(insertTableCommand))
{
ERROR_LOG(m_logger) << "qOut prepare failed... " << qOut.lastError().text();
return false;
}
if (!qIn.exec(selectTableCommand))
{
ERROR_LOG(m_logger) << "qIn select failed... " << qIn.lastError().text();
DEBUG_LOG(m_logger) << "FAILED statement: " << selectTableCommand;
qIn.finish();
return false;
}
while (qIn.next())
{
for (int i = 0; i < insertTablePlaceholder.size(); ++i)
qOut.bindValue(insertTablePlaceholder.at(i), qIn.value(i));
if (!qOut.exec())
{
ERROR_LOG(m_logger) << "qOut insert failed.. " << qOut.lastError().text();
DEBUG_LOG(m_logger) << "FAILED statement: " << insertTableCommand;
qOut.finish();
return false;
}
checkAliveTimer();
}
DEBUG_LOG(m_logger) << "Copying " << tableName << " finished";
if (!fixUpSequence(dbOut, tableName))
WARNING_LOG(m_logger) << "Failed to update sequence for table " << tableName;
return true;
}
bool HandlerBaseDownload::fixUpSequence(const QSqlDatabase &dbOut, const QString &tableName)
{
NSqlQuery qOut(dbOut);
QString seqName, keyField;
if (tableName.contains(QStringLiteral(".rec_")) && !tableName.contains(QStringLiteral(".rec_snapshot")))
{
seqName = tableName + QStringLiteral("_rec_id_seq");
keyField = QStringLiteral("rec_id");
}
else
{
seqName = tableName + QStringLiteral("_id_seq");
keyField = QStringLiteral("id");
}
DEBUG_LOG(m_logger) << "Updating sequence " << seqName << " for table " << tableName;
const QString stmt(QStringLiteral("SELECT setval('%1', COALESCE((SELECT MAX(%2)+1 FROM %3), 1), false)").arg(seqName, keyField, tableName));
if (!qOut.exec(stmt))
{
ERROR_LOG(m_logger) << "FAILED to update sequence for table " << tableName << " : " << qOut.lastError().text();
DEBUG_LOG(m_logger) << "FAILED statement: " << stmt;
qOut.finish();
return false;
}
return true;
}
} // namespace OcBaseDownload