summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers/db2/qsql_db2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/drivers/db2/qsql_db2.cpp')
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp105
1 files changed, 87 insertions, 18 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 69383f7..11d0041 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -49,6 +49,7 @@
#include <qstringlist.h>
#include <qvarlengtharray.h>
#include <qvector.h>
+#include <QDebug>
#ifndef UNICODE
#define UNICODE
@@ -87,8 +88,19 @@ public:
{}
~QDB2ResultPrivate()
{
- for (int i = 0; i < valueCache.count(); ++i)
+ emptyValueCache();
+ }
+ void clearValueCache()
+ {
+ for (int i = 0; i < valueCache.count(); ++i) {
delete valueCache[i];
+ valueCache[i] = NULL;
+ }
+ }
+ void emptyValueCache()
+ {
+ clearValueCache();
+ valueCache.clear();
}
const QDB2DriverPrivate* dp;
@@ -544,7 +556,7 @@ bool QDB2Result::reset (const QString& query)
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly()))
return false;
@@ -568,6 +580,7 @@ bool QDB2Result::reset (const QString& query)
setSelect(false);
}
d->valueCache.resize(count);
+ d->valueCache.fill(NULL);
setActive(true);
return true;
}
@@ -579,7 +592,7 @@ bool QDB2Result::prepare(const QString& query)
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly()))
return false;
@@ -607,7 +620,7 @@ bool QDB2Result::exec()
SQLRETURN r;
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
if (!qMakeStatement(d, isForwardOnly(), false))
return false;
@@ -811,6 +824,7 @@ bool QDB2Result::exec()
}
setActive(true);
d->valueCache.resize(count);
+ d->valueCache.fill(NULL);
//get out parameters
if (!hasOutValues())
@@ -858,7 +872,7 @@ bool QDB2Result::fetch(int i)
return false;
if (i == at())
return true;
- d->valueCache.fill(0);
+ d->clearValueCache();
int actualIdx = i + 1;
if (actualIdx <= 0) {
setAt(QSql::BeforeFirstRow);
@@ -887,7 +901,7 @@ bool QDB2Result::fetch(int i)
bool QDB2Result::fetchNext()
{
SQLRETURN r;
- d->valueCache.fill(0);
+ d->clearValueCache();
r = SQLFetchScroll(d->hStmt,
SQL_FETCH_NEXT,
0);
@@ -907,7 +921,7 @@ bool QDB2Result::fetchFirst()
return false;
if (isForwardOnly())
return fetchNext();
- d->valueCache.fill(0);
+ d->clearValueCache();
SQLRETURN r;
r = SQLFetchScroll(d->hStmt,
SQL_FETCH_FIRST,
@@ -923,7 +937,7 @@ bool QDB2Result::fetchFirst()
bool QDB2Result::fetchLast()
{
- d->valueCache.fill(0);
+ d->clearValueCache();
int i = at();
if (i == QSql::AfterLastRow) {
@@ -1044,7 +1058,7 @@ QVariant QDB2Result::data(int field)
case QSql::HighPrecision:
default:
// length + 1 for the comma
- v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull));
+ v = new QVariant(value);
ok = true;
break;
}
@@ -1101,7 +1115,7 @@ bool QDB2Result::nextResult()
setActive(false);
setAt(QSql::BeforeFirstRow);
d->recInf.clear();
- d->valueCache.clear();
+ d->emptyValueCache();
setSelect(false);
SQLRETURN r = SQLMoreResults(d->hStmt);
@@ -1120,6 +1134,7 @@ bool QDB2Result::nextResult()
d->recInf.append(qMakeFieldInfo(d, i));
d->valueCache.resize(fieldCount);
+ d->valueCache.fill(NULL);
setActive(true);
return true;
@@ -1167,7 +1182,7 @@ QDB2Driver::~QDB2Driver()
delete d;
}
-bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int,
+bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
const QString& connOpts)
{
if (isOpen())
@@ -1190,6 +1205,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
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) {
@@ -1220,7 +1237,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
} else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) {
v = val.toUInt();
r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0);
- } else {
+ } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) {
+ protocol = tmp;
+ }
+ else {
qWarning("QDB2Driver::open: Unknown connection attribute '%s'",
tmp.toLocal8Bit().constData());
}
@@ -1229,9 +1249,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
"Unable to set connection attribute '%1'").arg(opt), d);
}
+ if (protocol.isEmpty())
+ protocol = QLatin1String("PROTOCOL=TCPIP");
+
+ if (port < 0 )
+ port = 50000;
+
QString connQStr;
- connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=")
- + password;
+ 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;
@@ -1250,7 +1279,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
return false;
}
- d->user = user.toUpper();
+ d->user = user;
setOpen(true);
setOpenError(false);
return true;
@@ -1295,10 +1324,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
SQLHANDLE hStmt;
QString catalog, schema, table;
- qSplitTableQualifier(tableName.toUpper(), &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);
@@ -1312,6 +1356,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
(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,
@@ -1392,7 +1439,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const
bool isNull;
QString fieldVal = qGetStringData(hStmt, 2, -1, isNull);
QString userVal = qGetStringData(hStmt, 1, -1, isNull);
- if (userVal != d->user)
+ 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,
@@ -1423,7 +1476,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const
return index;
}
QString catalog, schema, table;
- qSplitTableQualifier(tablename.toUpper(), &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,