/** * @RDE_HEADER@ * Template for 'real' structures including insert/update/delete functions for db * $Id$ * $HeadURL$ * $Author$ */ // filename: tab_db_impl.cpp #include "tab_db_impl.h" #include #include #include #include #include #include #include namespace TrainingAreaBase { QString qVariantToJsonString(const QVariant &value) { return value.isNull() ? QStringLiteral("{}") : value.toString(); } QString fixupEmptyJsonString(const QString &str) { return str.isEmpty() ? QStringLiteral("{}") : str; } // DatabaseInterface std::shared_ptr DatabaseInterface::create(int exerciseId) { return std::make_shared(exerciseId); } DatabaseInterfaceImpl::DatabaseInterfaceImpl(int exerciseId) : m_query(nullptr) , m_exerciseId(exerciseId) , m_bEmitMessageOnError(true) , m_bCanHandleSchemas(true) , m_ownDatabaseConnection(true) , m_logger(getLogger("Db")) {} DatabaseInterfaceImpl::~DatabaseInterfaceImpl() { m_query = nullptr; if (m_ownDatabaseConnection && m_dbConnection.isOpen()) m_dbConnection.close(); } bool DatabaseInterfaceImpl::init(const QSqlDatabase &dbConnection) { m_dbConnection = dbConnection; m_ownDatabaseConnection = false; return initInternal(); } bool DatabaseInterfaceImpl::init(const QString &dbUser, const QString &dbPasswd, const QString &dbDriver, const QString &dbHost, const QString &dbName) { m_ownDatabaseConnection = true; m_dbConnection = DBConnection::open(m_logger, dbUser, dbPasswd, dbDriver, dbHost, dbName, schemaName()); return initInternal(); } bool DatabaseInterfaceImpl::initInternal() { QSqlDriver *driver = m_dbConnection.driver(); if (!driver) { WARNING_LOG(m_logger) << "No SQL driver loaded - no database available!"; return false; } const QString driverName = m_dbConnection.driverName(); DEBUG_LOG(m_logger) << "Connected to database " << m_dbConnection.databaseName() << "@" << m_dbConnection.hostName() << ", schema: " << schemaName() << ", used driver: " << driverName; if (!m_dbConnection.isOpen()) { WARNING_LOG(m_logger) << "Database connection is no open - can not initialize database interface"; return false; } if (driverName == QLatin1String("QSQLITE")) m_bCanHandleSchemas = false; m_query = std::unique_ptr(new NSqlQuery(m_dbConnection, m_logger)); return true; } QString DatabaseInterfaceImpl::schemaName() const { if (!m_bCanHandleSchemas) return QString(); if (m_exerciseId <= 0) return QStringLiteral("tab"); return DBCommon::getExerciseSchemaName(m_exerciseId); } QString DatabaseInterfaceImpl::dbUser() const { if (m_exerciseId > 0) return QStringLiteral("ets_ex_00"); else return QStringLiteral("ets_") + schemaName(); } void DatabaseInterfaceImpl::setEmitMessageOnError(bool bEmit) { m_bEmitMessageOnError = bEmit; } QString DatabaseInterfaceImpl::getTableName(const QString &tableName) const { if (!m_bCanHandleSchemas) return tableName; if (m_exerciseId > 0) return DBCommon::getExerciseTableName(tableName, m_exerciseId); return QStringLiteral("tab.") + tableName; } QSqlError DatabaseInterfaceImpl::getLastError() const { return m_lastError; } // // Struct: Database::AesId2TaId // bool DatabaseInterfaceImpl::insert(Database::AesId2TaId &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = data.aesTetraId != 0; if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("aes_tetra_id, "); keyColumnInsertVal = QStringLiteral(" :aes_tetra_id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" aes_dds_id, exercise_id, is_available_in_tetra" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":aes_dds_id, :exercise_id, :is_available_in_tetra )")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.aesTetraId == 0) data.aesTetraId = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::upsert(Database::AesId2TaId &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :aes_tetra_id, "); keyColumnInsertKey = QStringLiteral("aes_tetra_id, "); keyColumnInsertKeyConflict = QStringLiteral("aes_tetra_id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" aes_dds_id, exercise_id, is_available_in_tetra" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":aes_dds_id, :exercise_id, :is_available_in_tetra )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " aes_dds_id = :aes_dds_id, exercise_id = :exercise_id, is_available_in_tetra = :is_available_in_tetra" " WHERE excluded.aes_tetra_id = :aes_tetra_id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.aesTetraId == 0) data.aesTetraId = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::update(const Database::AesId2TaId &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " aes_dds_id = :aes_dds_id, exercise_id = :exercise_id, is_available_in_tetra = :is_available_in_tetra" " WHERE aes_tetra_id = :aes_tetra_id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::insert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = cont[0].aesTetraId != 0; // the first element determines the stmt to be used if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("aes_tetra_id, "); keyColumnInsertVal = QStringLiteral(" :aes_tetra_id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" aes_dds_id, exercise_id, is_available_in_tetra" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":aes_dds_id, :exercise_id, :is_available_in_tetra )")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.aesTetraId == 0) data.aesTetraId = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequenceAesId2TaId(); } return true; } bool DatabaseInterfaceImpl::upsert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :aes_tetra_id, "); keyColumnInsertKey = QStringLiteral("aes_tetra_id, "); // the first element determines the stmt to be used keyColumnInsertKeyConflict = QStringLiteral("aes_tetra_id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" aes_dds_id, exercise_id, is_available_in_tetra" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":aes_dds_id, :exercise_id, :is_available_in_tetra )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " aes_dds_id = :aes_dds_id, exercise_id = :exercise_id, is_available_in_tetra = :is_available_in_tetra" " WHERE excluded.aes_tetra_id = :aes_tetra_id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.aesTetraId == 0) data.aesTetraId = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequenceAesId2TaId(); } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::update(const std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " aes_dds_id = :aes_dds_id, exercise_id = :exercise_id, is_available_in_tetra = :is_available_in_tetra" " WHERE aes_tetra_id = :aes_tetra_id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (const auto &data : cont) { m_query->bindValue(QStringLiteral(":aes_dds_id"), data.aesDdsId); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":is_available_in_tetra"), data.isAvailableInTetra); m_query->bindValue(QStringLiteral(":aes_tetra_id"), data.aesTetraId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::select(QVector &dataVec) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::AesId2TaId &data) { dataVec.push_back(data); }; return selectPrepareInternalAesId2TaId(QString()) && selectFetchInternalAesId2TaId(cb); } bool DatabaseInterfaceImpl::select(const std::function &cb) { SqlQueryJanitor janitor(m_query); return selectPrepareInternalAesId2TaId(QString()) && selectFetchInternalAesId2TaId(cb); } bool DatabaseInterfaceImpl::selectByExerciseId(QVector &dataVec, const qint32 &exerciseId, const QString &orderBy) { SqlQueryJanitor janitor(m_query); if (!selectPrepareInternalAesId2TaId(QStringLiteral(" WHERE exercise_id = :exercise_id") + orderBy)) { ERROR_LOG(m_logger) << "Error preparing query: " << m_query->lastError().text(); m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":exercise_id"), exerciseId); const auto cb =[&dataVec] (const Database::AesId2TaId &data) { dataVec.push_back(data); }; return selectFetchInternalAesId2TaId(cb); } bool DatabaseInterfaceImpl::selectByExerciseId(const std::function &cb, const qint32 &exerciseId, const QString &orderBy) { SqlQueryJanitor janitor(m_query); if (!selectPrepareInternalAesId2TaId(QStringLiteral(" WHERE exercise_id = :exercise_id") + orderBy)) { ERROR_LOG(m_logger) << "Error preparing query: " << m_query->lastError().text(); m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":exercise_id"), exerciseId); return selectFetchInternalAesId2TaId(cb); } bool DatabaseInterfaceImpl::selectPrepareInternalAesId2TaId(const QString &where) { const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("SELECT aes_tetra_id, aes_dds_id, exercise_id, is_available_in_tetra" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool DatabaseInterfaceImpl::selectFetchInternalAesId2TaId(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::AesId2TaId data; while (m_query->next()) { int i = 0; data.aesTetraId = m_query->value(i++).toInt(); data.aesDdsId = m_query->value(i++).toInt(); data.exerciseId = m_query->value(i++).toInt(); data.isAvailableInTetra = m_query->value(i++).toBool(); cb(data); } return true; } bool DatabaseInterfaceImpl::selectAesId2TaId(qint32 aesTetraId, Database::AesId2TaId &data) { SqlQueryJanitor janitor(m_query); int iCnt = 0; const auto cb =[&data, &iCnt] (const Database::AesId2TaId &content) { data = content; ++iCnt; }; const QString where = QStringLiteral(" WHERE aes_tetra_id = %1").arg(aesTetraId); if (!selectPrepareInternalAesId2TaId(where) || !selectFetchInternalAesId2TaId(cb)) return false; return (iCnt == 1); } bool DatabaseInterfaceImpl::removeAesId2TaId(qint32 aesTetraId) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE aes_tetra_id = ") + QString::number(aesTetraId)); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::removeAesId2TaIdByExerciseId(const qint32 &exerciseId) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE exercise_id = :exerciseId")); if (!m_query->prepare(stmt)) { ERROR_LOG(m_logger) << "Error preparing query: " << m_query->lastError().text(); m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":exerciseId"), exerciseId); return m_query->exec(m_bEmitMessageOnError); } bool DatabaseInterfaceImpl::fixUpSequenceAesId2TaId() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("SELECT setval('") + tableName + QStringLiteral("_aes_tetra_id_seq', COALESCE((SELECT MAX(aes_tetra_id)+1 FROM ") + tableName + QStringLiteral("), 1),false)")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::truncateAesId2TaId() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("aes_id_2_ta_id"))); const QString stmt(QStringLiteral("TRUNCATE TABLE ") + tableName + QStringLiteral(" CASCADE")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } // Database::AesId2TaId end // // Struct: Database::PrtCnvMember // bool DatabaseInterfaceImpl::insert(Database::PrtCnvMember &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = data.id != 0; if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" issi, licensed, claims, exercise_id" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":issi, :licensed, :claims, :exercise_id )")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::upsert(Database::PrtCnvMember &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" issi, licensed, claims, exercise_id" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":issi, :licensed, :claims, :exercise_id )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " issi = :issi, licensed = :licensed, claims = :claims, exercise_id = :exercise_id" " WHERE excluded.id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::update(const Database::PrtCnvMember &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " issi = :issi, licensed = :licensed, claims = :claims, exercise_id = :exercise_id" " WHERE id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::insert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = cont[0].id != 0; // the first element determines the stmt to be used if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" issi, licensed, claims, exercise_id" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":issi, :licensed, :claims, :exercise_id )")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvMember(); } return true; } bool DatabaseInterfaceImpl::upsert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); // the first element determines the stmt to be used keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" issi, licensed, claims, exercise_id" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":issi, :licensed, :claims, :exercise_id )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " issi = :issi, licensed = :licensed, claims = :claims, exercise_id = :exercise_id" " WHERE excluded.id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvMember(); } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::update(const std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " issi = :issi, licensed = :licensed, claims = :claims, exercise_id = :exercise_id" " WHERE id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (const auto &data : cont) { m_query->bindValue(QStringLiteral(":issi"), data.issi); m_query->bindValue(QStringLiteral(":licensed"), data.licensed); m_query->bindValue(QStringLiteral(":claims"), data.claims); m_query->bindValue(QStringLiteral(":exercise_id"), data.exerciseId); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::select(QVector &dataVec) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::PrtCnvMember &data) { dataVec.push_back(data); }; return selectPrepareInternalPrtCnvMember(QString()) && selectFetchInternalPrtCnvMember(cb); } bool DatabaseInterfaceImpl::select(const std::function &cb) { SqlQueryJanitor janitor(m_query); return selectPrepareInternalPrtCnvMember(QString()) && selectFetchInternalPrtCnvMember(cb); } bool DatabaseInterfaceImpl::selectPrepareInternalPrtCnvMember(const QString &where) { const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("SELECT id, issi, licensed, claims, exercise_id" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool DatabaseInterfaceImpl::selectFetchInternalPrtCnvMember(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::PrtCnvMember data; while (m_query->next()) { int i = 0; data.id = m_query->value(i++).toInt(); data.issi = m_query->value(i++).toInt(); data.licensed = m_query->value(i++).toInt(); data.claims = m_query->value(i++).toInt(); data.exerciseId = m_query->value(i++).toInt(); cb(data); } return true; } bool DatabaseInterfaceImpl::selectPrtCnvMember(qint32 id, Database::PrtCnvMember &data) { SqlQueryJanitor janitor(m_query); int iCnt = 0; const auto cb =[&data, &iCnt] (const Database::PrtCnvMember &content) { data = content; ++iCnt; }; const QString where = QStringLiteral(" WHERE id = %1").arg(id); if (!selectPrepareInternalPrtCnvMember(where) || !selectFetchInternalPrtCnvMember(cb)) return false; return (iCnt == 1); } bool DatabaseInterfaceImpl::removePrtCnvMember(qint32 id) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE id = ") + QString::number(id)); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::fixUpSequencePrtCnvMember() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("SELECT setval('") + tableName + QStringLiteral("_id_seq', COALESCE((SELECT MAX(id)+1 FROM ") + tableName + QStringLiteral("), 1),false)")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::truncatePrtCnvMember() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_member"))); const QString stmt(QStringLiteral("TRUNCATE TABLE ") + tableName + QStringLiteral(" CASCADE")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } // Database::PrtCnvMember end // // Struct: Database::PrtCnvStatus // bool DatabaseInterfaceImpl::insert(Database::PrtCnvStatus &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" id, reset_counter, ctas_operating_state, machine_state" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":id, :reset_counter, :ctas_operating_state, :machine_state )")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } bool DatabaseInterfaceImpl::upsert(Database::PrtCnvStatus &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" id, reset_counter, ctas_operating_state, machine_state" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":id, :reset_counter, :ctas_operating_state, :machine_state )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " id = :id, reset_counter = :reset_counter, ctas_operating_state = :ctas_operating_state, machine_state = :machine_state" " WHERE excluded.id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } bool DatabaseInterfaceImpl::update(const Database::PrtCnvStatus &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " id = :id, reset_counter = :reset_counter, ctas_operating_state = :ctas_operating_state, machine_state = :machine_state" " WHERE id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::insert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" id, reset_counter, ctas_operating_state, machine_state" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":id, :reset_counter, :ctas_operating_state, :machine_state )")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::upsert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; // the first element determines the stmt to be used keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" id, reset_counter, ctas_operating_state, machine_state" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":id, :reset_counter, :ctas_operating_state, :machine_state )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " id = :id, reset_counter = :reset_counter, ctas_operating_state = :ctas_operating_state, machine_state = :machine_state" " WHERE excluded.id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::update(const std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " id = :id, reset_counter = :reset_counter, ctas_operating_state = :ctas_operating_state, machine_state = :machine_state" " WHERE id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (const auto &data : cont) { m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":ctas_operating_state"), data.ctasOperatingState); m_query->bindValue(QStringLiteral(":machine_state"), data.machineState); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::select(QVector &dataVec) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::PrtCnvStatus &data) { dataVec.push_back(data); }; return selectPrepareInternalPrtCnvStatus(QString()) && selectFetchInternalPrtCnvStatus(cb); } bool DatabaseInterfaceImpl::select(const std::function &cb) { SqlQueryJanitor janitor(m_query); return selectPrepareInternalPrtCnvStatus(QString()) && selectFetchInternalPrtCnvStatus(cb); } bool DatabaseInterfaceImpl::selectPrepareInternalPrtCnvStatus(const QString &where) { const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("SELECT id, reset_counter, ctas_operating_state, machine_state" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool DatabaseInterfaceImpl::selectFetchInternalPrtCnvStatus(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::PrtCnvStatus data; while (m_query->next()) { int i = 0; data.id = m_query->value(i++).toInt(); data.resetCounter = m_query->value(i++).toInt(); data.ctasOperatingState = m_query->value(i++).toInt(); data.machineState = m_query->value(i++).toInt(); cb(data); } return true; } bool DatabaseInterfaceImpl::selectPrtCnvStatus(qint32 id, Database::PrtCnvStatus &data) { SqlQueryJanitor janitor(m_query); int iCnt = 0; const auto cb =[&data, &iCnt] (const Database::PrtCnvStatus &content) { data = content; ++iCnt; }; const QString where = QStringLiteral(" WHERE id = %1").arg(id); if (!selectPrepareInternalPrtCnvStatus(where) || !selectFetchInternalPrtCnvStatus(cb)) return false; return (iCnt == 1); } bool DatabaseInterfaceImpl::removePrtCnvStatus(qint32 id) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE id = ") + QString::number(id)); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::fixUpSequencePrtCnvStatus() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("SELECT setval('") + tableName + QStringLiteral("_id_seq', COALESCE((SELECT MAX(id)+1 FROM ") + tableName + QStringLiteral("), 1),false)")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::truncatePrtCnvStatus() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_status"))); const QString stmt(QStringLiteral("TRUNCATE TABLE ") + tableName + QStringLiteral(" CASCADE")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } // Database::PrtCnvStatus end // // Struct: Database::PrtCnvToCentral // bool DatabaseInterfaceImpl::insert(Database::PrtCnvToCentral &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = data.id != 0; if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :data )")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::upsert(Database::PrtCnvToCentral &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :data )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, data = :data" " WHERE excluded.id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::update(const Database::PrtCnvToCentral &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, data = :data" " WHERE id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::insert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = cont[0].id != 0; // the first element determines the stmt to be used if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :data )")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvToCentral(); } return true; } bool DatabaseInterfaceImpl::upsert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); // the first element determines the stmt to be used keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :data )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, data = :data" " WHERE excluded.id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvToCentral(); } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::update(const std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, data = :data" " WHERE id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (const auto &data : cont) { m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":data"), data.data); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::select(QVector &dataVec) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::PrtCnvToCentral &data) { dataVec.push_back(data); }; return selectPrepareInternalPrtCnvToCentral(QString()) && selectFetchInternalPrtCnvToCentral(cb); } bool DatabaseInterfaceImpl::select(const std::function &cb) { SqlQueryJanitor janitor(m_query); return selectPrepareInternalPrtCnvToCentral(QString()) && selectFetchInternalPrtCnvToCentral(cb); } bool DatabaseInterfaceImpl::selectPrepareInternalPrtCnvToCentral(const QString &where) { const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("SELECT id, tel_id, counter, data" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool DatabaseInterfaceImpl::selectFetchInternalPrtCnvToCentral(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::PrtCnvToCentral data; while (m_query->next()) { int i = 0; data.id = m_query->value(i++).toInt(); data.telId = m_query->value(i++).toInt(); data.counter = m_query->value(i++).toInt(); data.data = m_query->value(i++).toByteArray(); cb(data); } return true; } bool DatabaseInterfaceImpl::selectPrtCnvToCentral(qint32 id, Database::PrtCnvToCentral &data) { SqlQueryJanitor janitor(m_query); int iCnt = 0; const auto cb =[&data, &iCnt] (const Database::PrtCnvToCentral &content) { data = content; ++iCnt; }; const QString where = QStringLiteral(" WHERE id = %1").arg(id); if (!selectPrepareInternalPrtCnvToCentral(where) || !selectFetchInternalPrtCnvToCentral(cb)) return false; return (iCnt == 1); } bool DatabaseInterfaceImpl::removePrtCnvToCentral(qint32 id) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE id = ") + QString::number(id)); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::fixUpSequencePrtCnvToCentral() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("SELECT setval('") + tableName + QStringLiteral("_id_seq', COALESCE((SELECT MAX(id)+1 FROM ") + tableName + QStringLiteral("), 1),false)")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::truncatePrtCnvToCentral() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_central"))); const QString stmt(QStringLiteral("TRUNCATE TABLE ") + tableName + QStringLiteral(" CASCADE")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } // Database::PrtCnvToCentral end // // Struct: Database::PrtCnvToRadio // bool DatabaseInterfaceImpl::insert(Database::PrtCnvToRadio &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = data.id != 0; if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, broadcast_index, reset_counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :broadcast_index, :reset_counter, :data )")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::upsert(Database::PrtCnvToRadio &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, broadcast_index, reset_counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :broadcast_index, :reset_counter, :data )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, broadcast_index = :broadcast_index, reset_counter = :reset_counter, data = :data" " WHERE excluded.id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } return true; } bool DatabaseInterfaceImpl::update(const Database::PrtCnvToRadio &data) { SqlQueryJanitor janitor(m_query); { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, broadcast_index = :broadcast_index, reset_counter = :reset_counter, data = :data" " WHERE id = :id")); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::insert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); QString keyColumnInsertKey; QString keyColumnInsertVal; const bool bInsertWithKey = cont[0].id != 0; // the first element determines the stmt to be used if (bInsertWithKey) { keyColumnInsertKey = QStringLiteral("id, "); keyColumnInsertVal = QStringLiteral(" :id, "); } const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, broadcast_index, reset_counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :broadcast_index, :reset_counter, :data )")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvToRadio(); } return true; } bool DatabaseInterfaceImpl::upsert(std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); QString keyColumnInsertKey; QString keyColumnInsertKeyConflict; QString keyColumnInsertVal; const bool bInsertWithKey = true; keyColumnInsertVal = QStringLiteral(" :id, "); keyColumnInsertKey = QStringLiteral("id, "); // the first element determines the stmt to be used keyColumnInsertKeyConflict = QStringLiteral("id "); const QString stmt(QStringLiteral("INSERT INTO ") + tableName + QStringLiteral(" (") + keyColumnInsertKey + QStringLiteral(" tel_id, counter, broadcast_index, reset_counter, data" " ) VALUES (") + keyColumnInsertVal + QStringLiteral(":tel_id, :counter, :broadcast_index, :reset_counter, :data )") + QStringLiteral(" ON CONFLICT (") + keyColumnInsertKeyConflict + QStringLiteral(") DO UPDATE ") + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, broadcast_index = :broadcast_index, reset_counter = :reset_counter, data = :data" " WHERE excluded.id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (auto &data : cont) { if (bInsertWithKey) m_query->bindValue(QStringLiteral(":id"), data.id); m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } if (data.id == 0) data.id = m_query->lastInsertId().toInt(); } } if (bInsertWithKey) fixUpSequencePrtCnvToRadio(); } return true; } // current only implemented for 'plain' structures with only one affected table bool DatabaseInterfaceImpl::update(const std::vector &cont) { if (cont.empty()) return true; { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("UPDATE ") + tableName + QStringLiteral(" SET" " tel_id = :tel_id, counter = :counter, broadcast_index = :broadcast_index, reset_counter = :reset_counter, data = :data" " WHERE id = :id")); { SqlQueryJanitor janitor(m_query); if (!m_query->prepare(stmt)) { m_lastError = m_query->lastError(); return false; } for (const auto &data : cont) { m_query->bindValue(QStringLiteral(":tel_id"), data.telId); m_query->bindValue(QStringLiteral(":counter"), data.counter); m_query->bindValue(QStringLiteral(":broadcast_index"), data.broadcastIndex); m_query->bindValue(QStringLiteral(":reset_counter"), data.resetCounter); m_query->bindValue(QStringLiteral(":data"), data.data); m_query->bindValue(QStringLiteral(":id"), data.id); if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } } } } return true; } bool DatabaseInterfaceImpl::select(QVector &dataVec) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::PrtCnvToRadio &data) { dataVec.push_back(data); }; return selectPrepareInternalPrtCnvToRadio(QString()) && selectFetchInternalPrtCnvToRadio(cb); } bool DatabaseInterfaceImpl::select(const std::function &cb) { SqlQueryJanitor janitor(m_query); return selectPrepareInternalPrtCnvToRadio(QString()) && selectFetchInternalPrtCnvToRadio(cb); } bool DatabaseInterfaceImpl::selectPrepareInternalPrtCnvToRadio(const QString &where) { const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("SELECT id, tel_id, counter, broadcast_index, reset_counter, data" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool DatabaseInterfaceImpl::selectFetchInternalPrtCnvToRadio(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::PrtCnvToRadio data; while (m_query->next()) { int i = 0; data.id = m_query->value(i++).toInt(); data.telId = m_query->value(i++).toInt(); data.counter = m_query->value(i++).toInt(); data.broadcastIndex = m_query->value(i++).toInt(); data.resetCounter = m_query->value(i++).toInt(); data.data = m_query->value(i++).toByteArray(); cb(data); } return true; } bool DatabaseInterfaceImpl::selectPrtCnvToRadio(qint32 id, Database::PrtCnvToRadio &data) { SqlQueryJanitor janitor(m_query); int iCnt = 0; const auto cb =[&data, &iCnt] (const Database::PrtCnvToRadio &content) { data = content; ++iCnt; }; const QString where = QStringLiteral(" WHERE id = %1").arg(id); if (!selectPrepareInternalPrtCnvToRadio(where) || !selectFetchInternalPrtCnvToRadio(cb)) return false; return (iCnt == 1); } bool DatabaseInterfaceImpl::removePrtCnvToRadio(qint32 id) { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("DELETE FROM ") + tableName + QStringLiteral(" WHERE id = ") + QString::number(id)); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::fixUpSequencePrtCnvToRadio() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("SELECT setval('") + tableName + QStringLiteral("_id_seq', COALESCE((SELECT MAX(id)+1 FROM ") + tableName + QStringLiteral("), 1),false)")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } bool DatabaseInterfaceImpl::truncatePrtCnvToRadio() { SqlQueryJanitor janitor(m_query); const QString tableName(getTableName(QStringLiteral("prtcnv_to_radio"))); const QString stmt(QStringLiteral("TRUNCATE TABLE ") + tableName + QStringLiteral(" CASCADE")); if (!m_query->exec(stmt, m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } return true; } // Database::PrtCnvToRadio end } // namespace TrainingAreaBase