diff options
Diffstat (limited to 'src/plugins/sqldrivers/db2/qsql_db2.cpp')
-rw-r--r-- | src/plugins/sqldrivers/db2/qsql_db2.cpp | 103 |
1 files changed, 75 insertions, 28 deletions
diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp index 839d80466f..1d7e985731 100644 --- a/src/plugins/sqldrivers/db2/qsql_db2.cpp +++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp @@ -66,6 +66,10 @@ QT_BEGIN_NAMESPACE static const int COLNAMESIZE = 255; +// Based on what is mentioned in the documentation here: +// https://www.ibm.com/support/knowledgecenter/en/SSEPEK_10.0.0/sqlref/src/tpc/db2z_limits.html +// The limit is 128 bytes for table names +static const SQLSMALLINT TABLENAMESIZE = 128; static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT }; class QDB2DriverPrivate : public QSqlDriverPrivate @@ -88,24 +92,24 @@ class QDB2Result: public QSqlResult public: QDB2Result(const QDB2Driver *drv); ~QDB2Result(); - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool prepare(const QString &query) override; + bool exec() override; + QVariant handle() const override; protected: - QVariant data(int field) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchNext() Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - bool isNull(int i) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - void detachFromResultSet() Q_DECL_OVERRIDE; - bool nextResult() Q_DECL_OVERRIDE; + QVariant data(int field) override; + bool reset(const QString &query) override; + bool fetch(int i) override; + bool fetchNext() override; + bool fetchFirst() override; + bool fetchLast() override; + bool isNull(int i) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + void virtual_hook(int id, void *data) override; + void detachFromResultSet() override; + bool nextResult() override; }; class QDB2ResultPrivate: public QSqlResultPrivate @@ -152,7 +156,7 @@ static SQLTCHAR* qToTChar(const QString& str) return (SQLTCHAR*)str.utf16(); } -static QString qWarnDB2Handle(int handleType, SQLHANDLE handle) +static QString qWarnDB2Handle(int handleType, SQLHANDLE handle, int *errorCode) { SQLINTEGER nativeCode; SQLSMALLINT msgLen; @@ -167,22 +171,51 @@ static QString qWarnDB2Handle(int handleType, SQLHANDLE handle) (SQLTCHAR*) description, SQL_MAX_MESSAGE_LENGTH - 1, /* in bytes, not in characters */ &msgLen); - if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + if (errorCode) + *errorCode = nativeCode; return QString(qFromTChar(description)); + } return QString(); } -static QString qDB2Warn(const QDB2DriverPrivate* d) +static QString qDB2Warn(const QDB2DriverPrivate* d, QStringList *errorCodes = nullptr) { - return (qWarnDB2Handle(SQL_HANDLE_ENV, d->hEnv) + QLatin1Char(' ') - + qWarnDB2Handle(SQL_HANDLE_DBC, d->hDbc)); + int errorCode = 0; + QString error = qWarnDB2Handle(SQL_HANDLE_ENV, d->hEnv, &errorCode); + if (errorCodes && errorCode != 0) { + *errorCodes << QString::number(errorCode); + errorCode = 0; + } + if (!error.isEmpty()) + error += QLatin1Char(' '); + error += qWarnDB2Handle(SQL_HANDLE_DBC, d->hDbc, &errorCode); + if (errorCodes && errorCode != 0) + *errorCodes << QString::number(errorCode); + return error; } -static QString qDB2Warn(const QDB2ResultPrivate* d) +static QString qDB2Warn(const QDB2ResultPrivate* d, QStringList *errorCodes = nullptr) { - return (qWarnDB2Handle(SQL_HANDLE_ENV, d->drv_d_func()->hEnv) + QLatin1Char(' ') - + qWarnDB2Handle(SQL_HANDLE_DBC, d->drv_d_func()->hDbc) - + qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt)); + int errorCode = 0; + QString error = qWarnDB2Handle(SQL_HANDLE_ENV, d->drv_d_func()->hEnv, &errorCode); + if (errorCodes && errorCode != 0) { + *errorCodes << QString::number(errorCode); + errorCode = 0; + } + if (!error.isEmpty()) + error += QLatin1Char(' '); + error += qWarnDB2Handle(SQL_HANDLE_DBC, d->drv_d_func()->hDbc, &errorCode); + if (errorCodes && errorCode != 0) { + *errorCodes << QString::number(errorCode); + errorCode = 0; + } + if (!error.isEmpty()) + error += QLatin1Char(' '); + error += qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt, &errorCode); + if (errorCodes && errorCode != 0) + *errorCodes << QString::number(errorCode); + return error; } static void qSqlWarning(const QString& message, const QDB2DriverPrivate* d) @@ -200,13 +233,19 @@ static void qSqlWarning(const QString& message, const QDB2ResultPrivate* d) static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QDB2DriverPrivate* p) { - return QSqlError(QLatin1String("QDB2: ") + err, qDB2Warn(p), type); + QStringList errorCodes; + const QString error = qDB2Warn(p, &errorCodes); + return QSqlError(QStringLiteral("QDB2: ") + err, error, type, + errorCodes.join(QLatin1Char(';'))); } static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QDB2ResultPrivate* p) { - return QSqlError(QLatin1String("QDB2: ") + err, qDB2Warn(p), type); + QStringList errorCodes; + const QString error = qDB2Warn(p, &errorCodes); + return QSqlError(QStringLiteral("QDB2: ") + err, error, type, + errorCodes.join(QLatin1Char(';'))); } static QVariant::Type qDecodeDB2Type(SQLSMALLINT sqltype) @@ -297,6 +336,12 @@ static QSqlField qMakeFieldInfo(const QDB2ResultPrivate* d, int i) f.setLength(colSize == 0 ? -1 : int(colSize)); f.setPrecision(colScale == 0 ? -1 : int(colScale)); f.setSqlType(int(colType)); + SQLTCHAR tableName[TABLENAMESIZE]; + SQLSMALLINT tableNameLen; + r = SQLColAttribute(d->hStmt, i + 1, SQL_DESC_BASE_TABLE_NAME, tableName, + TABLENAMESIZE, &tableNameLen, 0); + if (r == SQL_SUCCESS) + f.setTableName(qFromTChar(tableName)); return f; } @@ -1394,7 +1439,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const SQL_FETCH_NEXT, 0); while (r == SQL_SUCCESS) { - fil.append(qMakeFieldInfo(hStmt)); + QSqlField fld = qMakeFieldInfo(hStmt); + fld.setTableName(tableName); + fil.append(fld); r = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0); |