458 lines
9.5 KiB
C++
Executable File
458 lines
9.5 KiB
C++
Executable File
|
|
|
|
#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: " << val.type() << " 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: " << val.type() << " 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: " << val.type() << " 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
|
|
return QSqlQuery::boundValues();
|
|
}
|
|
|
|
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
|
|
QSqlQuery::operator= (other);
|
|
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());
|
|
}
|