Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
@@ -0,0 +1,45 @@
|
||||
# NGLDB
|
||||
FIND_PACKAGE(PostgreSQL REQUIRED)
|
||||
|
||||
OPTION(ENABLE_DB_TRACING "Enable trace output for NGLDB library" OFF)
|
||||
IF(ENABLE_DB_TRACING)
|
||||
add_compile_definitions(NGLDB_ENABLE_TRACE)
|
||||
ENDIF(ENABLE_DB_TRACING)
|
||||
|
||||
#
|
||||
# NGL Database Library
|
||||
#
|
||||
SET(ngldb_SRCS
|
||||
dbcommon.h
|
||||
dbconnection.cpp
|
||||
dbconnection.h
|
||||
db_service_handler.h
|
||||
dbtransaction.cpp
|
||||
dbtransaction.h
|
||||
ngldb_export.h
|
||||
ngldb_logger.cpp
|
||||
ngldb_logger.h
|
||||
nsqlquery.cpp
|
||||
nsqlquery.h
|
||||
sql_query_janitor.cpp
|
||||
sql_query_janitor.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV HLA WS ngldb SHARED ${ngldb_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(ngldb
|
||||
PRIVATE
|
||||
NGLLogger
|
||||
nglsettings
|
||||
${PostgreSQL_LIBRARIES}
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
Qt5::Sql
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(ngldb
|
||||
PRIVATE
|
||||
${PostgreSQL_INCLUDE_DIR}
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(ngldb)
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <memory>
|
||||
|
||||
class QSqlDatabase;
|
||||
namespace NGLDB
|
||||
{
|
||||
template<typename DB>
|
||||
class DbServiceHandler
|
||||
{
|
||||
public:
|
||||
DbServiceHandler() = default;
|
||||
~DbServiceHandler() = default;
|
||||
|
||||
|
||||
bool init(int exerciseId, NGL::Settings *settings)
|
||||
{
|
||||
if (m_dbInterface)
|
||||
return true;
|
||||
|
||||
m_dbInterface = DB::create(exerciseId);
|
||||
|
||||
if (!m_dbInterface->init(m_dbInterface->dbUser(),
|
||||
settings->databasePassword(m_dbInterface->dbUser()),
|
||||
settings->databaseDriver(),
|
||||
settings->databaseHostname(),
|
||||
settings->databaseName()))
|
||||
{
|
||||
m_dbInterface = nullptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init(int exerciseId, const QSqlDatabase &db)
|
||||
{
|
||||
if (m_dbInterface)
|
||||
return true;
|
||||
|
||||
m_dbInterface = DB::create(exerciseId);
|
||||
|
||||
if (!m_dbInterface->init(db))
|
||||
{
|
||||
m_dbInterface = nullptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<DB> db() const { return m_dbInterface; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<DB> m_dbInterface;
|
||||
};
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngldb_export.h"
|
||||
#include <QString>
|
||||
|
||||
|
||||
|
||||
namespace DBCommon
|
||||
{
|
||||
|
||||
enum class eDatabaseSchema
|
||||
{
|
||||
Exercise
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline QString getExerciseSchemaName(int exerciseId)
|
||||
{
|
||||
return QLatin1String("ex_") + QString::number(exerciseId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QString getTableName(const QString &tableName, const QString &schemaName)
|
||||
{
|
||||
if (schemaName.isEmpty())
|
||||
return tableName;
|
||||
return schemaName + QLatin1Char('.') + tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QString getExerciseTableName(const QString &tableName, int exerciseId)
|
||||
{
|
||||
return getTableName(tableName, getExerciseSchemaName(exerciseId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
|
||||
#include "dbconnection.h"
|
||||
|
||||
#include <QtSql/QSqlDatabase>
|
||||
#include <QtSql/QSqlError>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#include "nsqlquery.h"
|
||||
|
||||
namespace DBConnection
|
||||
{
|
||||
|
||||
QSqlDatabase open(NGL::INGLLogger &logger,
|
||||
const QString &dbUser,
|
||||
const QString &dbPasswd,
|
||||
const QString &dbDriver,
|
||||
const QString &dbHost,
|
||||
const QString &dbName,
|
||||
const QString &schemaName,
|
||||
const QString &connectionName)
|
||||
{
|
||||
|
||||
|
||||
|
||||
DEBUG_LOG(logger) << "host: " << dbHost << " database: " << dbName;
|
||||
QString realConnectionName(connectionName);
|
||||
if (connectionName.isEmpty())
|
||||
{
|
||||
realConnectionName = dbHost + QLatin1Char('_') + dbName;
|
||||
if (!schemaName.isEmpty())
|
||||
realConnectionName += QLatin1Char('_') + schemaName;
|
||||
}
|
||||
|
||||
auto dbConnection = QSqlDatabase::addDatabase(dbDriver, realConnectionName);
|
||||
dbConnection.setHostName(dbHost);
|
||||
dbConnection.setDatabaseName(dbName);
|
||||
dbConnection.setUserName(dbUser);
|
||||
dbConnection.setPassword(dbPasswd);
|
||||
|
||||
if (!dbConnection.open())
|
||||
{
|
||||
const QString err = dbConnection.lastError().nativeErrorCode();
|
||||
FATAL_LOG(logger) << "Error opening database " << dbHost
|
||||
<< ":" << dbName << " as user " << dbUser;
|
||||
FATAL_LOG(logger) << dbConnection.lastError().driverText() << " "
|
||||
<< dbConnection.lastError().databaseText() << " " << err;
|
||||
return dbConnection;
|
||||
}
|
||||
|
||||
DEBUG_LOG(logger) << "Database Initialisation successful -> DB: " << dbName << ", con: " << realConnectionName;
|
||||
|
||||
if (!schemaName.isEmpty())
|
||||
{
|
||||
const QString stmt = QLatin1String("SET SEARCH_PATH TO ") + schemaName + QLatin1String(", PUBLIC");
|
||||
|
||||
NSqlQuery q(dbConnection);
|
||||
if (!q.exec(stmt))
|
||||
{
|
||||
ERROR_LOG(logger) << "Set SEARCH_PATH to " << schemaName << " failed!";
|
||||
dbConnection.close();
|
||||
}
|
||||
}
|
||||
|
||||
return dbConnection;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtSql/QSqlDatabase>
|
||||
|
||||
#include "ngldb_export.h"
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
namespace DBConnection
|
||||
{
|
||||
NGLDB_EXPORT QSqlDatabase open(NGL::INGLLogger &logger,
|
||||
const QString &dbUser,
|
||||
const QString &dbPasswd,
|
||||
const QString &dbDriver,
|
||||
const QString &dbHost,
|
||||
const QString &dbName,
|
||||
const QString &schemaName = QString(),
|
||||
const QString &connectionName = QString());
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
|
||||
#include "dbtransaction.h"
|
||||
#include "ngldb_logger.h"
|
||||
#include <QtSql/QSqlError>
|
||||
|
||||
thread_local int s_refCounter = 0;
|
||||
|
||||
DBTransaction::DBTransaction(const QSqlDatabase &db)
|
||||
: m_db(db)
|
||||
, m_bCommitted(true)
|
||||
, mLogger(NGLDB::getLogger("DBTransaction"))
|
||||
{
|
||||
++s_refCounter;
|
||||
if (s_refCounter == 1)
|
||||
begin();
|
||||
}
|
||||
|
||||
DBTransaction::~DBTransaction()
|
||||
{
|
||||
if (s_refCounter == 1)
|
||||
{
|
||||
if (!m_bCommitted)
|
||||
rollback();
|
||||
}
|
||||
--s_refCounter;
|
||||
}
|
||||
|
||||
bool DBTransaction::begin()
|
||||
{
|
||||
if (!m_bCommitted)
|
||||
return setState(false);
|
||||
if (!m_db.transaction())
|
||||
{
|
||||
ERROR_LOG(mLogger) << "Error starting a transaction: " << m_db.lastError().driverText();
|
||||
return setState(false);
|
||||
}
|
||||
m_bCommitted = false;
|
||||
return setState(true);
|
||||
}
|
||||
|
||||
bool DBTransaction::commit()
|
||||
{
|
||||
if (s_refCounter == 1)
|
||||
{
|
||||
if (!m_db.commit())
|
||||
{
|
||||
ERROR_LOG(mLogger) << "Error committing a transaction: " << m_db.lastError().driverText();
|
||||
return setState(false);
|
||||
}
|
||||
m_bCommitted = true;
|
||||
return setState(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DBTransaction::rollback()
|
||||
{
|
||||
if (s_refCounter == 1)
|
||||
{
|
||||
if (!m_db.rollback())
|
||||
{
|
||||
ERROR_LOG(mLogger) << "Error rolling back a transaction" << m_db.lastError().driverText();
|
||||
return setState(false);
|
||||
}
|
||||
m_bCommitted = true;
|
||||
return setState(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DBTransaction::state() const
|
||||
{
|
||||
return m_lastState;
|
||||
}
|
||||
|
||||
bool DBTransaction::setState(bool bState)
|
||||
{
|
||||
m_lastState = bState;
|
||||
return m_lastState;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtSql/QSqlDatabase>
|
||||
|
||||
#include "ngldb_export.h"
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
|
||||
class NGLDB_EXPORT DBTransaction
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
explicit DBTransaction(const QSqlDatabase &db);
|
||||
|
||||
|
||||
|
||||
~DBTransaction();
|
||||
|
||||
|
||||
|
||||
bool begin();
|
||||
|
||||
|
||||
bool commit();
|
||||
|
||||
|
||||
bool rollback();
|
||||
|
||||
|
||||
bool state() const;
|
||||
|
||||
private:
|
||||
bool setState(bool bState);
|
||||
|
||||
QSqlDatabase m_db;
|
||||
bool m_bCommitted;
|
||||
bool m_lastState;
|
||||
NGL::INGLLogger &mLogger;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef NGLDB_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define NGLDB_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_NGLDB_LIB)
|
||||
# define NGLDB_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define NGLDB_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
|
||||
#include "ngldb_logger.h"
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
NGLDB::LOGGER_T NGLDB::getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "NGLDB.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try {
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger( loggerName );
|
||||
} catch ( const std::exception &ex )
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
#ifdef Q_CC_GNU
|
||||
#define DB_TRACE_FUNCTION __PRETTY_FUNCTION__
|
||||
#else
|
||||
#define DB_TRACE_FUNCTION __FUNCTION__
|
||||
#endif
|
||||
|
||||
#ifdef NGLDB_ENABLE_TRACE
|
||||
#define DB_TRACE { TRACE_LOG(mLogger) << DB_TRACE_FUNCTION }
|
||||
#define DB_TRACE2(x) { TRACE_LOG(mLogger) << DB_TRACE_FUNCTION << x }
|
||||
#else
|
||||
#define DB_TRACE
|
||||
#define DB_TRACE2(x)
|
||||
#endif
|
||||
|
||||
namespace NGLDB
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
+471
@@ -0,0 +1,471 @@
|
||||
|
||||
|
||||
#include "nsqlquery.h"
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtSql/QSqlDriver>
|
||||
#include <QtSql/QSqlError>
|
||||
#include <QtSql/QSqlRecord>
|
||||
#include <QtSql/QSqlResult>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QJsonValue>
|
||||
|
||||
#include "ngldb_logger.h"
|
||||
#include <libpq-fe.h>
|
||||
|
||||
static QString getSqlErrorString(const QSqlError &error)
|
||||
{
|
||||
return error.driverText() + QLatin1Char(' ') +
|
||||
error.databaseText() + QLatin1Char(' ') +
|
||||
error.nativeErrorCode();
|
||||
}
|
||||
|
||||
NSqlQuery::NSqlQuery(const QSqlDatabase &db)
|
||||
: QSqlQuery(db)
|
||||
, m_db(db)
|
||||
, mLogger(NGLDB::getLogger("NSqlQuery"))
|
||||
{
|
||||
DB_TRACE
|
||||
setForwardOnly(true);
|
||||
}
|
||||
|
||||
NSqlQuery::NSqlQuery(const QSqlDatabase &db, NGL::INGLLogger &logger)
|
||||
: QSqlQuery(db)
|
||||
, m_db(db)
|
||||
, mLogger(logger)
|
||||
{
|
||||
DB_TRACE
|
||||
setForwardOnly(true);
|
||||
}
|
||||
|
||||
NSqlQuery::NSqlQuery(const QString &query, const QSqlDatabase &db)
|
||||
: QSqlQuery(query, db)
|
||||
, m_db(db)
|
||||
, mLogger(NGLDB::getLogger("NSqlQuery"))
|
||||
{
|
||||
DB_TRACE
|
||||
setForwardOnly(true);
|
||||
}
|
||||
|
||||
NSqlQuery::NSqlQuery(const QString &query, const QSqlDatabase &db, NGL::INGLLogger &logger)
|
||||
: QSqlQuery(query, db)
|
||||
, m_db(db)
|
||||
, mLogger(logger)
|
||||
{
|
||||
DB_TRACE
|
||||
setForwardOnly(true);
|
||||
}
|
||||
|
||||
void NSqlQuery::addBindValue(const QVariant &val, QSql::ParamType paramType)
|
||||
{
|
||||
DB_TRACE;
|
||||
DEBUG_LOG(mLogger) << "type: " << QString::fromLatin1(val.typeName()) << " paramType: " << paramType;
|
||||
QSqlQuery::addBindValue(val, paramType);
|
||||
}
|
||||
|
||||
int NSqlQuery::at() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::at();
|
||||
}
|
||||
|
||||
void NSqlQuery::bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType)
|
||||
{
|
||||
DB_TRACE;
|
||||
TRACE_LOG(mLogger) << "placeholder: " << placeholder << " type: " << QString::fromLatin1(val.typeName()) << " paramType: " << paramType;
|
||||
QSqlQuery::bindValue(placeholder, val, paramType);
|
||||
}
|
||||
|
||||
void NSqlQuery::bindValue(int pos, const QVariant &val, QSql::ParamType paramType)
|
||||
{
|
||||
DB_TRACE;
|
||||
TRACE_LOG(mLogger) << "pos: " << pos << " type: " << QString::fromLatin1(val.typeName()) << " paramType: " << paramType;
|
||||
QSqlQuery::bindValue(pos, val, paramType);
|
||||
}
|
||||
|
||||
QVariant NSqlQuery::boundValue(const QString &placeholder) const
|
||||
{
|
||||
DB_TRACE
|
||||
TRACE_LOG(mLogger) << "placeholder: " << placeholder;
|
||||
return QSqlQuery::boundValue(placeholder);
|
||||
}
|
||||
|
||||
QVariant NSqlQuery::boundValue(int pos) const
|
||||
{
|
||||
DB_TRACE
|
||||
TRACE_LOG(mLogger) << "pos: " << pos;
|
||||
return QSqlQuery::boundValue(pos);
|
||||
}
|
||||
|
||||
QMap<QString, QVariant> NSqlQuery::boundValues() const
|
||||
{
|
||||
DB_TRACE
|
||||
QMap<QString, QVariant> res;
|
||||
const QVariantList list = QSqlQuery::boundValues();
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
res.insert(QString::number(i), list.at(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
void NSqlQuery::clear()
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::clear();
|
||||
}
|
||||
|
||||
const QSqlDriver *NSqlQuery::driver() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::driver();
|
||||
}
|
||||
|
||||
bool NSqlQuery::exec(const QString &query, bool bEmitMessageOnError)
|
||||
{
|
||||
DB_TRACE;
|
||||
DEBUG_LOG(mLogger) << "query: " << query;
|
||||
if (QSqlQuery::exec(query))
|
||||
return true;
|
||||
if (bEmitMessageOnError)
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NSqlQuery::exec(bool bEmitMessageOnError)
|
||||
{
|
||||
DB_TRACE
|
||||
DEBUG_LOG(mLogger) << "query: " << lastQuery();
|
||||
|
||||
if (mLogger.isDebugEnabled())
|
||||
{
|
||||
const QMap<QString, QVariant> &boundValuesMap = boundValues();
|
||||
for (auto it=boundValuesMap.begin(); it != boundValuesMap.end(); ++it)
|
||||
{
|
||||
if ( it.value().canConvert<QString>())
|
||||
DEBUG_LOG(mLogger) << "key='" << it.key() << "' value='" << it.value().toString() << "'";
|
||||
else
|
||||
DEBUG_LOG(mLogger) << "key='" << it.key() << "' value cant Convert to string'";
|
||||
}
|
||||
}
|
||||
if (QSqlQuery::exec())
|
||||
return true;
|
||||
if (bEmitMessageOnError)
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NSqlQuery::execAndFetch()
|
||||
{
|
||||
DB_TRACE
|
||||
if (!exec())
|
||||
return false;
|
||||
return (next());
|
||||
}
|
||||
|
||||
bool NSqlQuery::execAndFetch(const QString &query)
|
||||
{
|
||||
DB_TRACE
|
||||
if (!exec(query))
|
||||
return false;
|
||||
return (next());
|
||||
}
|
||||
|
||||
bool NSqlQuery::execBatch(BatchExecutionMode mode)
|
||||
{
|
||||
DB_TRACE2("mode: " << mode)
|
||||
DEBUG_LOG(mLogger) << "mode: " << mode;
|
||||
if (QSqlQuery::execBatch(mode))
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
QString NSqlQuery::executedQuery() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::executedQuery();
|
||||
}
|
||||
|
||||
void NSqlQuery::finish()
|
||||
{
|
||||
DB_TRACE
|
||||
QSqlQuery::finish();
|
||||
}
|
||||
|
||||
bool NSqlQuery::first()
|
||||
{
|
||||
DB_TRACE
|
||||
if (QSqlQuery::first())
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NSqlQuery::isActive() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::isActive();
|
||||
}
|
||||
|
||||
bool NSqlQuery::isForwardOnly() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::isForwardOnly();
|
||||
}
|
||||
|
||||
bool NSqlQuery::isNull(int field) const
|
||||
{
|
||||
DB_TRACE2("field: " << field)
|
||||
return QSqlQuery::isNull(field);
|
||||
}
|
||||
|
||||
bool NSqlQuery::isSelect() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::isSelect();
|
||||
}
|
||||
|
||||
bool NSqlQuery::isValid() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::isValid();
|
||||
}
|
||||
|
||||
bool NSqlQuery::last()
|
||||
{
|
||||
DB_TRACE
|
||||
if (QSqlQuery::last())
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlError NSqlQuery::lastError() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::lastError();
|
||||
}
|
||||
|
||||
QString NSqlQuery::sqlstate()
|
||||
{
|
||||
const QVariant resultHandle = this->result()->handle();
|
||||
|
||||
|
||||
|
||||
|
||||
if (resultHandle.isValid() && (qstrcmp(resultHandle.typeName(), "PGresult*") == 0))
|
||||
{
|
||||
|
||||
const PGresult *pgresHandle = *static_cast<const PGresult * const *>(resultHandle.data());
|
||||
|
||||
if (pgresHandle != nullptr)
|
||||
{
|
||||
|
||||
return QString::fromLocal8Bit(PQresultErrorField(pgresHandle, PG_DIAG_SQLSTATE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return QStringLiteral("58000");
|
||||
}
|
||||
|
||||
QVariant NSqlQuery::lastInsertId()
|
||||
{
|
||||
DB_TRACE
|
||||
|
||||
QVariant ret;
|
||||
|
||||
if (this->driver()->hasFeature(QSqlDriver::LastInsertId))
|
||||
ret = QSqlQuery::lastInsertId();
|
||||
|
||||
if (!ret.isValid())
|
||||
{
|
||||
NSqlQuery q(m_db);
|
||||
if (q.execAndFetch(QLatin1String("SELECT LASTVAL()")))
|
||||
ret = q.value(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString NSqlQuery::lastQuery() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::lastQuery();
|
||||
}
|
||||
|
||||
bool NSqlQuery::next()
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::next();
|
||||
}
|
||||
|
||||
bool NSqlQuery::nextResult()
|
||||
{
|
||||
DB_TRACE
|
||||
if (QSqlQuery::nextResult())
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
int NSqlQuery::numRowsAffected() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::numRowsAffected();
|
||||
}
|
||||
|
||||
QSql::NumericalPrecisionPolicy NSqlQuery::numericalPrecisionPolicy() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::numericalPrecisionPolicy();
|
||||
}
|
||||
|
||||
bool NSqlQuery::prepare(const QString &query)
|
||||
{
|
||||
DB_TRACE2("query: " << query)
|
||||
if (QSqlQuery::prepare(query))
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NSqlQuery::previous()
|
||||
{
|
||||
DB_TRACE
|
||||
if (QSqlQuery::previous())
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlRecord NSqlQuery::record() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::record();
|
||||
}
|
||||
|
||||
const QSqlResult *NSqlQuery::result() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::result();
|
||||
}
|
||||
|
||||
bool NSqlQuery::seek(int index, bool relative)
|
||||
{
|
||||
DB_TRACE2("index: " << index << " relative: " << relative);
|
||||
if (QSqlQuery::seek(index, relative))
|
||||
return true;
|
||||
printLastSqlError();
|
||||
return false;
|
||||
}
|
||||
|
||||
void NSqlQuery::setForwardOnly(bool forward)
|
||||
{
|
||||
DB_TRACE2("forward: " << forward);
|
||||
QSqlQuery::setForwardOnly(forward);
|
||||
}
|
||||
|
||||
void NSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
|
||||
{
|
||||
DB_TRACE2("precisionPolicy: " << precisionPolicy);
|
||||
QSqlQuery::setNumericalPrecisionPolicy(precisionPolicy);
|
||||
}
|
||||
|
||||
int NSqlQuery::size() const
|
||||
{
|
||||
DB_TRACE
|
||||
return QSqlQuery::size();
|
||||
}
|
||||
|
||||
QVariant NSqlQuery::value(int index) const
|
||||
{
|
||||
DB_TRACE2("index: " << index)
|
||||
return QSqlQuery::value(index);
|
||||
}
|
||||
|
||||
NSqlQuery &NSqlQuery::operator= (const NSqlQuery &other)
|
||||
{
|
||||
DB_TRACE
|
||||
// Use move assignment to avoid deprecated copy-assignment of QSqlQuery.
|
||||
// The QSqlQuery copy constructor is deprecated; silence the warning locally.
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
QSqlQuery tmp(other);
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
QSqlQuery::operator=(std::move(tmp));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool NSqlQuery::export2CSV(const QString &filename)
|
||||
{
|
||||
DB_TRACE2("export csv to file: " << filename)
|
||||
QFile data(filename);
|
||||
QTextStream output(&data);
|
||||
if (data.open(QFile::WriteOnly | QFile::Truncate))
|
||||
{
|
||||
if (isSelect() && isActive())
|
||||
{
|
||||
bool isHeaderWritten = false;
|
||||
while (next())
|
||||
{
|
||||
QSqlRecord rec = record();
|
||||
if (!isHeaderWritten)
|
||||
{
|
||||
for (int i = 0; i < rec.count(); ++i)
|
||||
output << QLatin1Char('\"') + rec.fieldName(i) + QLatin1String("\",");
|
||||
output << QLatin1Char('\n');
|
||||
isHeaderWritten = true;
|
||||
}
|
||||
for (int i = 0; i < rec.count(); ++i)
|
||||
output << QLatin1Char('\"') + rec.value(i).toString() + QLatin1String("\",");
|
||||
output << QLatin1Char('\n');
|
||||
}
|
||||
}
|
||||
data.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant NSqlQuery::qDateTimeToQVariant(const QDateTime &dt)
|
||||
{
|
||||
if (dt.isValid())
|
||||
return dt.toMSecsSinceEpoch();
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QDateTime NSqlQuery::qVariantToQDateTime(const QVariant &var)
|
||||
{
|
||||
if (var.isNull())
|
||||
return QDateTime();
|
||||
return QDateTime::fromMSecsSinceEpoch(var.toLongLong());
|
||||
}
|
||||
|
||||
QString NSqlQuery::qVariantToJsonString(const QVariant &value)
|
||||
{
|
||||
if (value.isNull())
|
||||
return QStringLiteral("{}");
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
QString NSqlQuery::jsonValueToJsonString(const QJsonValue &value)
|
||||
{
|
||||
if (value.isNull())
|
||||
return QStringLiteral("{}");
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
void NSqlQuery::printLastSqlError()
|
||||
{
|
||||
ERROR_LOG(mLogger) << getSqlErrorString(lastError()) << " " << lastQuery();
|
||||
}
|
||||
|
||||
QString NSqlQuery::getLastSqlError()
|
||||
{
|
||||
return (getSqlErrorString(lastError()) + QLatin1Char(' ') + lastQuery());
|
||||
}
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtSql/QSqlQuery>
|
||||
|
||||
#include "ngldb_export.h"
|
||||
#include "dbcommon.h"
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
class QDateTime;
|
||||
class QJsonValue;
|
||||
|
||||
|
||||
|
||||
class NGLDB_EXPORT NSqlQuery final : public QSqlQuery
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
explicit NSqlQuery(const QSqlDatabase &db);
|
||||
explicit NSqlQuery(const QSqlDatabase &db, NGL::INGLLogger &logger);
|
||||
explicit NSqlQuery(const QString &query, const QSqlDatabase &db);
|
||||
explicit NSqlQuery(const QString &query, const QSqlDatabase &db, NGL::INGLLogger &logger);
|
||||
|
||||
|
||||
|
||||
NSqlQuery(const NSqlQuery &other) = default;
|
||||
|
||||
|
||||
|
||||
~NSqlQuery() = default;
|
||||
|
||||
|
||||
|
||||
void addBindValue(const QVariant &val, QSql::ParamType paramType = QSql::In);
|
||||
|
||||
|
||||
|
||||
int at() const;
|
||||
|
||||
|
||||
|
||||
void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType = QSql::In);
|
||||
|
||||
|
||||
|
||||
void bindValue(int pos, const QVariant &val, QSql::ParamType paramType = QSql::In);
|
||||
|
||||
|
||||
|
||||
QVariant boundValue(const QString &placeholder) const;
|
||||
|
||||
|
||||
|
||||
QVariant boundValue(int pos) const;
|
||||
|
||||
|
||||
|
||||
QMap<QString, QVariant> boundValues() const;
|
||||
|
||||
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
|
||||
const QSqlDriver *driver() const;
|
||||
|
||||
|
||||
|
||||
bool exec(const QString &query, bool bEmitMessageOnError = true);
|
||||
|
||||
|
||||
|
||||
bool exec(bool bEmitMessageOnError = true);
|
||||
|
||||
|
||||
|
||||
bool execAndFetch();
|
||||
|
||||
|
||||
|
||||
bool execAndFetch(const QString &query);
|
||||
|
||||
|
||||
|
||||
bool execBatch(BatchExecutionMode mode = ValuesAsRows);
|
||||
|
||||
|
||||
|
||||
QString executedQuery() const;
|
||||
|
||||
|
||||
|
||||
void finish();
|
||||
|
||||
|
||||
|
||||
bool first();
|
||||
|
||||
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
|
||||
|
||||
bool isForwardOnly() const;
|
||||
|
||||
|
||||
|
||||
bool isNull(int field) const;
|
||||
|
||||
|
||||
|
||||
bool isSelect() const;
|
||||
|
||||
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
|
||||
|
||||
bool last();
|
||||
|
||||
|
||||
|
||||
QSqlError lastError() const;
|
||||
|
||||
QString sqlstate();
|
||||
|
||||
|
||||
QVariant lastInsertId();
|
||||
|
||||
|
||||
|
||||
QString lastQuery() const;
|
||||
|
||||
|
||||
|
||||
bool next();
|
||||
|
||||
|
||||
|
||||
bool nextResult();
|
||||
|
||||
|
||||
|
||||
int numRowsAffected() const;
|
||||
|
||||
|
||||
|
||||
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
|
||||
|
||||
|
||||
|
||||
bool prepare(const QString &query);
|
||||
|
||||
|
||||
|
||||
bool previous();
|
||||
|
||||
|
||||
|
||||
QSqlRecord record() const;
|
||||
|
||||
|
||||
|
||||
const QSqlResult *result() const;
|
||||
|
||||
|
||||
|
||||
bool seek(int index, bool relative = false);
|
||||
|
||||
|
||||
|
||||
void setForwardOnly(bool forward);
|
||||
|
||||
|
||||
|
||||
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
|
||||
|
||||
|
||||
|
||||
int size() const;
|
||||
|
||||
|
||||
|
||||
QVariant value(int index) const;
|
||||
|
||||
|
||||
|
||||
NSqlQuery &operator= (const NSqlQuery &other);
|
||||
|
||||
bool export2CSV(const QString &filename);
|
||||
|
||||
|
||||
|
||||
static QVariant qDateTimeToQVariant(const QDateTime &dt);
|
||||
|
||||
|
||||
static QDateTime qVariantToQDateTime(const QVariant &var);
|
||||
|
||||
|
||||
static QString qVariantToJsonString(const QVariant &value);
|
||||
|
||||
|
||||
static QString jsonValueToJsonString(const QJsonValue &value);
|
||||
|
||||
static inline QString fixupEmptyJsonString(const QString &str) { return str.isEmpty() ? QLatin1String("{}") : str; }
|
||||
|
||||
QString getLastSqlError();
|
||||
|
||||
private:
|
||||
void printLastSqlError();
|
||||
QSqlDatabase m_db;
|
||||
NGL::INGLLogger &mLogger;
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
|
||||
#include "sql_query_janitor.h"
|
||||
#include "nsqlquery.h"
|
||||
#include <QtGlobal>
|
||||
|
||||
|
||||
SqlQueryJanitor::SqlQueryJanitor(NSqlQuery *query)
|
||||
: m_query(query)
|
||||
{
|
||||
Q_ASSERT(m_query);
|
||||
Q_ASSERT(!m_query->isActive());
|
||||
}
|
||||
|
||||
SqlQueryJanitor::SqlQueryJanitor(const std::unique_ptr<NSqlQuery> &query)
|
||||
: SqlQueryJanitor(query.get())
|
||||
{
|
||||
}
|
||||
|
||||
SqlQueryJanitor::~SqlQueryJanitor()
|
||||
{
|
||||
m_query->finish();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngldb_export.h"
|
||||
#include <memory>
|
||||
|
||||
class NSqlQuery;
|
||||
|
||||
|
||||
|
||||
class NGLDB_EXPORT SqlQueryJanitor
|
||||
{
|
||||
public:
|
||||
explicit SqlQueryJanitor(NSqlQuery *query);
|
||||
explicit SqlQueryJanitor(const std::unique_ptr<NSqlQuery> &query);
|
||||
~SqlQueryJanitor();
|
||||
|
||||
private:
|
||||
NSqlQuery *m_query;
|
||||
};
|
||||
Reference in new issue
Block a user