#include "nsqlquery.h" #include #include #include #include #include #include #include #include #include #include "ngldb_logger.h" #include 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 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 &boundValuesMap = boundValues(); for (auto it=boundValuesMap.begin(); it != boundValuesMap.end(); ++it) { if ( it.value().canConvert()) 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(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()); }