summaryrefslogtreecommitdiffstats
path: root/src/sql
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-06-22 08:38:59 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-06-22 08:38:59 (GMT)
commit252ea664604c85a5e993d28ee32d2aa0da7eca85 (patch)
tree0819bdd6e3614048faa8f2739299fb4be4301795 /src/sql
parent31ac8ea4a7a5360a01c2fc1f8f930ae8b236c94b (diff)
parentfe48ca11f7da7200c052a7825ad4d46319b13cc5 (diff)
downloadQt-252ea664604c85a5e993d28ee32d2aa0da7eca85.zip
Qt-252ea664604c85a5e993d28ee32d2aa0da7eca85.tar.gz
Qt-252ea664604c85a5e993d28ee32d2aa0da7eca85.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
Conflicts: doc/src/qnamespace.qdoc src/corelib/global/qnamespace.h src/gui/graphicsview/qgraphicsscene.cpp
Diffstat (limited to 'src/sql')
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp91
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp52
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp3
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp2
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp1
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp32
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp18
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp2
-rw-r--r--src/sql/drivers/tds/qsql_tds.cpp21
-rw-r--r--src/sql/kernel/qsqlcachedresult.cpp13
-rw-r--r--src/sql/kernel/qsqlcachedresult_p.h1
-rw-r--r--src/sql/kernel/qsqlresult.cpp2
-rw-r--r--src/sql/models/qsqltablemodel.cpp20
13 files changed, 210 insertions, 48 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index b6ca82d..1a82377 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -1043,26 +1043,22 @@ QVariant QDB2Result::data(int field)
case QVariant::Double:
{
QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull);
- bool ok=false;
- switch(d->precisionPolicy) {
+ switch(numericalPrecisionPolicy()) {
case QSql::LowPrecisionInt32:
- v = new QVariant(value.toInt(&ok));
+ v = new QVariant(qGetIntData(d->hStmt, field, isNull));
break;
case QSql::LowPrecisionInt64:
- v = new QVariant(value.toLongLong(&ok));
+ v = new QVariant(qGetBigIntData(d->hStmt, field, isNull));
break;
case QSql::LowPrecisionDouble:
- v = new QVariant(value.toDouble(&ok));
+ v = new QVariant(qGetDoubleData(d->hStmt, field, isNull));
break;
case QSql::HighPrecision:
default:
// length + 1 for the comma
- v = new QVariant(value);
- ok = true;
+ v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull));
break;
}
- if(!ok)
- v = new QVariant();
break;
}
case QVariant::String:
@@ -1146,6 +1142,10 @@ void QDB2Result::virtual_hook(int id, void *data)
Q_ASSERT(data);
*static_cast<bool*>(data) = nextResult();
break;
+ case QSqlResult::DetachFromResultSet:
+ if (d->hStmt)
+ SQLCloseCursor(d->hStmt);
+ break;
default:
QSqlResult::virtual_hook(id, data);
}
@@ -1177,7 +1177,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())
@@ -1200,6 +1200,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) {
@@ -1230,7 +1232,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());
}
@@ -1239,9 +1244,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;
@@ -1260,7 +1274,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;
@@ -1305,10 +1319,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);
@@ -1322,6 +1351,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,
@@ -1402,7 +1434,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,
@@ -1433,7 +1471,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,
@@ -1477,7 +1531,6 @@ bool QDB2Driver::hasFeature(DriverFeature f) const
case BatchOperations:
case LastInsertId:
case SimpleLocking:
- case LowPrecisionNumbers:
case EventNotifications:
return false;
case BLOB:
@@ -1485,6 +1538,8 @@ bool QDB2Driver::hasFeature(DriverFeature f) const
case MultipleResultSets:
case PreparedQueries:
case PositionalPlaceholders:
+ case LowPrecisionNumbers:
+ case FinishQuery:
return true;
case Unicode:
// this is the query that shows the codepage for the types:
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index 0698f26..d714327 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -1103,6 +1103,19 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
// null value
QVariant v;
v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0));
+ if(v.type() == QVariant::Double) {
+ switch(numericalPrecisionPolicy()) {
+ case QSql::LowPrecisionInt32:
+ v.convert(QVariant::Int);
+ break;
+ case QSql::LowPrecisionInt64:
+ v.convert(QVariant::LongLong);
+ break;
+ case QSql::HighPrecision:
+ v.convert(QVariant::String);
+ break;
+ }
+ }
row[idx] = v;
continue;
}
@@ -1168,6 +1181,27 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
row[idx] = QVariant();
break;
}
+ if (d->sqlda->sqlvar[i].sqlscale < 0) {
+ QVariant v = row[idx];
+ switch(numericalPrecisionPolicy()) {
+ case QSql::LowPrecisionInt32:
+ if(v.convert(QVariant::Int))
+ row[idx]=v;
+ break;
+ case QSql::LowPrecisionInt64:
+ if(v.convert(QVariant::LongLong))
+ row[idx]=v;
+ break;
+ case QSql::LowPrecisionDouble:
+ if(v.convert(QVariant::Double))
+ row[idx]=v;
+ break;
+ case QSql::HighPrecision:
+ if(v.convert(QVariant::String))
+ row[idx]=v;
+ break;
+ }
+ }
}
return true;
@@ -1339,7 +1373,6 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const
case LastInsertId:
case BatchOperations:
case SimpleLocking:
- case LowPrecisionNumbers:
case FinishQuery:
case MultipleResultSets:
return false;
@@ -1349,6 +1382,7 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const
case Unicode:
case BLOB:
case EventNotifications:
+ case LowPrecisionNumbers:
return true;
}
return false;
@@ -1558,12 +1592,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const
QSqlQuery q(createResult());
q.setForwardOnly(true);
-
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+ else
+ table = table.toUpper();
q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, "
"b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG "
"FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
"WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
- "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' "
+ "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' "
"ORDER BY a.RDB$FIELD_POSITION"));
while (q.next()) {
@@ -1591,12 +1629,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const
if (!isOpen())
return index;
+ QString tablename = table;
+ if (isIdentifierEscaped(tablename, QSqlDriver::TableName))
+ tablename = stripDelimiters(tablename, QSqlDriver::TableName);
+ else
+ tablename = tablename.toUpper();
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE "
"FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d "
"WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
- "AND a.RDB$RELATION_NAME = '") + table.toUpper() +
+ "AND a.RDB$RELATION_NAME = '") + tablename +
QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME "
"AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME "
"AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME "
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 46726a5..bfd65fc 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -254,6 +254,9 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
case FIELD_TYPE_FLOAT :
case FIELD_TYPE_DOUBLE :
case FIELD_TYPE_DECIMAL :
+#if defined(FIELD_TYPE_NEWDECIMAL)
+ case FIELD_TYPE_NEWDECIMAL:
+#endif
type = QVariant::Double;
break;
case FIELD_TYPE_DATE :
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index ca4b286..d5fb10f 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -1899,7 +1899,7 @@ void QOCIResult::virtual_hook(int id, void *data)
QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data));
break;
default:
- QSqlResult::virtual_hook(id, data);
+ QSqlCachedResult::virtual_hook(id, data);
}
}
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 164e82c..3658ff3 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -598,6 +598,7 @@ QChar QODBCDriverPrivate::quoteChar() const
return quote;
}
+
bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
{
// Set any connection attributes
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index db09e93..1ab8214 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -891,6 +891,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QString schema;
qSplitTableName(tbl, schema);
+ if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+ else
+ tbl = tbl.toLower();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toLower();
+
switch(d->pro) {
case QPSQLDriver::Version6:
stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname "
@@ -923,7 +933,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
"FROM pg_attribute, pg_class "
"WHERE %1 pg_class.oid IN "
"(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN "
- " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) "
+ " (SELECT oid FROM pg_class WHERE relname = '%2')) "
"AND pg_attribute.attrelid = pg_class.oid "
"AND pg_attribute.attisdropped = false "
"ORDER BY pg_attribute.attnum");
@@ -931,11 +941,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND"));
else
stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower()));
+ "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema));
break;
}
- i.exec(stmt.arg(tbl.toLower()));
+ i.exec(stmt.arg(tbl));
while (i.isActive() && i.next()) {
QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt()));
idx.append(f);
@@ -954,6 +964,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString schema;
qSplitTableName(tbl, schema);
+ if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+ else
+ tbl = tbl.toLower();
+
+ if (isIdentifierEscaped(schema, QSqlDriver::TableName))
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ else
+ schema = schema.toLower();
+
QString stmt;
switch(d->pro) {
case QPSQLDriver::Version6:
@@ -998,7 +1018,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
"left join pg_attrdef on (pg_attrdef.adrelid = "
"pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
"where %1 "
- "and lower(pg_class.relname) = '%2' "
+ "and pg_class.relname = '%2' "
"and pg_attribute.attnum > 0 "
"and pg_attribute.attrelid = pg_class.oid "
"and pg_attribute.attisdropped = false "
@@ -1007,12 +1027,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)"));
else
stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower()));
+ "pg_namespace where pg_namespace.nspname = '%1')").arg(schema));
break;
}
QSqlQuery query(createResult());
- query.exec(stmt.arg(tbl.toLower()));
+ query.exec(stmt.arg(tbl));
if (d->pro >= QPSQLDriver::Version71) {
while (query.next()) {
int len = query.value(3).toInt();
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 1a05873..8e1091b 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -289,7 +289,7 @@ void QSQLiteResult::virtual_hook(int id, void *data)
sqlite3_reset(d->stmt);
break;
default:
- QSqlResult::virtual_hook(id, data);
+ QSqlCachedResult::virtual_hook(id, data);
}
}
@@ -656,9 +656,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const
if (!isOpen())
return QSqlIndex();
+ QString table = tblname;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
- return qGetTableInfo(q, tblname, true);
+ return qGetTableInfo(q, table, true);
}
QSqlRecord QSQLiteDriver::record(const QString &tbl) const
@@ -666,9 +670,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const
if (!isOpen())
return QSqlRecord();
+ QString table = tbl;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QSqlQuery q(createResult());
q.setForwardOnly(true);
- return qGetTableInfo(q, tbl);
+ return qGetTableInfo(q, table);
}
QVariant QSQLiteDriver::handle() const
@@ -676,10 +684,10 @@ QVariant QSQLiteDriver::handle() const
return qVariantFromValue(d->access);
}
-QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const
+QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
{
QString res = identifier;
- if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
+ if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) {
res.replace(QLatin1Char('"'), QLatin1String("\"\""));
res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
res.replace(QLatin1Char('.'), QLatin1String("\".\""));
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index 790c1ef..1989c45 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -260,7 +260,7 @@ void QSQLite2Result::virtual_hook(int id, void *data)
d->finalize();
break;
default:
- QSqlResult::virtual_hook(id, data);
+ QSqlCachedResult::virtual_hook(id, data);
}
}
diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp
index 5ddc4e4..e100863 100644
--- a/src/sql/drivers/tds/qsql_tds.cpp
+++ b/src/sql/drivers/tds/qsql_tds.cpp
@@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
// insert d in error handler dict
errs()->insert(d->dbproc, d);
+ dbcmd(d->dbproc, "set quoted_identifier on");
+ dbsqlexec(d->dbproc);
}
QTDSResult::~QTDSResult()
@@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
if (qIsNull(d->buffer.at(i * 2 + 1)))
values[idx] = QVariant(QVariant::String);
else
- values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2));
+ values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed();
break;
case QVariant::ByteArray: {
if (qIsNull(d->buffer.at(i * 2 + 1)))
@@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const
return info;
QSqlQuery t(createResult());
t.setForwardOnly(true);
+
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
QString stmt (QLatin1String("select name, type, length, prec from syscolumns "
"where id = (select id from sysobjects where name = '%1')"));
- t.exec(stmt.arg(tablename));
+ t.exec(stmt.arg(table));
while (t.next()) {
QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt()));
f.setLength(t.value(2).toInt());
@@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const
{
QSqlRecord rec = record(tablename);
- QSqlIndex idx(tablename);
- if ((!isOpen()) || (tablename.isEmpty()))
+ QString table = tablename;
+ if (isIdentifierEscaped(table, QSqlDriver::TableName))
+ table = stripDelimiters(table, QSqlDriver::TableName);
+
+ QSqlIndex idx(table);
+ if ((!isOpen()) || (table.isEmpty()))
return QSqlIndex();
QSqlQuery t(createResult());
t.setForwardOnly(true);
- t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename));
+ t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table));
if (t.next()) {
QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(','));
QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*"));
diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp
index 3cace06..ca51dc0 100644
--- a/src/sql/kernel/qsqlcachedresult.cpp
+++ b/src/sql/kernel/qsqlcachedresult.cpp
@@ -294,4 +294,17 @@ QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
return d->cache;
}
+void QSqlCachedResult::virtual_hook(int id, void *data)
+{
+ switch (id) {
+ case QSqlResult::DetachFromResultSet:
+ case QSqlResult::SetNumericalPrecision:
+ cleanup();
+ break;
+ default:
+ QSqlResult::virtual_hook(id, data);
+ }
+}
+
+
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h
index d19435c..a384b2e 100644
--- a/src/sql/kernel/qsqlcachedresult_p.h
+++ b/src/sql/kernel/qsqlcachedresult_p.h
@@ -89,6 +89,7 @@ protected:
int colCount() const;
ValueCache &cache();
+ void virtual_hook(int id, void *data);
private:
bool cacheNext();
QSqlCachedResultPrivate *d;
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 1c1595d..93c9d9f 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -905,7 +905,6 @@ QVariant QSqlResult::lastInsertId() const
*/
void QSqlResult::virtual_hook(int, void *)
{
- Q_ASSERT(false);
}
/*! \internal
@@ -971,6 +970,7 @@ void QSqlResult::detachFromResultSet()
void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
{
d->precisionPolicy = policy;
+ virtual_hook(SetNumericalPrecision, &policy);
}
/*! \internal
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 1acc846..156af26 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record)
int QSqlTableModelPrivate::nameToIndex(const QString &name) const
{
- return rec.indexOf(name);
+ QString fieldname = name;
+ if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
+ fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
+ return rec.indexOf(fieldname);
}
void QSqlTableModelPrivate::initRecordAndPrimaryIndex()
@@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName)
{
Q_D(QSqlTableModel);
clear();
- if(d->db.tables().contains(tableName.toUpper()))
- d->tableName = tableName.toUpper();
- else
- d->tableName = tableName;
+ d->tableName = tableName;
d->initRecordAndPrimaryIndex();
d->initColOffsets(d->rec.count());
@@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const
if (!f.isValid())
return s;
- QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName);
+ QString table = d->tableName;
+ //we can safely escape the field because it would have been obtained from the database
+ //and have the correct case
QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field);
s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC");
@@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record)
mrow.rec = d->rec;
mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row());
}
+ QString fieldName;
for (int i = 0; i < record.count(); ++i) {
- int idx = mrow.rec.indexOf(record.fieldName(i));
+ fieldName = record.fieldName(i);
+ if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName))
+ fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName);
+ int idx = mrow.rec.indexOf(fieldName);
if (idx == -1)
isOk = false;
else