/** * @RDE_HEADER@ * Template for 'real' structures including insert/update/delete functions for db * $Id: svc_db_impl.cpp.grantlee 56901 2022-04-22 04:21:30Z karwat $ * $HeadURL: svn://192.168.133.21/TDS/branches/product/features/25_02_refactoring/Lts/Common/CodeGen/svc_db_impl.cpp.grantlee $ * $Author: karwat $ */ {% autoescape off %} // filename: {{ namespace_abbr }}_dao.cpp #include "{{ namespace_abbr }}_dao.h" {% if custom_db_procs %} #include <{{ include_prefix }}/{{ namespace_abbr }}_db_impl_custom.h> {% endif %} #include #include #include #include #include #include #include namespace {{ namespace }} { Dao::Dao(int exerciseId) : m_query(nullptr) , m_exerciseId(exerciseId) , m_bEmitMessageOnError(true) , m_bCanHandleSchemas(true) , m_ownDatabaseConnection(true) , m_logger(getLogger("Db")) {} Dao::~Dao() { m_query = nullptr; {% if has_db_notifications %} QSqlDriver *driver = m_dbConnection.driver(); if (driver && m_dbConnection.isOpen()) { {% for cpp_struct in cpp_structs %}{% for db_notify in cpp_struct.dbNotifications %} driver->unsubscribeFromNotification(QStringLiteral("{{ db_notify }}")); {% endfor %}{% endfor %} } {% endif %} if (m_ownDatabaseConnection && m_dbConnection.isOpen()) m_dbConnection.close(); } bool Dao::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 Dao::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; {% if has_db_notifications %} if (!driver->hasFeature(QSqlDriver::EventNotifications)) { WARNING_LOG(m_logger) << "Can not subscribe to notifications - sqldriver does not support this feature!"; } else { connect(driver, QOverload::of(&QSqlDriver::notification), this, &Dao::onNotification); {% for cpp_struct in cpp_structs %}{% for db_notify in cpp_struct.dbNotifications %}driver->subscribeToNotification(QStringLiteral("{{ db_notify }}"));{% endfor %}{% endfor %} } {% endif %} m_query = std::unique_ptr(new NSqlQuery(m_dbConnection, m_logger)); return true; } QString Dao::schemaName() const { if (!m_bCanHandleSchemas) return QString(); if (m_exerciseId <= 0) return QStringLiteral("{{ namespace_abbr }}"); return DBCommon::getExerciseSchemaName(m_exerciseId); } QString Dao::dbUser() const { if (m_exerciseId > 0) return QStringLiteral("ets_ex_00"); else return QStringLiteral("ets_") + schemaName(); } void Dao::setEmitMessageOnError(bool bEmit) { m_bEmitMessageOnError = bEmit; } QString Dao::getTableName(const QString &tableName) const { if (!m_bCanHandleSchemas) return tableName; if (m_exerciseId > 0) return DBCommon::getExerciseTableName(tableName, m_exerciseId); return QStringLiteral("{{ namespace_abbr }}.") + tableName; } QSqlError Dao::getLastError() const { return m_lastError; } {% if has_db_notifications %} void Dao::onNotification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload) { DEBUG_LOG(m_logger) << "Notification source = " << source; if (source == QSqlDriver::SelfSource) return; // search coresponding signal {% for cpp_struct in cpp_structs %}{% for db_notify in cpp_struct.dbNotifications %} if (name == QStringLiteral("{{ db_notify }}")) { emit signal{{ db_notify }}(payload.toInt()); return; } {% endfor %}{% endfor %} } {% endif %} {% for cpp_struct in cpp_structs %} // // --> Struct: Database::{{ cpp_struct.name }} // bool Dao::select(QVector &dataVec, const QString &where) { SqlQueryJanitor janitor(m_query); const auto cb =[&dataVec] (const Database::{{ cpp_struct.name }} &data) { dataVec.push_back(data); }; return selectPrepareInternal{{ cpp_struct.name }}(where) && selectFetchInternal{{ cpp_struct.name }}(cb); } bool Dao::selectPrepareInternal{{ cpp_struct.name }}(const QString &where) { const QString tableName(getTableName(QStringLiteral("{{ cpp_struct.viewTableName }}"))); const QString stmt(QStringLiteral("SELECT {% for row in cpp_struct.viewMember %}{{ row.dbColumnNameView }}{% if not forloop.last %}, {% endif %}{% endfor %}" " FROM ") + tableName + where); return m_query->prepare(stmt); } bool Dao::selectFetchInternal{{ cpp_struct.name }}(const std::function &cb) { if (!m_query->exec(m_bEmitMessageOnError)) { m_lastError = m_query->lastError(); return false; } Database::{{ cpp_struct.name }} data; while (m_query->next()) { int i = 0; {% for row in cpp_struct.viewMember %} data.{{ row.cppMemberName }}{{ row.cppFromQvPre1 }} = {{ row.cppFromQvPre2 }}m_query->value(i++){{ row.cppFromQvPost }};{% endfor %} cb(data); } return true; } // <-- Database::{{ cpp_struct.name }} end {% endfor %} /*static*/ QString Dao::qVariantToJsonString(const QVariant &value) { return value.isNull() ? QStringLiteral("{}") : value.toString(); } } // namespace {{ namespace }} {% endautoescape %}