summaryrefslogtreecommitdiffstats
path: root/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qsqldatabase/tst_qsqldatabase.cpp')
-rw-r--r--tests/auto/qsqldatabase/tst_qsqldatabase.cpp239
1 files changed, 174 insertions, 65 deletions
diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
index a3a4712..13cb3be 100644
--- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
@@ -86,6 +86,8 @@ private slots:
void open();
void tables_data() { generic_data(); }
void tables();
+ void oci_tables_data() { generic_data("QOCI"); }
+ void oci_tables();
void transaction_data() { generic_data(); }
void transaction();
void eventNotification_data() { generic_data(); }
@@ -157,6 +159,8 @@ private slots:
void mysqlOdbc_unsignedIntegers();
void mysql_multiselect_data() { generic_data("QMYSQL"); }
void mysql_multiselect(); // For task 144331
+ void mysql_savepointtest_data() { generic_data("QMYSQL"); }
+ void mysql_savepointtest();
void accessOdbc_strings_data() { generic_data(); }
void accessOdbc_strings();
@@ -189,6 +193,8 @@ private slots:
void oci_xmltypeSupport();
void oci_fieldLength_data() { generic_data("QOCI"); }
void oci_fieldLength();
+ void oci_synonymstest_data() { generic_data("QOCI"); }
+ void oci_synonymstest();
void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE"); }
void sqlite_bindAndFetchUInt();
@@ -251,7 +257,7 @@ struct FieldDef {
// excluding the primary key field
static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
{
- tst_Databases::safeDropTables(db, QStringList() << qTableName("qtestfields"));
+ tst_Databases::safeDropTable(db, qTableName("qtestfields"));
QSqlQuery q(db);
// construct a create table statement consisting of all fieldtypes
QString qs = "create table " + qTableName("qtestfields");
@@ -300,10 +306,11 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
// ### stupid workaround until we find a way to hardcode this
// in the MySQL server startup script
q.exec("set table_type=innodb");
- if (tst_Databases::isSqlServer(db)) {
+ else if (tst_Databases::isSqlServer(db)) {
QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON"));
QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF"));
- }
+ } else if(tst_Databases::isPostgreSQL(db))
+ QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
// please never ever change this table; otherwise fix all tests ;)
if (tst_Databases::isMSAccess(db)) {
@@ -330,6 +337,12 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
{
if (!db.isValid())
return;
+
+ if(tst_Databases::isPostgreSQL(db)) {
+ QSqlQuery q(db);
+ QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
+ }
+
// drop the view first, otherwise we'll get dependency problems
tst_Databases::safeDropViews(db, QStringList() << qTableName("qtest_view") << qTableName("qtest_view2"));
@@ -356,13 +369,22 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
<< qTableName("bug_249059");
QSqlQuery q(0, db);
- if (db.driverName().startsWith("QPSQL"))
+ if (db.driverName().startsWith("QPSQL")) {
q.exec("drop schema " + qTableName("qtestschema") + " cascade");
+ q.exec("drop schema " + qTableName("qtestScHeMa") + " cascade");
+ }
if (testWhiteSpaceNames(db.driverName()))
- tableNames << (qTableName("qtest") + " test");
+ tableNames << db.driver()->escapeIdentifier(qTableName("qtest") + " test", QSqlDriver::TableName);
tst_Databases::safeDropTables(db, tableNames);
+
+ if (db.driverName().startsWith("QOCI")) {
+ q.exec("drop user "+qTableName("CREATOR")+" cascade");
+ q.exec("drop user "+qTableName("APPUSER")+" cascade");
+ q.exec("DROP TABLE system."+qTableName("mypassword"));
+
+ }
}
void tst_QSqlDatabase::populateTestTables(QSqlDatabase db)
@@ -511,10 +533,6 @@ void tst_QSqlDatabase::tables()
QVERIFY(tables.contains(qTableName("qtest"), Qt::CaseInsensitive));
QVERIFY(!tables.contains("sql_features", Qt::CaseInsensitive)); //check for postgres 7.4 internal tables
if (views) {
- if (db.driverName().startsWith("QMYSQL"))
- // MySQL doesn't differentiate between tables and views when calling QSqlDatabase::tables()
- // May be fixable by doing a select on informational_schema.tables instead of using the client library api
- QEXPECT_FAIL("", "MySQL driver thinks that views are tables", Continue);
QVERIFY(!tables.contains(qTableName("qtest_view"), Qt::CaseInsensitive));
}
if (tempTables)
@@ -522,10 +540,6 @@ void tst_QSqlDatabase::tables()
tables = db.tables(QSql::Views);
if (views) {
- if (db.driverName().startsWith("QMYSQL"))
- // MySQL doesn't give back anything when calling QSqlDatabase::tables() with QSql::Views
- // May be fixable by doing a select on informational_schema.views instead of using the client library api
- QEXPECT_FAIL("", "MySQL driver thinks that views are tables", Continue);
if(!tables.contains(qTableName("qtest_view"), Qt::CaseInsensitive))
qDebug() << "failed to find" << qTableName("qtest_view") << "in" << tables;
QVERIFY(tables.contains(qTableName("qtest_view"), Qt::CaseInsensitive));
@@ -546,11 +560,6 @@ void tst_QSqlDatabase::tables()
QVERIFY(tables.contains(qTableName("temp_tab"), Qt::CaseInsensitive));
QVERIFY(tables.contains(qTableName("qtest"), Qt::CaseInsensitive));
- if (tst_Databases::isMSAccess(db))
- QSqlQuery("drop table " + qTableName("qtest_view"), db);
- else
- QSqlQuery("drop view " + qTableName("qtest_view"), db);
-
if (db.driverName().startsWith("QPSQL")) {
QVERIFY(tables.contains(qTableName("qtest") + " test"));
}
@@ -566,19 +575,19 @@ void tst_QSqlDatabase::whitespaceInIdentifiers()
QString tableName = qTableName("qtest") + " test";
QVERIFY(db.tables().contains(tableName, Qt::CaseInsensitive));
- QSqlRecord rec = db.record(tableName);
+ QSqlRecord rec = db.record(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName));
QCOMPARE(rec.count(), 1);
QCOMPARE(rec.fieldName(0), QString("test test"));
if(db.driverName().startsWith("QOCI"))
- QCOMPARE(rec.field(0).type(), QVariant::String);
+ QCOMPARE(rec.field(0).type(), QVariant::Double);
else
QCOMPARE(rec.field(0).type(), QVariant::Int);
- QSqlIndex idx = db.primaryIndex(tableName);
+ QSqlIndex idx = db.primaryIndex(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName));
QCOMPARE(idx.count(), 1);
QCOMPARE(idx.fieldName(0), QString("test test"));
if(db.driverName().startsWith("QOCI"))
- QCOMPARE(idx.field(0).type(), QVariant::String);
+ QCOMPARE(idx.field(0).type(), QVariant::Double);
else
QCOMPARE(idx.field(0).type(), QVariant::Int);
} else {
@@ -759,9 +768,7 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db)
rec->setValue(fieldDefs[ i ].fieldName(), fieldDefs[ i ].val);
// qDebug(QString("inserting %1 into %2").arg(fieldDefs[ i ].val.toString()).arg(fieldDefs[ i ].fieldName()));
}
- if (!cur.insert()) {
- QFAIL(QString("Couldn't insert record: %1 %2").arg(cur.lastError().databaseText()).arg(cur.lastError().driverText()));
- }
+ QVERIFY_SQL(cur, insert());
cur.setForwardOnly(true);
QVERIFY_SQL(cur, select("id = " + QString::number(pkey - 1)));
QVERIFY_SQL(cur, next());
@@ -793,8 +800,8 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db)
if (val1.type() == QVariant::DateTime || val1.type() == QVariant::Time)
qDebug("Received Time: " + val1.toTime().toString("hh:mm:ss.zzz"));
QFAIL(QString(" Expected: '%1' Received: '%2' for field %3 (etype %4 rtype %5) in checkValues").arg(
- val2.toString()).arg(
- val1.toString()).arg(
+ val2.type() == QVariant::ByteArray ? val2.toByteArray().toHex() : val2.toString()).arg(
+ val1.type() == QVariant::ByteArray ? val1.toByteArray().toHex() : val1.toString()).arg(
fieldDefs[ i ].fieldName()).arg(
val2.typeName()).arg(
val1.typeName())
@@ -824,9 +831,7 @@ void tst_QSqlDatabase::checkNullValues(const FieldDef fieldDefs[], QSqlDatabase
else
rec->setValue(fieldDefs[ i ].fieldName(), fieldDefs[ i ].val);
}
- if (!cur.insert()) {
- QFAIL(QString("Couldn't insert record: %1 %2").arg(cur.lastError().databaseText()).arg(cur.lastError().driverText()));
- }
+ QVERIFY_SQL(cur, insert());
cur.setForwardOnly(true);
QVERIFY_SQL(cur, select("id = " + QString::number(pkey - 1)));
QVERIFY_SQL(cur, next());
@@ -926,22 +931,20 @@ void tst_QSqlDatabase::recordOCI()
FieldDef("varchar(20)", QVariant::String, QString("blah2")),
FieldDef("nchar(20)", QVariant::String, QString("blah3")),
FieldDef("nvarchar2(20)", QVariant::String, QString("blah4")),
- FieldDef("number(10,5)", QVariant::String, 1.1234567),
+ FieldDef("number(10,5)", QVariant::Double, 1.1234567),
FieldDef("date", QVariant::DateTime, dt),
-#ifdef QT3_SUPPORT
-//X? FieldDef("long raw", QVariant::ByteArray, QByteArray(Q3CString("blah5"))),
- FieldDef("raw(2000)", QVariant::ByteArray, QByteArray(Q3CString("blah6")), false),
- FieldDef("blob", QVariant::ByteArray, QByteArray(Q3CString("blah7"))),
-#endif
-//FIXME FieldDef("clob", QVariant::CString, Q3CString("blah8")),
-//FIXME FieldDef("nclob", QVariant::CString, Q3CString("blah9")),
-//X FieldDef("bfile", QVariant::ByteArray, QByteArray(Q3CString("blah10"))),
+ FieldDef("long raw", QVariant::ByteArray, QByteArray("blah5")),
+ FieldDef("raw(2000)", QVariant::ByteArray, QByteArray("blah6"), false),
+ FieldDef("blob", QVariant::ByteArray, QByteArray("blah7")),
+ FieldDef("clob", QVariant::String, QString("blah8")),
+ FieldDef("nclob", QVariant::String, QString("blah9")),
+ FieldDef("bfile", QVariant::ByteArray, QByteArray("blah10")),
intytm,
- intdts,
- tsdef,
- tstzdef,
- tsltzdef,
+// intdts,
+// tsdef,
+// tstzdef,
+// tsltzdef,
FieldDef()
};
@@ -1020,6 +1023,10 @@ void tst_QSqlDatabase::recordPSQL()
};
QSqlQuery q(db);
+
+ if(tst_Databases::isPostgreSQL(db))
+ QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
+
q.exec("drop sequence " + qTableName("qtestfields") + "_t_bigserial_seq");
q.exec("drop sequence " + qTableName("qtestfields") + "_t_serial_seq");
// older psql cut off the table name
@@ -1062,17 +1069,20 @@ void tst_QSqlDatabase::recordMySQL()
int revision = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 2, 2 ).toInt();
int vernum = (major << 16) + (minor << 8) + revision;
-#ifdef QT3_SUPPORT
/* The below is broken in mysql below 5.0.15
see http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html
specifically: Before MySQL 5.0.15, the pad value is space. Values are right-padded
with space on insert, and trailing spaces are removed on select.
*/
if( vernum >= ((5 << 16) + 15) ) {
+#ifdef QT3_SUPPORT
bin10 = FieldDef("binary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abc ")));
varbin10 = FieldDef("varbinary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abcv ")));
- }
+#else
+ bin10 = FieldDef("binary(10)", QVariant::ByteArray, QString("123abc "));
+ varbin10 = FieldDef("varbinary(10)", QVariant::ByteArray, QString("123abcv "));
#endif
+ }
static QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0));
static const FieldDef fieldDefs[] = {
@@ -1088,8 +1098,8 @@ void tst_QSqlDatabase::recordMySQL()
FieldDef("bigint unsigned", QVariant::ULongLong, Q_UINT64_C(18446744073709551615)),
FieldDef("float", QVariant::Double, 1.12345),
FieldDef("double", QVariant::Double, 1.123456789),
- FieldDef("decimal(10, 9)", QVariant::String,1.123456789),
- FieldDef("numeric(5, 2)", QVariant::String, 123.67),
+ FieldDef("decimal(10, 9)", QVariant::Double,1.123456789),
+ FieldDef("numeric(5, 2)", QVariant::Double, 123.67),
FieldDef("date", QVariant::Date, QDate::currentDate()),
FieldDef("datetime", QVariant::DateTime, dt),
FieldDef("timestamp", QVariant::DateTime, dt, false),
@@ -1221,6 +1231,7 @@ void tst_QSqlDatabase::recordSQLite()
FieldDef("integer", QVariant::Int, QVariant(13)),
FieldDef("int", QVariant::Int, QVariant(12)),
+ FieldDef("real", QVariant::String, QVariant(1.234567890123456)),
FieldDef()
};
@@ -1293,9 +1304,9 @@ void tst_QSqlDatabase::recordAccess()
FieldDef("varchar(20)", QVariant::String, QString("Blah1")),
FieldDef("single", QVariant::Double, 1.12345),
FieldDef("double", QVariant::Double, 1.123456),
- FieldDef("byte", QVariant::Int, 255),
+ FieldDef("byte", QVariant::UInt, 255),
#ifdef QT3_SUPPORT
- FieldDef("binary", QVariant::ByteArray, Q3CString("Blah2")),
+ FieldDef("binary(5)", QVariant::ByteArray, Q3CString("Blah2")),
#endif
FieldDef("long", QVariant::Int, 2147483647),
FieldDef("memo", QVariant::String, memo),
@@ -1495,6 +1506,11 @@ void tst_QSqlDatabase::psql_schemas()
QSKIP("server does not support schemas", SkipSingle);
QSqlQuery q(db);
+
+ if(tst_Databases::isPostgreSQL(db)) {
+ QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
+ }
+
QVERIFY_SQL(q, exec("CREATE SCHEMA " + qTableName("qtestschema")));
QString table = qTableName("qtestschema") + '.' + qTableName("qtesttable");
@@ -1530,8 +1546,11 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
QSqlQuery q(db);
+ if(tst_Databases::isPostgreSQL(db))
+ QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
+
QString schemaName = qTableName("qtestScHeMa");
- QString tableName = qTableName("qtestTaBlE");
+ QString tableName = qTableName("qtest");
QString field1Name = QString("fIeLdNaMe");
QString field2Name = QString("ZuLu");
@@ -1549,7 +1568,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
rec.append(fld1);
rec.append(fld2);
- QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement, schemaName + '.' + tableName, rec, false)));
+ QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement, db.driver()->escapeIdentifier(schemaName, QSqlDriver::TableName) + '.' + db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName), rec, false)));
rec = q.record();
QCOMPARE(rec.count(), 2);
@@ -1644,62 +1663,83 @@ void tst_QSqlDatabase::precisionPolicy()
QSKIP("Driver or database doesn't support setting precision policy", SkipSingle);
// Create a test table with some data
- QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id smallint, num numeric(20,0))").arg(tableName)));
+ if(tst_Databases::isMSAccess(db))
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id smallint, num number)").arg(tableName)));
+ else
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id smallint, num numeric(18,5))").arg(tableName)));
QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES (?, ?)").arg(tableName)));
q.bindValue(0, 1);
q.bindValue(1, 123);
QVERIFY_SQL(q, exec());
q.bindValue(0, 2);
- q.bindValue(1, QString("18500000000000000000"));
+ q.bindValue(1, 1850000000000.0001);
QVERIFY_SQL(q, exec());
// These are expected to pass
+ q.setNumericalPrecisionPolicy(QSql::HighPrecision);
QString query = QString("SELECT num FROM %1 WHERE id = 1").arg(tableName);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
+ if(db.driverName().startsWith("QSQLITE"))
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::String);
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
+ if(q.value(0).type() != QVariant::LongLong)
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::LongLong);
QCOMPARE(q.value(0).toLongLong(), (qlonglong)123);
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32);
QVERIFY_SQL(q, exec(query));
+ if(db.driverName().startsWith("QOCI"))
+ QEXPECT_FAIL("", "Oracle fails to move to next when data columns are oversize", Abort);
QVERIFY_SQL(q, next());
+ if(db.driverName().startsWith("QSQLITE"))
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::Int);
QCOMPARE(q.value(0).toInt(), 123);
q.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
+ if(db.driverName().startsWith("QSQLITE"))
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::Double);
QCOMPARE(q.value(0).toDouble(), (double)123);
query = QString("SELECT num FROM %1 WHERE id = 2").arg(tableName);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
+ if(db.driverName().startsWith("QSQLITE"))
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::Double);
- QCOMPARE(q.value(0).toDouble(), QString("18500000000000000000").toDouble());
+ QCOMPARE(q.value(0).toDouble(), QString("1850000000000.0001").toDouble());
// Postgres returns invalid QVariants on overflow
q.setNumericalPrecisionPolicy(QSql::HighPrecision);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
+ if(db.driverName().startsWith("QSQLITE"))
+ QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
QCOMPARE(q.value(0).type(), QVariant::String);
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64);
+ QEXPECT_FAIL("QOCI", "Oracle fails here, to retrieve next", Continue);
QVERIFY_SQL(q, exec(query));
QVERIFY_SQL(q, next());
- QCOMPARE(q.value(0).type(), QVariant::Invalid);
+ QCOMPARE(q.value(0).type(), QVariant::LongLong);
- q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32);
- QVERIFY_SQL(q, exec(query));
- if(db.driverName().startsWith("QOCI"))
- QEXPECT_FAIL("", "Oracle fails to move to next when data columns are oversize", Abort);
- QVERIFY_SQL(q, next());
- QCOMPARE(q.value(0).type(), QVariant::Invalid);
+ QSql::NumericalPrecisionPolicy oldPrecision= db.numericalPrecisionPolicy();
+ db.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64);
+ QSqlQuery q2(db);
+ q2.exec(QString("SELECT num FROM %1 WHERE id = 2").arg(tableName));
+ QVERIFY_SQL(q2, exec(query));
+ QVERIFY_SQL(q2, next());
+ QCOMPARE(q2.value(0).type(), QVariant::LongLong);
+ db.setNumericalPrecisionPolicy(oldPrecision);
}
// This test needs a ODBC data source containing MYSQL in it's name
@@ -1986,6 +2026,11 @@ void tst_QSqlDatabase::odbc_bindBoolean()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ if (tst_Databases::isMySQL(db)) {
+ QSKIP("MySql has inconsistent behaviour of bit field type across versions.", SkipSingle);
+ return;
+ }
+
QSqlQuery q(db);
QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtestBindBool") + "(id int, boolvalue bit)"));
@@ -2017,6 +2062,8 @@ void tst_QSqlDatabase::odbc_testqGetString()
QSqlQuery q(db);
if (tst_Databases::isSqlServer(db))
QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("testqGetString") + "(id int, vcvalue varchar(MAX))"));
+ else if(tst_Databases::isMSAccess(db))
+ QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("testqGetString") + "(id int, vcvalue memo)"));
else
QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("testqGetString") + "(id int, vcvalue varchar(65538))"));
@@ -2154,6 +2201,36 @@ void tst_QSqlDatabase::oci_fieldLength()
QCOMPARE(q.record().field(1).length(), 40);
}
+void tst_QSqlDatabase::oci_synonymstest()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlQuery q(db);
+ QString creator(qTableName("CREATOR")), appuser(qTableName("APPUSER")), table1(qTableName("TABLE1"));
+// QVERIFY_SQL(q, exec("drop public synonym "+table1));
+ QVERIFY_SQL(q, exec(QString("create user %1 identified by %2 default tablespace users temporary tablespace temp").arg(creator).arg(creator)));
+ QVERIFY_SQL(q, exec(QString("grant CONNECT to %1").arg(creator)));
+ QVERIFY_SQL(q, exec(QString("grant RESOURCE to %1").arg(creator)));
+ QSqlDatabase db2=db.cloneDatabase(db, QLatin1String("oci_synonymstest"));
+ db2.close();
+ QVERIFY_SQL(db2, open(creator,creator));
+ QSqlQuery q2(db2);
+ QVERIFY_SQL(q2, exec(QString("create table %1(id int primary key)").arg(table1)));
+ QVERIFY_SQL(q, exec(QString("create user %1 identified by %2 default tablespace users temporary tablespace temp").arg(appuser).arg(appuser)));
+ QVERIFY_SQL(q, exec(QString("grant CREATE ANY SYNONYM to %1").arg(appuser)));
+ QVERIFY_SQL(q, exec(QString("grant CONNECT to %1").arg(appuser)));
+ QVERIFY_SQL(q2, exec(QString("grant select, insert, update, delete on %1 to %2").arg(table1).arg(appuser)));
+ QSqlDatabase db3=db.cloneDatabase(db, QLatin1String("oci_synonymstest2"));
+ db3.close();
+ QVERIFY_SQL(db3, open(appuser,appuser));
+ QSqlQuery q3(db3);
+ QVERIFY_SQL(q3, exec("create synonym "+appuser+'.'+qTableName("synonyms")+" for "+creator+'.'+table1));
+ QVERIFY_SQL(db3, tables().filter(qTableName("synonyms"), Qt::CaseInsensitive).count() >= 1);
+}
+
+
// This test isn't really necessary as SQL_GUID / uniqueidentifier is
// already tested in recordSQLServer().
void tst_QSqlDatabase::odbc_uniqueidentifier()
@@ -2213,7 +2290,10 @@ void tst_QSqlDatabase::odbc_uintfield()
unsigned int val = 4294967295U;
QSqlQuery q(db);
- q.exec(QString("CREATE TABLE %1(num numeric(10))").arg(tableName));
+ if ( tst_Databases::isMSAccess( db ) )
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num number)").arg(tableName)));
+ else
+ QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(num numeric(10))").arg(tableName)));
q.prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName));
q.addBindValue(val);
QVERIFY_SQL(q, exec());
@@ -2299,18 +2379,22 @@ void tst_QSqlDatabase::eventNotificationPSQL()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+#if defined(Q_OS_LINUX)
+ QSKIP( "Event support doesn't work on linux", SkipAll );
+#endif
+
QSqlQuery query(db);
QString procedureName = qTableName("posteventProc");
- QSqlDriver *driver=db.driver();
- QVERIFY_SQL(*driver, subscribeToNotification(procedureName));
+ QSqlDriver &driver=*(db.driver());
+ QVERIFY_SQL(driver, subscribeToNotification(procedureName));
QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&)));
query.exec(QString("NOTIFY \"%1\"").arg(procedureName));
QCoreApplication::processEvents();
QCOMPARE(spy.count(), 1);
QList<QVariant> arguments = spy.takeFirst();
QVERIFY(arguments.at(0).toString() == procedureName);
- QVERIFY_SQL(*driver, unsubscribeFromNotification(procedureName));
+ QVERIFY_SQL(driver, unsubscribeFromNotification(procedureName));
}
void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
@@ -2380,6 +2464,31 @@ void tst_QSqlDatabase::sqlStatementUseIsNull_189093()
QCOMPARE(statment.count("IS NULL", Qt::CaseInsensitive), 2);
}
+void tst_QSqlDatabase::mysql_savepointtest()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if ( db.driverName().startsWith( "QMYSQL" ) && tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 1 ).toDouble()<4.1 )
+ QSKIP( "Test requires MySQL >= 4.1", SkipSingle );
+
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("begin"));
+ QVERIFY_SQL(q, exec("insert into "+qTableName("qtest")+" VALUES (54, 'foo', 'foo', 54.54)"));
+ QVERIFY_SQL(q, exec("savepoint foo"));
+}
+
+void tst_QSqlDatabase::oci_tables()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ QSqlQuery q(db);
+ QString systemTableName("system."+qTableName("mypassword"));
+ QVERIFY_SQL(q, exec("CREATE TABLE "+systemTableName+"(name VARCHAR(20))"));
+ QVERIFY(!db.tables().contains(systemTableName.toUpper()));
+ QVERIFY(db.tables(QSql::SystemTables).contains(systemTableName.toUpper()));
+}
QTEST_MAIN(tst_QSqlDatabase)
#include "tst_qsqldatabase.moc"