summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers/db2
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/drivers/db2')
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp1700
-rw-r--r--src/sql/drivers/db2/qsql_db2.pri8
-rw-r--r--src/sql/drivers/db2/qsql_db2_p.h103
3 files changed, 0 insertions, 1811 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
deleted file mode 100644
index 4ccc3aca9e..0000000000
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ /dev/null
@@ -1,1700 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtSql module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsql_db2_p.h"
-#include <qcoreapplication.h>
-#include <qdatetime.h>
-#include <qsqlfield.h>
-#include <qsqlerror.h>
-#include <qsqlindex.h>
-#include <qsqlrecord.h>
-#include <qstringlist.h>
-#include <qvarlengtharray.h>
-#include <qvector.h>
-#include <QDebug>
-#include <QtSql/private/qsqldriver_p.h>
-#include <QtSql/private/qsqlresult_p.h>
-
-#if defined(Q_CC_BOR)
-// DB2's sqlsystm.h (included through sqlcli1.h) defines the SQL_BIGINT_TYPE
-// and SQL_BIGUINT_TYPE to wrong the types for Borland; so do the defines to
-// the right type before including the header
-#define SQL_BIGINT_TYPE qint64
-#define SQL_BIGUINT_TYPE quint64
-#endif
-
-#define UNICODE
-
-#include <sqlcli1.h>
-
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
-static const int COLNAMESIZE = 255;
-static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT };
-
-class QDB2DriverPrivate : public QSqlDriverPrivate
-{
- Q_DECLARE_PUBLIC(QDB2Driver)
-
-public:
- QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = QSqlDriver::DB2; }
- SQLHANDLE hEnv;
- SQLHANDLE hDbc;
- QString user;
-};
-
-class QDB2ResultPrivate;
-
-class QDB2Result: public QSqlResult
-{
- Q_DECLARE_PRIVATE(QDB2Result)
-
-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;
-
-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;
-};
-
-class QDB2ResultPrivate: public QSqlResultPrivate
-{
- Q_DECLARE_PUBLIC(QDB2Result)
-
-public:
- Q_DECLARE_SQLDRIVER_PRIVATE(QDB2Driver)
- QDB2ResultPrivate(QDB2Result *q, const QDB2Driver *drv)
- : QSqlResultPrivate(q, drv),
- hStmt(0)
- {}
- ~QDB2ResultPrivate()
- {
- emptyValueCache();
- }
- void clearValueCache()
- {
- for (int i = 0; i < valueCache.count(); ++i) {
- delete valueCache[i];
- valueCache[i] = NULL;
- }
- }
- void emptyValueCache()
- {
- clearValueCache();
- valueCache.clear();
- }
-
- SQLHANDLE hStmt;
- QSqlRecord recInf;
- QVector<QVariant*> valueCache;
-};
-
-static QString qFromTChar(SQLTCHAR* str)
-{
- return QString((const QChar *)str);
-}
-
-// dangerous!! (but fast). Don't use in functions that
-// require out parameters!
-static SQLTCHAR* qToTChar(const QString& str)
-{
- return (SQLTCHAR*)str.utf16();
-}
-
-static QString qWarnDB2Handle(int handleType, SQLHANDLE handle)
-{
- SQLINTEGER nativeCode;
- SQLSMALLINT msgLen;
- SQLRETURN r = SQL_ERROR;
- SQLTCHAR state[SQL_SQLSTATE_SIZE + 1];
- SQLTCHAR description[SQL_MAX_MESSAGE_LENGTH];
- r = SQLGetDiagRec(handleType,
- handle,
- 1,
- (SQLTCHAR*) state,
- &nativeCode,
- (SQLTCHAR*) description,
- SQL_MAX_MESSAGE_LENGTH - 1, /* in bytes, not in characters */
- &msgLen);
- if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
- return QString(qFromTChar(description));
- return QString();
-}
-
-static QString qDB2Warn(const QDB2DriverPrivate* d)
-{
- return (qWarnDB2Handle(SQL_HANDLE_ENV, d->hEnv) + QLatin1Char(' ')
- + qWarnDB2Handle(SQL_HANDLE_DBC, d->hDbc));
-}
-
-static QString qDB2Warn(const QDB2ResultPrivate* d)
-{
- 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));
-}
-
-static void qSqlWarning(const QString& message, const QDB2DriverPrivate* d)
-{
- qWarning("%s\tError: %s", message.toLocal8Bit().constData(),
- qDB2Warn(d).toLocal8Bit().constData());
-}
-
-static void qSqlWarning(const QString& message, const QDB2ResultPrivate* d)
-{
- qWarning("%s\tError: %s", message.toLocal8Bit().constData(),
- qDB2Warn(d).toLocal8Bit().constData());
-}
-
-static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
- const QDB2DriverPrivate* p)
-{
- return QSqlError(QLatin1String("QDB2: ") + err, qDB2Warn(p), type);
-}
-
-static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
- const QDB2ResultPrivate* p)
-{
- return QSqlError(QLatin1String("QDB2: ") + err, qDB2Warn(p), type);
-}
-
-static QVariant::Type qDecodeDB2Type(SQLSMALLINT sqltype)
-{
- QVariant::Type type = QVariant::Invalid;
- switch (sqltype) {
- case SQL_REAL:
- case SQL_FLOAT:
- case SQL_DOUBLE:
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- type = QVariant::Double;
- break;
- case SQL_SMALLINT:
- case SQL_INTEGER:
- case SQL_BIT:
- case SQL_TINYINT:
- type = QVariant::Int;
- break;
- case SQL_BIGINT:
- type = QVariant::LongLong;
- break;
- case SQL_BLOB:
- case SQL_BINARY:
- case SQL_VARBINARY:
- case SQL_LONGVARBINARY:
- case SQL_CLOB:
- case SQL_DBCLOB:
- type = QVariant::ByteArray;
- break;
- case SQL_DATE:
- case SQL_TYPE_DATE:
- type = QVariant::Date;
- break;
- case SQL_TIME:
- case SQL_TYPE_TIME:
- type = QVariant::Time;
- break;
- case SQL_TIMESTAMP:
- case SQL_TYPE_TIMESTAMP:
- type = QVariant::DateTime;
- break;
- case SQL_WCHAR:
- case SQL_WVARCHAR:
- case SQL_WLONGVARCHAR:
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_LONGVARCHAR:
- type = QVariant::String;
- break;
- default:
- type = QVariant::ByteArray;
- break;
- }
- return type;
-}
-
-static QSqlField qMakeFieldInfo(const QDB2ResultPrivate* d, int i)
-{
- SQLSMALLINT colNameLen;
- SQLSMALLINT colType;
- SQLUINTEGER colSize;
- SQLSMALLINT colScale;
- SQLSMALLINT nullable;
- SQLRETURN r = SQL_ERROR;
- SQLTCHAR colName[COLNAMESIZE];
- r = SQLDescribeCol(d->hStmt,
- i+1,
- colName,
- (SQLSMALLINT) COLNAMESIZE,
- &colNameLen,
- &colType,
- &colSize,
- &colScale,
- &nullable);
-
- if (r != SQL_SUCCESS) {
- qSqlWarning(QString::fromLatin1("qMakeFieldInfo: Unable to describe column %1").arg(i), d);
- return QSqlField();
- }
- QSqlField f(qFromTChar(colName), qDecodeDB2Type(colType));
- // nullable can be SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN
- if (nullable == SQL_NO_NULLS)
- f.setRequired(true);
- else if (nullable == SQL_NULLABLE)
- f.setRequired(false);
- // else required is unknown
- f.setLength(colSize == 0 ? -1 : int(colSize));
- f.setPrecision(colScale == 0 ? -1 : int(colScale));
- f.setSqlType(int(colType));
- return f;
-}
-
-static int qGetIntData(SQLHANDLE hStmt, int column, bool& isNull)
-{
- SQLINTEGER intbuf;
- isNull = false;
- SQLINTEGER lengthIndicator = 0;
- SQLRETURN r = SQLGetData(hStmt,
- column + 1,
- SQL_C_SLONG,
- (SQLPOINTER) &intbuf,
- 0,
- &lengthIndicator);
- if ((r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) || lengthIndicator == SQL_NULL_DATA) {
- isNull = true;
- return 0;
- }
- return int(intbuf);
-}
-
-static double qGetDoubleData(SQLHANDLE hStmt, int column, bool& isNull)
-{
- SQLDOUBLE dblbuf;
- isNull = false;
- SQLINTEGER lengthIndicator = 0;
- SQLRETURN r = SQLGetData(hStmt,
- column+1,
- SQL_C_DOUBLE,
- (SQLPOINTER) &dblbuf,
- 0,
- &lengthIndicator);
- if ((r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) || lengthIndicator == SQL_NULL_DATA) {
- isNull = true;
- return 0.0;
- }
-
- return (double) dblbuf;
-}
-
-static SQLBIGINT qGetBigIntData(SQLHANDLE hStmt, int column, bool& isNull)
-{
- SQLBIGINT lngbuf = Q_INT64_C(0);
- isNull = false;
- SQLINTEGER lengthIndicator = 0;
- SQLRETURN r = SQLGetData(hStmt,
- column+1,
- SQL_C_SBIGINT,
- (SQLPOINTER) &lngbuf,
- 0,
- &lengthIndicator);
- if ((r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) || lengthIndicator == SQL_NULL_DATA)
- isNull = true;
-
- return lngbuf;
-}
-
-static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& isNull)
-{
- QString fieldVal;
- SQLRETURN r = SQL_ERROR;
- SQLINTEGER lengthIndicator = 0;
-
- if (colSize <= 0)
- colSize = 255;
- else if (colSize > 65536) // limit buffer size to 64 KB
- colSize = 65536;
- else
- colSize++; // make sure there is room for more than the 0 termination
- SQLTCHAR* buf = new SQLTCHAR[colSize];
-
- while (true) {
- r = SQLGetData(hStmt,
- column + 1,
- SQL_C_WCHAR,
- (SQLPOINTER)buf,
- colSize * sizeof(SQLTCHAR),
- &lengthIndicator);
- if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
- if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
- fieldVal.clear();
- isNull = true;
- break;
- }
- fieldVal += qFromTChar(buf);
- } else if (r == SQL_NO_DATA) {
- break;
- } else {
- qWarning("qGetStringData: Error while fetching data (%d)", r);
- fieldVal.clear();
- break;
- }
- }
- delete[] buf;
- return fieldVal;
-}
-
-static QByteArray qGetBinaryData(SQLHANDLE hStmt, int column, SQLINTEGER& lengthIndicator, bool& isNull)
-{
- QByteArray fieldVal;
- SQLSMALLINT colNameLen;
- SQLSMALLINT colType;
- SQLUINTEGER colSize;
- SQLSMALLINT colScale;
- SQLSMALLINT nullable;
- SQLRETURN r = SQL_ERROR;
-
- SQLTCHAR colName[COLNAMESIZE];
- r = SQLDescribeCol(hStmt,
- column+1,
- colName,
- COLNAMESIZE,
- &colNameLen,
- &colType,
- &colSize,
- &colScale,
- &nullable);
- if (r != SQL_SUCCESS)
- qWarning("qGetBinaryData: Unable to describe column %d", column);
- // SQLDescribeCol may return 0 if size cannot be determined
- if (!colSize)
- colSize = 255;
- else if (colSize > 65536) // read the field in 64 KB chunks
- colSize = 65536;
- char * buf = new char[colSize];
- while (true) {
- r = SQLGetData(hStmt,
- column+1,
- colType == SQL_DBCLOB ? SQL_C_CHAR : SQL_C_BINARY,
- (SQLPOINTER) buf,
- colSize,
- &lengthIndicator);
- if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
- if (lengthIndicator == SQL_NULL_DATA) {
- isNull = true;
- break;
- } else {
- int rSize;
- r == SQL_SUCCESS ? rSize = lengthIndicator : rSize = colSize;
- if (lengthIndicator == SQL_NO_TOTAL) // size cannot be determined
- rSize = colSize;
- fieldVal.append(QByteArray(buf, rSize));
- if (r == SQL_SUCCESS) // the whole field was read in one chunk
- break;
- }
- } else {
- break;
- }
- }
- delete [] buf;
- return fieldVal;
-}
-
-static void qSplitTableQualifier(const QString & qualifier, QString * catalog,
- QString * schema, QString * table)
-{
- if (!catalog || !schema || !table)
- return;
- QStringList l = qualifier.split(QLatin1Char('.'));
- if (l.count() > 3)
- return; // can't possibly be a valid table qualifier
- int i = 0, n = l.count();
- if (n == 1) {
- *table = qualifier;
- } else {
- for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
- if (n == 3) {
- if (i == 0)
- *catalog = *it;
- else if (i == 1)
- *schema = *it;
- else if (i == 2)
- *table = *it;
- } else if (n == 2) {
- if (i == 0)
- *schema = *it;
- else if (i == 1)
- *table = *it;
- }
- i++;
- }
- }
-}
-
-// creates a QSqlField from a valid hStmt generated
-// by SQLColumns. The hStmt has to point to a valid position.
-static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt)
-{
- bool isNull;
- int type = qGetIntData(hStmt, 4, isNull);
- QSqlField f(qGetStringData(hStmt, 3, -1, isNull), qDecodeDB2Type(type));
- int required = qGetIntData(hStmt, 10, isNull); // nullable-flag
- // required can be SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN
- if (required == SQL_NO_NULLS)
- f.setRequired(true);
- else if (required == SQL_NULLABLE)
- f.setRequired(false);
- // else we don't know.
- f.setLength(qGetIntData(hStmt, 6, isNull)); // column size
- f.setPrecision(qGetIntData(hStmt, 8, isNull)); // precision
- f.setSqlType(type);
- return f;
-}
-
-static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwardOnly = true)
-{
- SQLRETURN r;
- if (!d->hStmt) {
- r = SQLAllocHandle(SQL_HANDLE_STMT,
- d->drv_d_func()->hDbc,
- &d->hStmt);
- if (r != SQL_SUCCESS) {
- qSqlWarning(QLatin1String("QDB2Result::reset: Unable to allocate statement handle"), d);
- return false;
- }
- } else {
- r = SQLFreeStmt(d->hStmt, SQL_CLOSE);
- if (r != SQL_SUCCESS) {
- qSqlWarning(QLatin1String("QDB2Result::reset: Unable to close statement handle"), d);
- return false;
- }
- }
-
- if (!setForwardOnly)
- return true;
-
- if (forwardOnly) {
- r = SQLSetStmtAttr(d->hStmt,
- SQL_ATTR_CURSOR_TYPE,
- (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY,
- SQL_IS_UINTEGER);
- } else {
- r = SQLSetStmtAttr(d->hStmt,
- SQL_ATTR_CURSOR_TYPE,
- (SQLPOINTER) SQL_CURSOR_STATIC,
- SQL_IS_UINTEGER);
- }
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- qSqlWarning(QString::fromLatin1("QDB2Result::reset: Unable to set %1 attribute.").arg(
- forwardOnly ? QLatin1String("SQL_CURSOR_FORWARD_ONLY")
- : QLatin1String("SQL_CURSOR_STATIC")), d);
- return false;
- }
- return true;
-}
-
-QVariant QDB2Result::handle() const
-{
- Q_D(const QDB2Result);
- return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
-}
-
-/************************************/
-
-QDB2Result::QDB2Result(const QDB2Driver *drv)
- : QSqlResult(*new QDB2ResultPrivate(this, drv))
-{
-}
-
-QDB2Result::~QDB2Result()
-{
- Q_D(const QDB2Result);
- if (d->hStmt) {
- SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
- + QString::number(r), d);
- }
-}
-
-bool QDB2Result::reset (const QString& query)
-{
- Q_D(QDB2Result);
- setActive(false);
- setAt(QSql::BeforeFirstRow);
- SQLRETURN r;
-
- d->recInf.clear();
- d->emptyValueCache();
-
- if (!qMakeStatement(d, isForwardOnly()))
- return false;
-
- r = SQLExecDirect(d->hStmt,
- qToTChar(query),
- (SQLINTEGER) query.length());
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to execute statement"), QSqlError::StatementError, d));
- return false;
- }
- SQLSMALLINT count = 0;
- r = SQLNumResultCols(d->hStmt, &count);
- if (count) {
- setSelect(true);
- for (int i = 0; i < count; ++i) {
- d->recInf.append(qMakeFieldInfo(d, i));
- }
- } else {
- setSelect(false);
- }
- d->valueCache.resize(count);
- d->valueCache.fill(NULL);
- setActive(true);
- return true;
-}
-
-bool QDB2Result::prepare(const QString& query)
-{
- Q_D(QDB2Result);
- setActive(false);
- setAt(QSql::BeforeFirstRow);
- SQLRETURN r;
-
- d->recInf.clear();
- d->emptyValueCache();
-
- if (!qMakeStatement(d, isForwardOnly()))
- return false;
-
- r = SQLPrepare(d->hStmt,
- qToTChar(query),
- (SQLINTEGER) query.length());
-
- if (r != SQL_SUCCESS) {
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to prepare statement"), QSqlError::StatementError, d));
- return false;
- }
- return true;
-}
-
-bool QDB2Result::exec()
-{
- Q_D(QDB2Result);
- QList<QByteArray> tmpStorage; // holds temporary ptrs
- QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count());
-
- memset(indicators.data(), 0, indicators.size() * sizeof(SQLINTEGER));
- setActive(false);
- setAt(QSql::BeforeFirstRow);
- SQLRETURN r;
-
- d->recInf.clear();
- d->emptyValueCache();
-
- if (!qMakeStatement(d, isForwardOnly(), false))
- return false;
-
-
- QVector<QVariant> &values = boundValues();
- int i;
- for (i = 0; i < values.count(); ++i) {
- // bind parameters - only positional binding allowed
- SQLINTEGER *ind = &indicators[i];
- if (values.at(i).isNull())
- *ind = SQL_NULL_DATA;
- if (bindValueType(i) & QSql::Out)
- values[i].detach();
-
- switch (values.at(i).type()) {
- case QVariant::Date: {
- QByteArray ba;
- ba.resize(sizeof(DATE_STRUCT));
- DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData();
- QDate qdt = values.at(i).toDate();
- dt->year = qdt.year();
- dt->month = qdt.month();
- dt->day = qdt.day();
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_DATE,
- SQL_DATE,
- 0,
- 0,
- (void *) dt,
- 0,
- *ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
- break; }
- case QVariant::Time: {
- QByteArray ba;
- ba.resize(sizeof(TIME_STRUCT));
- TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData();
- QTime qdt = values.at(i).toTime();
- dt->hour = qdt.hour();
- dt->minute = qdt.minute();
- dt->second = qdt.second();
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_TIME,
- SQL_TIME,
- 0,
- 0,
- (void *) dt,
- 0,
- *ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
- break; }
- case QVariant::DateTime: {
- QByteArray ba;
- ba.resize(sizeof(TIMESTAMP_STRUCT));
- TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData();
- QDateTime qdt = values.at(i).toDateTime();
- dt->year = qdt.date().year();
- dt->month = qdt.date().month();
- dt->day = qdt.date().day();
- dt->hour = qdt.time().hour();
- dt->minute = qdt.time().minute();
- dt->second = qdt.time().second();
- dt->fraction = qdt.time().msec() * 1000000;
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_TIMESTAMP,
- SQL_TIMESTAMP,
- 0,
- 0,
- (void *) dt,
- 0,
- *ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
- break; }
- case QVariant::Int:
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_SLONG,
- SQL_INTEGER,
- 0,
- 0,
- (void *)values.at(i).constData(),
- 0,
- *ind == SQL_NULL_DATA ? ind : NULL);
- break;
- case QVariant::Double:
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_DOUBLE,
- SQL_DOUBLE,
- 0,
- 0,
- (void *)values.at(i).constData(),
- 0,
- *ind == SQL_NULL_DATA ? ind : NULL);
- break;
- case QVariant::ByteArray: {
- int len = values.at(i).toByteArray().size();
- if (*ind != SQL_NULL_DATA)
- *ind = len;
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_BINARY,
- SQL_LONGVARBINARY,
- len,
- 0,
- (void *)values.at(i).toByteArray().constData(),
- len,
- ind);
- break; }
- case QVariant::String:
- {
- QString str(values.at(i).toString());
- if (*ind != SQL_NULL_DATA)
- *ind = str.length() * sizeof(QChar);
- if (bindValueType(i) & QSql::Out) {
- QByteArray ba((char*)str.utf16(), str.capacity() * sizeof(QChar));
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_WCHAR,
- SQL_WVARCHAR,
- str.length(),
- 0,
- (void *)ba.constData(),
- ba.size(),
- ind);
- tmpStorage.append(ba);
- } else {
- void *data = (void*)str.utf16();
- int len = str.length();
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_WCHAR,
- SQL_WVARCHAR,
- len,
- 0,
- data,
- len * sizeof(QChar),
- ind);
- }
- break;
- }
- default: {
- QByteArray ba = values.at(i).toString().toLatin1();
- int len = ba.length() + 1;
- if (*ind != SQL_NULL_DATA)
- *ind = ba.length();
- r = SQLBindParameter(d->hStmt,
- i + 1,
- qParamType[bindValueType(i) & 3],
- SQL_C_CHAR,
- SQL_VARCHAR,
- len,
- 0,
- (void *) ba.constData(),
- len,
- ind);
- tmpStorage.append(ba);
- break; }
- }
- if (r != SQL_SUCCESS) {
- qWarning("QDB2Result::exec: unable to bind variable: %s",
- qDB2Warn(d).toLocal8Bit().constData());
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to bind variable"), QSqlError::StatementError, d));
- return false;
- }
- }
-
- r = SQLExecute(d->hStmt);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- qWarning("QDB2Result::exec: Unable to execute statement: %s",
- qDB2Warn(d).toLocal8Bit().constData());
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to execute statement"), QSqlError::StatementError, d));
- return false;
- }
- SQLSMALLINT count = 0;
- r = SQLNumResultCols(d->hStmt, &count);
- if (count) {
- setSelect(true);
- for (int i = 0; i < count; ++i) {
- d->recInf.append(qMakeFieldInfo(d, i));
- }
- } else {
- setSelect(false);
- }
- setActive(true);
- d->valueCache.resize(count);
- d->valueCache.fill(NULL);
-
- //get out parameters
- if (!hasOutValues())
- return true;
-
- for (i = 0; i < values.count(); ++i) {
- switch (values[i].type()) {
- case QVariant::Date: {
- DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.takeFirst().constData());
- values[i] = QVariant(QDate(ds.year, ds.month, ds.day));
- break; }
- case QVariant::Time: {
- TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.takeFirst().constData());
- values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second));
- break; }
- case QVariant::DateTime: {
- TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT *)tmpStorage.takeFirst().constData());
- values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day),
- QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
- break; }
- case QVariant::Int:
- case QVariant::Double:
- case QVariant::ByteArray:
- break;
- case QVariant::String:
- if (bindValueType(i) & QSql::Out)
- values[i] = QString((const QChar *)tmpStorage.takeFirst().constData());
- break;
- default: {
- values[i] = QString::fromLatin1(tmpStorage.takeFirst().constData());
- break; }
- }
- if (indicators[i] == SQL_NULL_DATA)
- values[i] = QVariant(values[i].type());
- }
- return true;
-}
-
-bool QDB2Result::fetch(int i)
-{
- Q_D(QDB2Result);
- if (isForwardOnly() && i < at())
- return false;
- if (i == at())
- return true;
- d->clearValueCache();
- int actualIdx = i + 1;
- if (actualIdx <= 0) {
- setAt(QSql::BeforeFirstRow);
- return false;
- }
- SQLRETURN r;
- if (isForwardOnly()) {
- bool ok = true;
- while (ok && i > at())
- ok = fetchNext();
- return ok;
- } else {
- r = SQLFetchScroll(d->hStmt,
- SQL_FETCH_ABSOLUTE,
- actualIdx);
- }
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) {
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to fetch record %1").arg(i), QSqlError::StatementError, d));
- return false;
- }
- else if (r == SQL_NO_DATA)
- return false;
- setAt(i);
- return true;
-}
-
-bool QDB2Result::fetchNext()
-{
- Q_D(QDB2Result);
- SQLRETURN r;
- d->clearValueCache();
- r = SQLFetchScroll(d->hStmt,
- SQL_FETCH_NEXT,
- 0);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- if (r != SQL_NO_DATA)
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
- "Unable to fetch next"), QSqlError::StatementError, d));
- return false;
- }
- setAt(at() + 1);
- return true;
-}
-
-bool QDB2Result::fetchFirst()
-{
- Q_D(QDB2Result);
- if (isForwardOnly() && at() != QSql::BeforeFirstRow)
- return false;
- if (isForwardOnly())
- return fetchNext();
- d->clearValueCache();
- SQLRETURN r;
- r = SQLFetchScroll(d->hStmt,
- SQL_FETCH_FIRST,
- 0);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- if(r!= SQL_NO_DATA)
- setLastError(qMakeError(QCoreApplication::translate("QDB2Result", "Unable to fetch first"),
- QSqlError::StatementError, d));
- return false;
- }
- setAt(0);
- return true;
-}
-
-bool QDB2Result::fetchLast()
-{
- Q_D(QDB2Result);
- d->clearValueCache();
-
- int i = at();
- if (i == QSql::AfterLastRow) {
- if (isForwardOnly()) {
- return false;
- } else {
- if (!fetch(0))
- return false;
- i = at();
- }
- }
-
- while (fetchNext())
- ++i;
-
- if (i == QSql::BeforeFirstRow) {
- setAt(QSql::AfterLastRow);
- return false;
- }
-
- if (!isForwardOnly())
- return fetch(i);
-
- setAt(i);
- return true;
-}
-
-
-QVariant QDB2Result::data(int field)
-{
- Q_D(QDB2Result);
- if (field >= d->recInf.count()) {
- qWarning("QDB2Result::data: column %d out of range", field);
- return QVariant();
- }
- SQLRETURN r = 0;
- SQLINTEGER lengthIndicator = 0;
- bool isNull = false;
- const QSqlField info = d->recInf.field(field);
-
- if (!info.isValid() || field >= d->valueCache.size())
- return QVariant();
-
- if (d->valueCache[field])
- return *d->valueCache[field];
-
-
- QVariant* v = 0;
- switch (info.type()) {
- case QVariant::LongLong:
- v = new QVariant((qint64) qGetBigIntData(d->hStmt, field, isNull));
- break;
- case QVariant::Int:
- v = new QVariant(qGetIntData(d->hStmt, field, isNull));
- break;
- case QVariant::Date: {
- DATE_STRUCT dbuf;
- r = SQLGetData(d->hStmt,
- field + 1,
- SQL_C_DATE,
- (SQLPOINTER) &dbuf,
- 0,
- &lengthIndicator);
- if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) {
- v = new QVariant(QDate(dbuf.year, dbuf.month, dbuf.day));
- } else {
- v = new QVariant(QDate());
- isNull = true;
- }
- break; }
- case QVariant::Time: {
- TIME_STRUCT tbuf;
- r = SQLGetData(d->hStmt,
- field + 1,
- SQL_C_TIME,
- (SQLPOINTER) &tbuf,
- 0,
- &lengthIndicator);
- if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) {
- v = new QVariant(QTime(tbuf.hour, tbuf.minute, tbuf.second));
- } else {
- v = new QVariant(QTime());
- isNull = true;
- }
- break; }
- case QVariant::DateTime: {
- TIMESTAMP_STRUCT dtbuf;
- r = SQLGetData(d->hStmt,
- field + 1,
- SQL_C_TIMESTAMP,
- (SQLPOINTER) &dtbuf,
- 0,
- &lengthIndicator);
- if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) {
- v = new QVariant(QDateTime(QDate(dtbuf.year, dtbuf.month, dtbuf.day),
- QTime(dtbuf.hour, dtbuf.minute, dtbuf.second, dtbuf.fraction / 1000000)));
- } else {
- v = new QVariant(QDateTime());
- isNull = true;
- }
- break; }
- case QVariant::ByteArray:
- v = new QVariant(qGetBinaryData(d->hStmt, field, lengthIndicator, isNull));
- break;
- case QVariant::Double:
- {
- switch(numericalPrecisionPolicy()) {
- case QSql::LowPrecisionInt32:
- v = new QVariant(qGetIntData(d->hStmt, field, isNull));
- break;
- case QSql::LowPrecisionInt64:
- v = new QVariant((qint64) qGetBigIntData(d->hStmt, field, isNull));
- break;
- case QSql::LowPrecisionDouble:
- v = new QVariant(qGetDoubleData(d->hStmt, field, isNull));
- break;
- case QSql::HighPrecision:
- default:
- // length + 1 for the comma
- v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull));
- break;
- }
- break;
- }
- case QVariant::String:
- default:
- v = new QVariant(qGetStringData(d->hStmt, field, info.length(), isNull));
- break;
- }
- if (isNull)
- *v = QVariant(info.type());
- d->valueCache[field] = v;
- return *v;
-}
-
-bool QDB2Result::isNull(int i)
-{
- Q_D(const QDB2Result);
- if (i >= d->valueCache.size())
- return true;
-
- if (d->valueCache[i])
- return d->valueCache[i]->isNull();
- return data(i).isNull();
-}
-
-int QDB2Result::numRowsAffected()
-{
- Q_D(const QDB2Result);
- SQLINTEGER affectedRowCount = 0;
- SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
- if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
- return affectedRowCount;
- else
- qSqlWarning(QLatin1String("QDB2Result::numRowsAffected: Unable to count affected rows"), d);
- return -1;
-}
-
-int QDB2Result::size()
-{
- return -1;
-}
-
-QSqlRecord QDB2Result::record() const
-{
- Q_D(const QDB2Result);
- if (isActive())
- return d->recInf;
- return QSqlRecord();
-}
-
-bool QDB2Result::nextResult()
-{
- Q_D(QDB2Result);
- setActive(false);
- setAt(QSql::BeforeFirstRow);
- d->recInf.clear();
- d->emptyValueCache();
- setSelect(false);
-
- SQLRETURN r = SQLMoreResults(d->hStmt);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- if (r != SQL_NO_DATA) {
- setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
- "Unable to fetch last"), QSqlError::ConnectionError, d));
- }
- return false;
- }
-
- SQLSMALLINT fieldCount = 0;
- r = SQLNumResultCols(d->hStmt, &fieldCount);
- setSelect(fieldCount > 0);
- for (int i = 0; i < fieldCount; ++i)
- d->recInf.append(qMakeFieldInfo(d, i));
-
- d->valueCache.resize(fieldCount);
- d->valueCache.fill(NULL);
- setActive(true);
-
- return true;
-}
-
-void QDB2Result::virtual_hook(int id, void *data)
-{
- QSqlResult::virtual_hook(id, data);
-}
-
-void QDB2Result::detachFromResultSet()
-{
- Q_D(QDB2Result);
- if (d->hStmt)
- SQLCloseCursor(d->hStmt);
-}
-
-/************************************/
-
-QDB2Driver::QDB2Driver(QObject* parent)
- : QSqlDriver(*new QDB2DriverPrivate, parent)
-{
-}
-
-QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent)
- : QSqlDriver(*new QDB2DriverPrivate, parent)
-{
- Q_D(QDB2Driver);
- d->hEnv = reinterpret_cast<intptr_t>(env);
- d->hDbc = reinterpret_cast<intptr_t>(con);
- if (env && con) {
- setOpen(true);
- setOpenError(false);
- }
-}
-
-QDB2Driver::~QDB2Driver()
-{
- close();
-}
-
-bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
- const QString& connOpts)
-{
- Q_D(QDB2Driver);
- if (isOpen())
- close();
- SQLRETURN r;
- r = SQLAllocHandle(SQL_HANDLE_ENV,
- SQL_NULL_HANDLE,
- &d->hEnv);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- qSqlWarning(QLatin1String("QDB2Driver::open: Unable to allocate environment"), d);
- setOpenError(true);
- return false;
- }
-
- r = SQLAllocHandle(SQL_HANDLE_DBC,
- d->hEnv,
- &d->hDbc);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- qSqlWarning(QLatin1String("QDB2Driver::open: Unable to allocate connection"), d);
- setOpenError(true);
- return false;
- }
-
- QString protocol;
- // Set connection attributes
- const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
- for (int i = 0; i < opts.count(); ++i) {
- const QString tmp(opts.at(i));
- int idx;
- if ((idx = tmp.indexOf(QLatin1Char('='))) == -1) {
- qWarning("QDB2Driver::open: Illegal connect option value '%s'",
- tmp.toLocal8Bit().constData());
- continue;
- }
-
- const QString opt(tmp.left(idx));
- const QString val(tmp.mid(idx + 1).simplified());
-
- SQLUINTEGER v = 0;
- r = SQL_SUCCESS;
- if (opt == QLatin1String("SQL_ATTR_ACCESS_MODE")) {
- if (val == QLatin1String("SQL_MODE_READ_ONLY")) {
- v = SQL_MODE_READ_ONLY;
- } else if (val == QLatin1String("SQL_MODE_READ_WRITE")) {
- v = SQL_MODE_READ_WRITE;
- } else {
- qWarning("QDB2Driver::open: Unknown option value '%s'",
- tmp.toLocal8Bit().constData());
- continue;
- }
- r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_ACCESS_MODE, reinterpret_cast<SQLPOINTER>(v), 0);
- } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) {
- v = val.toUInt();
- r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast<SQLPOINTER>(v), 0);
- } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) {
- protocol = tmp;
- }
- else {
- qWarning("QDB2Driver::open: Unknown connection attribute '%s'",
- tmp.toLocal8Bit().constData());
- }
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)
- qSqlWarning(QString::fromLatin1("QDB2Driver::open: "
- "Unable to set connection attribute '%1'").arg(opt), d);
- }
-
- if (protocol.isEmpty())
- protocol = QLatin1String("PROTOCOL=TCPIP");
-
- if (port < 0 )
- port = 50000;
-
- QString connQStr;
- connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host
- + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user
- + QLatin1String(";PWD=") + password;
-
-
- SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH];
- SQLSMALLINT cb;
-
- r = SQLDriverConnect(d->hDbc,
- NULL,
- qToTChar(connQStr),
- (SQLSMALLINT) connQStr.length(),
- connOut,
- SQL_MAX_OPTION_STRING_LENGTH,
- &cb,
- SQL_DRIVER_NOPROMPT);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- setLastError(qMakeError(tr("Unable to connect"),
- QSqlError::ConnectionError, d));
- setOpenError(true);
- return false;
- }
-
- d->user = user;
- setOpen(true);
- setOpenError(false);
- return true;
-}
-
-void QDB2Driver::close()
-{
- Q_D(QDB2Driver);
- SQLRETURN r;
- if (d->hDbc) {
- // Open statements/descriptors handles are automatically cleaned up by SQLDisconnect
- if (isOpen()) {
- r = SQLDisconnect(d->hDbc);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver::close: Unable to disconnect datasource"), d);
- }
- r = SQLFreeHandle(SQL_HANDLE_DBC, d->hDbc);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver::close: Unable to free connection handle"), d);
- d->hDbc = 0;
- }
-
- if (d->hEnv) {
- r = SQLFreeHandle(SQL_HANDLE_ENV, d->hEnv);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver::close: Unable to free environment handle"), d);
- d->hEnv = 0;
- }
- setOpen(false);
- setOpenError(false);
-}
-
-QSqlResult *QDB2Driver::createResult() const
-{
- return new QDB2Result(this);
-}
-
-QSqlRecord QDB2Driver::record(const QString& tableName) const
-{
- Q_D(const QDB2Driver);
- QSqlRecord fil;
- if (!isOpen())
- return fil;
-
- SQLHANDLE hStmt;
- QString catalog, schema, table;
- qSplitTableQualifier(tableName, &catalog, &schema, &table);
- if (schema.isEmpty())
- schema = d->user;
-
- if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
- catalog = stripDelimiters(catalog, QSqlDriver::TableName);
- else
- catalog = catalog.toUpper();
-
- if (isIdentifierEscaped(schema, QSqlDriver::TableName))
- schema = stripDelimiters(schema, QSqlDriver::TableName);
- else
- schema = schema.toUpper();
-
- if (isIdentifierEscaped(table, QSqlDriver::TableName))
- table = stripDelimiters(table, QSqlDriver::TableName);
- else
- table = table.toUpper();
-
- SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
- d->hDbc,
- &hStmt);
- if (r != SQL_SUCCESS) {
- qSqlWarning(QLatin1String("QDB2Driver::record: Unable to allocate handle"), d);
- return fil;
- }
-
- r = SQLSetStmtAttr(hStmt,
- SQL_ATTR_CURSOR_TYPE,
- (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY,
- SQL_IS_UINTEGER);
-
-
- //Aside: szSchemaName and szTableName parameters of SQLColumns
- //are case sensitive search patterns, so no escaping is used.
- r = SQLColumns(hStmt,
- NULL,
- 0,
- qToTChar(schema),
- schema.length(),
- qToTChar(table),
- table.length(),
- NULL,
- 0);
-
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver::record: Unable to execute column list"), d);
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
- while (r == SQL_SUCCESS) {
- fil.append(qMakeFieldInfo(hStmt));
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
- }
-
- r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
- + QString::number(r), d);
-
- return fil;
-}
-
-QStringList QDB2Driver::tables(QSql::TableType type) const
-{
- Q_D(const QDB2Driver);
- QStringList tl;
- if (!isOpen())
- return tl;
-
- SQLHANDLE hStmt;
-
- SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
- d->hDbc,
- &hStmt);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
- qSqlWarning(QLatin1String("QDB2Driver::tables: Unable to allocate handle"), d);
- return tl;
- }
- r = SQLSetStmtAttr(hStmt,
- SQL_ATTR_CURSOR_TYPE,
- (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
- SQL_IS_UINTEGER);
-
- QString tableType;
- if (type & QSql::Tables)
- tableType += QLatin1String("TABLE,");
- if (type & QSql::Views)
- tableType += QLatin1String("VIEW,");
- if (type & QSql::SystemTables)
- tableType += QLatin1String("SYSTEM TABLE,");
- if (tableType.isEmpty())
- return tl;
- tableType.chop(1);
-
- r = SQLTables(hStmt,
- NULL,
- 0,
- NULL,
- 0,
- NULL,
- 0,
- qToTChar(tableType),
- tableType.length());
-
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)
- qSqlWarning(QLatin1String("QDB2Driver::tables: Unable to execute table list"), d);
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
- while (r == SQL_SUCCESS) {
- bool isNull;
- QString fieldVal = qGetStringData(hStmt, 2, -1, isNull);
- QString userVal = qGetStringData(hStmt, 1, -1, isNull);
- QString user = d->user;
- if ( isIdentifierEscaped(user, QSqlDriver::TableName))
- user = stripDelimiters(user, QSqlDriver::TableName);
- else
- user = user.toUpper();
-
- if (userVal != user)
- fieldVal = userVal + QLatin1Char('.') + fieldVal;
- tl.append(fieldVal);
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
- }
-
- r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
- if (r != SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver::tables: Unable to free statement handle ")
- + QString::number(r), d);
- return tl;
-}
-
-QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const
-{
- Q_D(const QDB2Driver);
- QSqlIndex index(tablename);
- if (!isOpen())
- return index;
- QSqlRecord rec = record(tablename);
-
- SQLHANDLE hStmt;
- SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
- d->hDbc,
- &hStmt);
- if (r != SQL_SUCCESS) {
- qSqlWarning(QLatin1String("QDB2Driver::primaryIndex: Unable to list primary key"), d);
- return index;
- }
- QString catalog, schema, table;
- qSplitTableQualifier(tablename, &catalog, &schema, &table);
-
- if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
- catalog = stripDelimiters(catalog, QSqlDriver::TableName);
- else
- catalog = catalog.toUpper();
-
- if (isIdentifierEscaped(schema, QSqlDriver::TableName))
- schema = stripDelimiters(schema, QSqlDriver::TableName);
- else
- schema = schema.toUpper();
-
- if (isIdentifierEscaped(table, QSqlDriver::TableName))
- table = stripDelimiters(table, QSqlDriver::TableName);
- else
- table = table.toUpper();
-
- r = SQLSetStmtAttr(hStmt,
- SQL_ATTR_CURSOR_TYPE,
- (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
- SQL_IS_UINTEGER);
-
- r = SQLPrimaryKeys(hStmt,
- NULL,
- 0,
- qToTChar(schema),
- schema.length(),
- qToTChar(table),
- table.length());
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
-
- bool isNull;
- QString cName, idxName;
- // Store all fields in a StringList because the driver can't detail fields in this FETCH loop
- while (r == SQL_SUCCESS) {
- cName = qGetStringData(hStmt, 3, -1, isNull); // column name
- idxName = qGetStringData(hStmt, 5, -1, isNull); // pk index name
- index.append(rec.field(cName));
- index.setName(idxName);
- r = SQLFetchScroll(hStmt,
- SQL_FETCH_NEXT,
- 0);
- }
- r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
- if (r!= SQL_SUCCESS)
- qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
- + QString::number(r), d);
- return index;
-}
-
-bool QDB2Driver::hasFeature(DriverFeature f) const
-{
- switch (f) {
- case QuerySize:
- case NamedPlaceholders:
- case BatchOperations:
- case LastInsertId:
- case SimpleLocking:
- case EventNotifications:
- case CancelQuery:
- return false;
- case BLOB:
- case Transactions:
- case MultipleResultSets:
- case PreparedQueries:
- case PositionalPlaceholders:
- case LowPrecisionNumbers:
- case FinishQuery:
- return true;
- case Unicode:
- return true;
- }
- return false;
-}
-
-bool QDB2Driver::beginTransaction()
-{
- if (!isOpen()) {
- qWarning("QDB2Driver::beginTransaction: Database not open");
- return false;
- }
- return setAutoCommit(false);
-}
-
-bool QDB2Driver::commitTransaction()
-{
- Q_D(QDB2Driver);
- if (!isOpen()) {
- qWarning("QDB2Driver::commitTransaction: Database not open");
- return false;
- }
- SQLRETURN r = SQLEndTran(SQL_HANDLE_DBC,
- d->hDbc,
- SQL_COMMIT);
- if (r != SQL_SUCCESS) {
- setLastError(qMakeError(tr("Unable to commit transaction"),
- QSqlError::TransactionError, d));
- return false;
- }
- return setAutoCommit(true);
-}
-
-bool QDB2Driver::rollbackTransaction()
-{
- Q_D(QDB2Driver);
- if (!isOpen()) {
- qWarning("QDB2Driver::rollbackTransaction: Database not open");
- return false;
- }
- SQLRETURN r = SQLEndTran(SQL_HANDLE_DBC,
- d->hDbc,
- SQL_ROLLBACK);
- if (r != SQL_SUCCESS) {
- setLastError(qMakeError(tr("Unable to rollback transaction"),
- QSqlError::TransactionError, d));
- return false;
- }
- return setAutoCommit(true);
-}
-
-bool QDB2Driver::setAutoCommit(bool autoCommit)
-{
- Q_D(QDB2Driver);
- SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
- SQLRETURN r = SQLSetConnectAttr(d->hDbc,
- SQL_ATTR_AUTOCOMMIT,
- reinterpret_cast<SQLPOINTER>(ac),
- sizeof(ac));
- if (r != SQL_SUCCESS) {
- setLastError(qMakeError(tr("Unable to set autocommit"),
- QSqlError::TransactionError, d));
- return false;
- }
- return true;
-}
-
-QString QDB2Driver::formatValue(const QSqlField &field, bool trimStrings) const
-{
- if (field.isNull())
- return QLatin1String("NULL");
-
- switch (field.type()) {
- case QVariant::DateTime: {
- // Use an escape sequence for the datetime fields
- if (field.value().toDateTime().isValid()) {
- QDate dt = field.value().toDateTime().date();
- QTime tm = field.value().toDateTime().time();
- // Dateformat has to be "yyyy-MM-dd hh:mm:ss", with leading zeroes if month or day < 10
- return QLatin1Char('\'') + QString::number(dt.year()) + QLatin1Char('-')
- + QString::number(dt.month()) + QLatin1Char('-')
- + QString::number(dt.day()) + QLatin1Char('-')
- + QString::number(tm.hour()) + QLatin1Char('.')
- + QString::number(tm.minute()).rightJustified(2, QLatin1Char('0'), true)
- + QLatin1Char('.')
- + QString::number(tm.second()).rightJustified(2, QLatin1Char('0'), true)
- + QLatin1Char('.')
- + QString::number(tm.msec() * 1000).rightJustified(6, QLatin1Char('0'), true)
- + QLatin1Char('\'');
- } else {
- return QLatin1String("NULL");
- }
- }
- case QVariant::ByteArray: {
- QByteArray ba = field.value().toByteArray();
- QString res = QString::fromLatin1("BLOB(X'");
- static const char hexchars[] = "0123456789abcdef";
- for (int i = 0; i < ba.size(); ++i) {
- uchar s = (uchar) ba[i];
- res += QLatin1Char(hexchars[s >> 4]);
- res += QLatin1Char(hexchars[s & 0x0f]);
- }
- res += QLatin1String("')");
- return res;
- }
- default:
- return QSqlDriver::formatValue(field, trimStrings);
- }
-}
-
-QVariant QDB2Driver::handle() const
-{
- Q_D(const QDB2Driver);
- return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
-}
-
-QString QDB2Driver::escapeIdentifier(const QString &identifier, IdentifierType) const
-{
- QString res = identifier;
- if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
- res.replace(QLatin1Char('"'), QLatin1String("\"\""));
- res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
- res.replace(QLatin1Char('.'), QLatin1String("\".\""));
- }
- return res;
-}
-
-QT_END_NAMESPACE
diff --git a/src/sql/drivers/db2/qsql_db2.pri b/src/sql/drivers/db2/qsql_db2.pri
deleted file mode 100644
index c9e65e2c2e..0000000000
--- a/src/sql/drivers/db2/qsql_db2.pri
+++ /dev/null
@@ -1,8 +0,0 @@
-HEADERS += $$PWD/qsql_db2_p.h
-SOURCES += $$PWD/qsql_db2.cpp
-
-unix {
- !contains(LIBS, .*db2.*):LIBS += -ldb2
-} else {
- !contains(LIBS, .*db2.*):LIBS += -ldb2cli
-}
diff --git a/src/sql/drivers/db2/qsql_db2_p.h b/src/sql/drivers/db2/qsql_db2_p.h
deleted file mode 100644
index fa6d739479..0000000000
--- a/src/sql/drivers/db2/qsql_db2_p.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtSql module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSQL_DB2_H
-#define QSQL_DB2_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#ifdef QT_PLUGIN
-#define Q_EXPORT_SQLDRIVER_DB2
-#else
-#define Q_EXPORT_SQLDRIVER_DB2 Q_SQL_EXPORT
-#endif
-
-#include <QtSql/qsqldriver.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDB2DriverPrivate;
-
-class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver
-{
- Q_DECLARE_PRIVATE(QDB2Driver)
- Q_OBJECT
- friend class QDB2ResultPrivate;
-
-public:
- explicit QDB2Driver(QObject* parent = 0);
- QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0);
- ~QDB2Driver();
- bool hasFeature(DriverFeature) const Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
- QSqlRecord record(const QString &tableName) const Q_DECL_OVERRIDE;
- QStringList tables(QSql::TableType type) const Q_DECL_OVERRIDE;
- QSqlResult *createResult() const Q_DECL_OVERRIDE;
- QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE;
- bool beginTransaction() Q_DECL_OVERRIDE;
- bool commitTransaction() Q_DECL_OVERRIDE;
- bool rollbackTransaction() Q_DECL_OVERRIDE;
- QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE;
- QVariant handle() const Q_DECL_OVERRIDE;
- bool open(const QString &db,
- const QString &user,
- const QString &password,
- const QString &host,
- int port,
- const QString& connOpts) Q_DECL_OVERRIDE;
- QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
-
-private:
- bool setAutoCommit(bool autoCommit);
-};
-
-QT_END_NAMESPACE
-
-#endif // QSQL_DB2_H