diff options
Diffstat (limited to 'tests/auto/qsqldatabase')
-rw-r--r-- | tests/auto/qsqldatabase/qsqldatabase.pro | 5 | ||||
-rw-r--r-- | tests/auto/qsqldatabase/tst_databases.h | 79 | ||||
-rw-r--r-- | tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 79 |
3 files changed, 111 insertions, 52 deletions
diff --git a/tests/auto/qsqldatabase/qsqldatabase.pro b/tests/auto/qsqldatabase/qsqldatabase.pro index 534a2d3c4e..3bca79a1a8 100644 --- a/tests/auto/qsqldatabase/qsqldatabase.pro +++ b/tests/auto/qsqldatabase/qsqldatabase.pro @@ -5,7 +5,10 @@ QT += sql contains(QT_CONFIG, qt3support): QT += qt3support -win32:!wince*: LIBS += -lws2_32 +win32: { + !wince*: LIBS += -lws2_32 + else: LIBS += -lws2 +} wince*: { DEPLOYMENT_PLUGIN += qsqlite diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index ad70471497..f1e9d28e01 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -211,7 +211,7 @@ public: // This requires a local ODBC data source to be configured( pointing to a MySql database ) // addDb( "QODBC", "mysqlodbc", "troll", "trond" ); // addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead.nokia.troll.no" ); +// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); // addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); // addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); @@ -243,7 +243,7 @@ public: // use in-memory database to prevent local files // addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); // addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); @@ -323,42 +323,75 @@ public: QSqlQuery q( db ); QStringList dbtables=db.tables(); - foreach(const QString &tableName, tableNames) { + foreach(const QString &tableName, tableNames) + { wasDropped = true; - foreach(const QString dbtablesName, dbtables) { - if(dbtablesName.toUpper() == tableName.toUpper()) { - dbtables.removeAll(dbtablesName); - wasDropped = q.exec("drop table " + db.driver()->escapeIdentifier( dbtablesName, QSqlDriver::TableName )); - if(!wasDropped) - wasDropped = q.exec("drop table " + dbtablesName); + QString table=tableName; + if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName)) + table = db.driver()->stripDelimiters(table, QSqlDriver::TableName); + + if ( dbtables.contains( table, Qt::CaseInsensitive ) ) { + foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) { + if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) { + table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName); + wasDropped = q.exec( "drop table " + table); + dbtables.removeAll(table2); + } } } - if ( !wasDropped ) - qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables; + if ( !wasDropped ) { + qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError(); +// qWarning() << "last query:" << q.lastQuery(); +// qWarning() << "dbtables:" << dbtables; +// qWarning() << "db.tables():" << db.tables(); + } } } + static void safeDropTable( QSqlDatabase db, const QString& tableName ) + { + safeDropTables(db, QStringList() << tableName); + } + static void safeDropViews( QSqlDatabase db, const QStringList &viewNames ) { if ( isMSAccess( db ) ) // Access is sooo stupid. safeDropTables( db, viewNames ); + bool wasDropped; + QSqlQuery q( db ); QStringList dbtables=db.tables(QSql::Views); foreach(QString viewName, viewNames) { - if ( dbtables.contains( viewName, Qt::CaseInsensitive ) ) { - QSqlQuery q( "drop view " + viewName, db ); - - if ( !q.isActive() ) - qWarning() << "unable to drop view" << viewName << ':' << q.lastError().text(); - } else if ( db.driverName().startsWith( "QMYSQL" ) - && dbtables.contains( viewName, Qt::CaseInsensitive ) ) { // MySql is a bit stupid too - QSqlQuery q( "drop view " + viewName, db ); + wasDropped = true; + QString view=viewName; + if ( db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName)) + view = db.driver()->stripDelimiters(view, QSqlDriver::TableName); + + if ( dbtables.contains( view, Qt::CaseInsensitive ) ) { + foreach(const QString &view2, dbtables.filter(view, Qt::CaseInsensitive)) { + if(view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) { + view=db.driver()->escapeIdentifier(view2, QSqlDriver::TableName); + wasDropped = q.exec( "drop view " + view); + dbtables.removeAll(view); + } + } } + + if ( !wasDropped ) + qWarning() << dbToString(db) << "unable to drop view" << viewName << ':' << q.lastError(); +// << "\nlast query:" << q.lastQuery() +// << "\ndbtables:" << dbtables +// << "\ndb.tables(QSql::Views):" << db.tables(QSql::Views); } } + static void safeDropView( QSqlDatabase db, const QString& tableName ) + { + safeDropViews(db, QStringList() << tableName); + } + // returns the type name of the blob datatype for the database db. // blobSize is only used if the db doesn't have a generic blob type static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 ) @@ -397,8 +430,8 @@ public: return "IDENTITY"; /* if ( db.driverName().startsWith( "QPSQL" ) ) return "SERIAL";*/ - if ( db.driverName().startsWith( "QDB2" ) ) - return "GENERATED BY DEFAULT AS IDENTITY"; +// if ( db.driverName().startsWith( "QDB2" ) ) +// return "GENERATED BY DEFAULT AS IDENTITY"; return QString(); } @@ -450,6 +483,10 @@ public: { return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL") ); } + static bool isDB2( QSqlDatabase db ) + { + return db.driverName().startsWith("QDB2") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("db2") ); + } // -1 on fail, else Oracle version static int getOraVersion( QSqlDatabase db ) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index de4fe8f553..fe4c86e1a7 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -249,7 +249,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"); @@ -353,11 +353,13 @@ 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); } @@ -543,11 +545,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")); } @@ -563,19 +560,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 { @@ -923,7 +920,7 @@ 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"))), @@ -1085,8 +1082,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), @@ -1528,7 +1525,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers() QSqlQuery q(db); QString schemaName = qTableName("qtestScHeMa"); - QString tableName = qTableName("qtestTaBlE"); + QString tableName = qTableName("qtest"); QString field1Name = QString("fIeLdNaMe"); QString field2Name = QString("ZuLu"); @@ -1546,7 +1543,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); @@ -1641,62 +1638,84 @@ 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))); + 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); + 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::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()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); + QCOMPARE(q2.value(0).type(), QVariant::LongLong); + db.setNumericalPrecisionPolicy(oldPrecision); } // This test needs a ODBC data source containing MYSQL in it's name @@ -2258,15 +2277,15 @@ void tst_QSqlDatabase::eventNotificationPSQL() 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() |