140 else if(tst_Databases::isPostgreSQL(db)) |
141 else if(tst_Databases::isPostgreSQL(db)) |
141 QVERIFY_SQL( q, exec("set client_min_messages='warning'")); |
142 QVERIFY_SQL( q, exec("set client_min_messages='warning'")); |
142 |
143 |
143 // please never ever change this table; otherwise fix all tests ;) |
144 // please never ever change this table; otherwise fix all tests ;) |
144 if ( tst_Databases::isMSAccess( db ) ) { |
145 if ( tst_Databases::isMSAccess( db ) ) { |
145 QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest" ) + " ( id int not null, t_varchar varchar(40) not null," |
146 QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," |
146 "t_char char(40), t_numeric number, primary key (id, t_varchar) )" )); |
147 "t_char char(40), t_numeric number, primary key (id, t_varchar) )" )); |
147 } else { |
148 } else { |
148 QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest" ) + " ( id int not null, t_varchar varchar(40) not null," |
149 QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," |
149 "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" )); |
150 "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" )); |
150 } |
151 } |
151 |
152 |
152 if ( tst_Databases::isSqlServer( db ) ) { |
153 if ( tst_Databases::isSqlServer( db ) ) { |
153 //workaround for SQL SERVER since he can store unicode only in nvarchar fields |
154 //workaround for SQL SERVER since he can store unicode only in nvarchar fields |
154 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode") + " (id int not null, " |
155 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " |
155 "t_varchar nvarchar(80) not null, t_char nchar(80) )" )); |
156 "t_varchar nvarchar(80) not null, t_char nchar(80) )" )); |
156 } else { |
157 } else { |
157 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode") + " (id int not null, " |
158 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " |
158 "t_varchar varchar(100) not null," "t_char char(100))" )); |
159 "t_varchar varchar(100) not null," "t_char char(100))" )); |
159 } |
160 } |
160 |
161 |
161 if (tst_Databases::isMSAccess(db)) { |
162 if (tst_Databases::isMSAccess(db)) { |
162 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 number)")); |
163 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision", __FILE__) + " (col1 number)")); |
163 } else { |
164 } else { |
164 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))")); |
165 QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision", __FILE__) + " (col1 numeric(15, 14))")); |
165 } |
166 } |
166 } |
167 } |
167 |
168 |
168 void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db ) |
169 void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db ) |
169 { |
170 { |
170 if ( !db.isValid() ) |
171 if ( !db.isValid() ) |
171 return; |
172 return; |
172 QStringList tableNames; |
173 QStringList tableNames; |
173 tableNames << qTableName( "qtest" ) |
174 tableNames << qtest |
174 << qTableName( "qtest_unicode" ) |
175 << qTableName( "qtest_unicode", __FILE__ ) |
175 << qTableName( "qtest_precision" ) |
176 << qTableName( "qtest_precision", __FILE__ ) |
176 << qTableName( "qtest_ovchar" ) |
177 << qTableName( "qtest_ovchar", __FILE__ ) |
177 << qTableName( "qtest_onvchar" ) |
178 << qTableName( "qtest_onvchar", __FILE__ ) |
178 << qTableName( "qtestPK" ); |
179 << qTableName( "qtestPK", __FILE__ ); |
179 tst_Databases::safeDropTables( db, tableNames ); |
180 tst_Databases::safeDropTables( db, tableNames ); |
180 } |
181 } |
181 |
182 |
182 void tst_Q3SqlCursor::populateTestTables( QSqlDatabase db ) |
183 void tst_Q3SqlCursor::populateTestTables( QSqlDatabase db ) |
183 { |
184 { |
184 if (!db.isValid()) |
185 if (!db.isValid()) |
185 return; |
186 return; |
186 QSqlQuery q( db ); |
187 QSqlQuery q( db ); |
187 |
188 |
188 q.exec( "delete from " + qTableName( "qtest" ) ); //not fatal |
189 q.exec( "delete from " + qtest ); //not fatal |
189 QVERIFY_SQL(q, prepare("insert into " + qTableName( "qtest" ) + " (id, t_varchar, t_char, t_numeric) values (?, ?, ?, ?)")); |
190 QVERIFY_SQL(q, prepare("insert into " + qtest + " (id, t_varchar, t_char, t_numeric) values (?, ?, ?, ?)")); |
190 q.addBindValue(QVariantList() << 0 << 1 << 2 << 3); |
191 q.addBindValue(QVariantList() << 0 << 1 << 2 << 3); |
191 q.addBindValue(QVariantList() << "VarChar0" << "VarChar1" << "VarChar2" << "VarChar3"); |
192 q.addBindValue(QVariantList() << "VarChar0" << "VarChar1" << "VarChar2" << "VarChar3"); |
192 q.addBindValue(QVariantList() << "Char0" << "Char1" << "Char2" << "Char3"); |
193 q.addBindValue(QVariantList() << "Char0" << "Char1" << "Char2" << "Char3"); |
193 q.addBindValue(QVariantList() << 1.1 << 2.2 << 3.3 << 4.4); |
194 q.addBindValue(QVariantList() << 1.1 << 2.2 << 3.3 << 4.4); |
194 QVERIFY_SQL(q, execBatch()); |
195 QVERIFY_SQL(q, execBatch()); |
241 QSqlDatabase db = QSqlDatabase::database( dbName ); |
242 QSqlDatabase db = QSqlDatabase::database( dbName ); |
242 CHECK_DATABASE( db ); |
243 CHECK_DATABASE( db ); |
243 |
244 |
244 Q3SqlCursor cur2; |
245 Q3SqlCursor cur2; |
245 { |
246 { |
246 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
247 Q3SqlCursor cur( qtest, true, db ); |
247 QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); |
248 QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); |
248 cur2 = Q3SqlCursor( cur ); |
249 cur2 = Q3SqlCursor( cur ); |
249 // let "cur" run out of scope... |
250 // let "cur" run out of scope... |
250 } |
251 } |
251 |
252 |
252 QSqlRecord* rec = cur2.primeUpdate(); |
253 QSqlRecord* rec = cur2.primeUpdate(); |
253 Q_ASSERT( rec ); |
254 Q_ASSERT( rec ); |
254 QCOMPARE( (int)rec->count(), 4 ); |
255 QCOMPARE( (int)rec->count(), 4 ); |
255 |
256 |
256 int i = 0; |
257 int i = 0; |
257 while ( cur2.next() ) { |
258 while ( cur2.next() ) { |
258 QVERIFY( cur2.value("id").toInt() == i ); |
259 QVERIFY( cur2.value("id").toInt() == i ); |
259 i++; |
260 i++; |
260 } |
261 } |
261 } |
262 } |
262 |
263 |
263 void tst_Q3SqlCursor::value() |
264 void tst_Q3SqlCursor::value() |
264 { |
265 { |
265 QFETCH( QString, dbName ); |
266 QFETCH( QString, dbName ); |
266 QSqlDatabase db = QSqlDatabase::database( dbName ); |
267 QSqlDatabase db = QSqlDatabase::database( dbName ); |
267 CHECK_DATABASE( db ); |
268 CHECK_DATABASE( db ); |
268 |
269 |
269 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
270 Q3SqlCursor cur( qtest, true, db ); |
270 QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); |
271 QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); |
271 int i = 0; |
272 int i = 0; |
272 while ( cur.next() ) { |
273 while ( cur.next() ) { |
273 QCOMPARE(cur.value("id").toInt(), i); |
274 QCOMPARE(cur.value("id").toInt(), i); |
274 i++; |
275 i++; |
275 } |
276 } |
276 } |
277 } |
277 |
278 |
278 void tst_Q3SqlCursor::primaryIndex() |
279 void tst_Q3SqlCursor::primaryIndex() |
279 { |
280 { |
280 QFETCH( QString, dbName ); |
281 QFETCH( QString, dbName ); |
281 QSqlDatabase db = QSqlDatabase::database( dbName ); |
282 QSqlDatabase db = QSqlDatabase::database( dbName ); |
282 CHECK_DATABASE( db ); |
283 CHECK_DATABASE( db ); |
283 |
284 |
284 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
285 Q3SqlCursor cur( qtest, true, db ); |
285 QSqlIndex index = cur.primaryIndex(); |
286 QSqlIndex index = cur.primaryIndex(); |
286 if ( tst_Databases::isMSAccess( db ) ) { |
287 if ( tst_Databases::isMSAccess( db ) ) { |
287 QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) ); |
288 QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) ); |
288 QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) ); |
289 QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) ); |
289 } else { |
290 } else { |
290 QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) ); |
291 QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) ); |
291 QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) ); |
292 QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) ); |
292 } |
293 } |
293 QVERIFY(!index.isDescending(0)); |
294 QVERIFY(!index.isDescending(0)); |
294 QVERIFY(!index.isDescending(1)); |
295 QVERIFY(!index.isDescending(1)); |
295 } |
296 } |
296 |
297 |
298 { |
299 { |
299 QFETCH( QString, dbName ); |
300 QFETCH( QString, dbName ); |
300 QSqlDatabase db = QSqlDatabase::database( dbName ); |
301 QSqlDatabase db = QSqlDatabase::database( dbName ); |
301 CHECK_DATABASE( db ); |
302 CHECK_DATABASE( db ); |
302 |
303 |
303 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
304 Q3SqlCursor cur( qtest, true, db ); |
304 QSqlRecord* irec = cur.primeInsert(); |
305 QSqlRecord* irec = cur.primeInsert(); |
305 QVERIFY( irec != 0 ); |
306 QVERIFY( irec != 0 ); |
306 |
307 |
307 // check that primeInsert returns a valid QSqlRecord |
308 // check that primeInsert returns a valid QSqlRecord |
308 QCOMPARE( (int)irec->count(), 4 ); |
309 QCOMPARE( (int)irec->count(), 4 ); |
309 if ( ( irec->field( 0 ).type() != QVariant::Int ) && |
310 if ( ( irec->field( 0 ).type() != QVariant::Int ) && |
310 ( irec->field( 0 ).type() != QVariant::String ) && |
311 ( irec->field( 0 ).type() != QVariant::String ) && |
311 ( irec->field( 0 ).type() != QVariant::Double ) ) { |
312 ( irec->field( 0 ).type() != QVariant::Double ) ) { |
312 QFAIL( QString( "Wrong datatype %1 for field 'ID'" |
313 QFAIL( QString( "Wrong datatype %1 for field 'ID'" |
313 " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) ); |
314 " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) ); |
314 } |
315 } |
315 QCOMPARE( QVariant::typeToName( irec->field( 1 ).type() ), QVariant::typeToName( QVariant::String ) ); |
316 QCOMPARE( QVariant::typeToName( irec->field( 1 ).type() ), QVariant::typeToName( QVariant::String ) ); |
316 QCOMPARE( QVariant::typeToName( irec->field( 2 ).type() ), QVariant::typeToName( QVariant::String ) ); |
317 QCOMPARE( QVariant::typeToName( irec->field( 2 ).type() ), QVariant::typeToName( QVariant::String ) ); |
317 QVERIFY((QVariant::typeToName(irec->field(3).type()) == QVariant::typeToName(QVariant::Double)) || |
318 QVERIFY((QVariant::typeToName(irec->field(3).type()) == QVariant::typeToName(QVariant::Double)) || |
318 (QVariant::typeToName(irec->field(3).type()) == QVariant::typeToName(QVariant::String))); |
319 (QVariant::typeToName(irec->field(3).type()) == QVariant::typeToName(QVariant::String))); |
324 irec->setValue( "id", 400 ); |
325 irec->setValue( "id", 400 ); |
325 irec->setValue( "t_varchar", "SomeVarChar" ); |
326 irec->setValue( "t_varchar", "SomeVarChar" ); |
326 irec->setValue( "t_char", "SomeChar" ); |
327 irec->setValue( "t_char", "SomeChar" ); |
327 irec->setValue( "t_numeric", 400.400 ); |
328 irec->setValue( "t_numeric", 400.400 ); |
328 |
329 |
329 QCOMPARE( cur.insert(), 1 ); |
330 QSet<int> validReturns(QSet<int>() << -1 << 1); |
|
331 |
|
332 QVERIFY( validReturns.contains(cur.insert()) ); |
330 |
333 |
331 // restore old test-tables |
334 // restore old test-tables |
332 populateTestTables( db ); |
335 populateTestTables( db ); |
333 } |
336 } |
334 |
337 |
335 void tst_Q3SqlCursor::insertSpecial() |
338 void tst_Q3SqlCursor::insertSpecial() |
336 { |
339 { |
337 QFETCH( QString, dbName ); |
340 QFETCH( QString, dbName ); |
338 QSqlDatabase db = QSqlDatabase::database( dbName ); |
341 QSqlDatabase db = QSqlDatabase::database( dbName ); |
339 CHECK_DATABASE( db ); |
342 CHECK_DATABASE( db ); |
340 |
343 QSet<int> validReturns(QSet<int>() << -1 << 1); |
341 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
344 |
|
345 Q3SqlCursor cur( qtest, true, db ); |
342 QSqlRecord* irec = cur.primeInsert(); |
346 QSqlRecord* irec = cur.primeInsert(); |
343 QVERIFY( irec != 0 ); |
347 QVERIFY( irec != 0 ); |
344 |
348 |
345 QStringList strings; |
349 QStringList strings; |
346 strings << "StringWith'ATick" << "StringWith\"Doublequote" << "StringWith\\Backslash" << "StringWith~Tilde"; |
350 strings << "StringWith'ATick" << "StringWith\"Doublequote" << "StringWith\\Backslash" << "StringWith~Tilde"; |
352 int i = 800; |
356 int i = 800; |
353 |
357 |
354 // INSERT the strings |
358 // INSERT the strings |
355 QStringList::Iterator it; |
359 QStringList::Iterator it; |
356 for ( it = strings.begin(); it != strings.end(); ++it ) { |
360 for ( it = strings.begin(); it != strings.end(); ++it ) { |
357 QSqlRecord* irec = cur.primeInsert(); |
361 QSqlRecord* irec = cur.primeInsert(); |
358 QVERIFY( irec != 0 ); |
362 QVERIFY( irec != 0 ); |
359 irec->setValue( "id", i ); |
363 irec->setValue( "id", i ); |
360 irec->setValue( "t_varchar", (*it) ); |
364 irec->setValue( "t_varchar", (*it) ); |
361 irec->setValue( "t_char", (*it) ); |
365 irec->setValue( "t_char", (*it) ); |
362 irec->setValue( "t_numeric", (double)i ); |
366 irec->setValue( "t_numeric", (double)i ); |
363 ++i; |
367 ++i; |
364 QCOMPARE( cur.insert(), 1 ); |
368 QVERIFY( validReturns.contains(cur.insert()) ); |
365 } |
369 } |
366 |
370 |
367 QVERIFY( cur.select( "id >= 800 and id < 900" ) ); |
371 QVERIFY( cur.select( "id >= 800 and id < 900" ) ); |
368 |
372 |
369 int i2 = 800; |
373 int i2 = 800; |
370 while( cur.next() ) { |
374 while( cur.next() ) { |
371 QCOMPARE( cur.value( "id" ).toInt(), i2 ); |
375 QCOMPARE( cur.value( "id" ).toInt(), i2 ); |
372 QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); |
376 QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); |
373 QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); |
377 QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); |
374 QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 ); |
378 QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 ); |
375 ++i2; |
379 ++i2; |
376 } |
380 } |
377 QCOMPARE( i, i2 ); |
381 QCOMPARE( i, i2 ); |
378 |
382 |
379 populateTestTables( db ); |
383 populateTestTables( db ); |
380 } |
384 } |
382 void tst_Q3SqlCursor::batchInsert() |
386 void tst_Q3SqlCursor::batchInsert() |
383 { |
387 { |
384 QFETCH( QString, dbName ); |
388 QFETCH( QString, dbName ); |
385 QSqlDatabase db = QSqlDatabase::database( dbName ); |
389 QSqlDatabase db = QSqlDatabase::database( dbName ); |
386 CHECK_DATABASE( db ); |
390 CHECK_DATABASE( db ); |
|
391 QSet<int> validReturns(QSet<int>() << -1 << 1); |
387 |
392 |
388 QSqlQuery q( db ); |
393 QSqlQuery q( db ); |
389 q.exec( "delete from " + qTableName( "qtest" ) ); |
394 q.exec( "delete from " + qtest ); |
390 |
395 |
391 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
396 Q3SqlCursor cur( qtest, true, db ); |
392 |
397 |
393 int i = 0; |
398 int i = 0; |
394 for ( ; i < 100; ++i ) { |
399 for ( ; i < 100; ++i ) { |
395 QSqlRecord* irec = cur.primeInsert(); |
400 QSqlRecord* irec = cur.primeInsert(); |
396 Q_ASSERT( irec ); |
401 Q_ASSERT( irec ); |
397 irec->setValue( "id", i ); |
402 irec->setValue( "id", i ); |
398 irec->setValue( "t_varchar", "blah" ); |
403 irec->setValue( "t_varchar", "blah" ); |
399 irec->setValue( "t_char", "blah" ); |
404 irec->setValue( "t_char", "blah" ); |
400 irec->setValue( "t_numeric", 1.1 ); |
405 irec->setValue( "t_numeric", 1.1 ); |
401 if ( db.driverName().startsWith( "QSQLITE" ) ) { |
406 if ( db.driverName().startsWith( "QSQLITE" ) ) { |
402 QVERIFY( cur.insert( true ) ); |
407 QVERIFY( cur.insert( true ) ); |
403 } else { |
408 } else { |
404 QCOMPARE( cur.insert( true ), 1 ); |
409 QVERIFY( validReturns.contains(cur.insert( true )) ); |
405 } |
410 } |
406 } |
411 } |
407 |
412 |
408 for ( ; i < 200; ++i ) { |
413 for ( ; i < 200; ++i ) { |
409 QSqlRecord* irec = cur.primeInsert(); |
414 QSqlRecord* irec = cur.primeInsert(); |
410 Q_ASSERT( irec ); |
415 Q_ASSERT( irec ); |
411 irec->setValue( "id", i ); |
416 irec->setValue( "id", i ); |
412 irec->setValue( "t_varchar", "blah" ); |
417 irec->setValue( "t_varchar", "blah" ); |
413 irec->setValue( "t_char", "blah" ); |
418 irec->setValue( "t_char", "blah" ); |
414 irec->setValue( "t_numeric", 1.1 ); |
419 irec->setValue( "t_numeric", 1.1 ); |
415 if ( db.driverName().startsWith( "QSQLITE" ) ) { |
420 if ( db.driverName().startsWith( "QSQLITE" ) ) { |
416 QVERIFY( cur.insert( false ) ); |
421 QVERIFY( cur.insert( false ) ); |
417 } else { |
422 } else { |
418 QCOMPARE( cur.insert( false ), 1 ); |
423 QVERIFY( validReturns.contains(cur.insert( false )) ); |
419 } |
424 } |
420 } |
425 } |
421 |
426 |
422 i = 0; |
427 i = 0; |
423 QVERIFY_SQL(q, exec( "select * from " + qTableName( "qtest" ) + " order by id" )); |
428 QVERIFY_SQL(q, exec( "select * from " + qtest + " order by id" )); |
424 while ( q.next() ) { |
429 while ( q.next() ) { |
425 QCOMPARE( q.value( 0 ).toInt(), i ); |
430 QCOMPARE( q.value( 0 ).toInt(), i ); |
426 i++; |
431 i++; |
427 } |
432 } |
428 |
433 |
429 QCOMPARE( i, 200 ); |
434 QCOMPARE( i, 200 ); |
430 |
435 |
431 populateTestTables( db ); |
436 populateTestTables( db ); |
445 QFETCH( QString, dbName ); |
450 QFETCH( QString, dbName ); |
446 QSqlDatabase db = QSqlDatabase::database( dbName ); |
451 QSqlDatabase db = QSqlDatabase::database( dbName ); |
447 CHECK_DATABASE( db ); |
452 CHECK_DATABASE( db ); |
448 |
453 |
449 if (tst_Databases::getOraVersion(db) < 9) |
454 if (tst_Databases::getOraVersion(db) < 9) |
450 QSKIP("Need Oracle >= 9", SkipSingle); |
455 QSKIP("Need Oracle >= 9", SkipSingle); |
451 |
456 |
452 /****** CHARSET TEST ******/ |
457 /****** CHARSET TEST ******/ |
453 |
458 |
454 QSqlQuery q( db ); |
459 QSqlQuery q( db ); |
455 QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest_ovchar" ) + " ( id int primary key, t_char varchar(40) )" )); |
460 QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest_ovchar", __FILE__ ) + " ( id int primary key, t_char varchar(40) )" )); |
456 |
461 |
457 static const QString val1( "blah1" ); |
462 static const QString val1( "blah1" ); |
458 |
463 |
459 Q3SqlCursor cur ( qTableName( "qtest_ovchar" ), true, db ); |
464 Q3SqlCursor cur ( qTableName( "qtest_ovchar", __FILE__ ), true, db ); |
460 QSqlRecord* irec = cur.primeInsert(); |
465 QSqlRecord* irec = cur.primeInsert(); |
461 irec->setValue( "id", 1 ); |
466 irec->setValue( "id", 1 ); |
462 irec->setValue( "t_char", val1 ); |
467 irec->setValue( "t_char", val1 ); |
463 QVERIFY( cur.insert() ); |
468 QVERIFY( cur.insert() ); |
464 |
469 |
465 QVERIFY_SQL(cur, select()); |
470 QVERIFY_SQL(cur, select()); |
466 QVERIFY( cur.next() ); |
471 QVERIFY( cur.next() ); |
467 if ( cur.value( "t_char" ).toString() != val1 ) |
472 if ( cur.value( "t_char" ).toString() != val1 ) |
468 qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg( |
473 qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg( |
469 cur.value( "t_char" ).toString() ) ); |
474 cur.value( "t_char" ).toString() ) ); |
470 |
475 |
471 static const unsigned short utf8arr[] = { 0xd792,0xd79c,0xd792,0xd79c,0xd799,0x00 }; |
476 static const unsigned short utf8arr[] = { 0xd792,0xd79c,0xd792,0xd79c,0xd799,0x00 }; |
472 static const QString utf8str = QString::fromUcs2( utf8arr ); |
477 static const QString utf8str = QString::fromUcs2( utf8arr ); |
473 |
478 |
474 irec = cur.primeInsert(); |
479 irec = cur.primeInsert(); |
521 QSqlDatabase db = QSqlDatabase::database( dbName ); |
526 QSqlDatabase db = QSqlDatabase::database( dbName ); |
522 CHECK_DATABASE( db ); |
527 CHECK_DATABASE( db ); |
523 |
528 |
524 static const QString utf8str = QString::fromUtf8( "ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει." ); |
529 static const QString utf8str = QString::fromUtf8( "ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει." ); |
525 if ( !db.driver()->hasFeature( QSqlDriver::Unicode ) ) { |
530 if ( !db.driver()->hasFeature( QSqlDriver::Unicode ) ) { |
526 QSKIP( "DBMS not Unicode capable", SkipSingle ); |
531 QSKIP( "DBMS not Unicode capable", SkipSingle ); |
527 } |
532 } |
528 // ascii in the data storage, can't transliterate properly. invalid test. |
533 // ascii in the data storage, can't transliterate properly. invalid test. |
529 if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) |
534 if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) |
530 QSKIP("Can't transliterate extended unicode to ascii", SkipSingle); |
535 QSKIP("Can't transliterate extended unicode to ascii", SkipSingle); |
531 |
536 |
532 Q3SqlCursor cur( qTableName( "qtest_unicode" ), true, db ); |
537 Q3SqlCursor cur( qTableName( "qtest_unicode", __FILE__ ), true, db ); |
533 QSqlRecord* irec = cur.primeInsert(); |
538 QSqlRecord* irec = cur.primeInsert(); |
534 irec->setValue( 0, 500 ); |
539 irec->setValue( 0, 500 ); |
535 irec->setValue( 1, utf8str ); |
540 irec->setValue( 1, utf8str ); |
536 irec->setValue( 2, utf8str ); |
541 irec->setValue( 2, utf8str ); |
537 QVERIFY_SQL(cur, insert()); |
542 QVERIFY_SQL(cur, insert()); |
617 { |
622 { |
618 QFETCH( QString, dbName ); |
623 QFETCH( QString, dbName ); |
619 QSqlDatabase db = QSqlDatabase::database( dbName ); |
624 QSqlDatabase db = QSqlDatabase::database( dbName ); |
620 CHECK_DATABASE( db ); |
625 CHECK_DATABASE( db ); |
621 |
626 |
622 Q3SqlCursor cur( qTableName( "qtest" ), true, db ); |
627 Q3SqlCursor cur( qtest, true, db ); |
623 QVERIFY_SQL(cur, select()); |
628 QVERIFY_SQL(cur, select()); |
624 QVERIFY( cur.next() ); |
629 QVERIFY( cur.next() ); |
625 QVERIFY( cur.next() ); |
630 QVERIFY( cur.next() ); |
626 |
631 |
627 Q3SqlCursor cur2( qTableName( "qtest" ), true, db ); |
632 Q3SqlCursor cur2( qtest, true, db ); |
628 QVERIFY_SQL(cur2, select( "id = 1" )); |
633 QVERIFY_SQL(cur2, select( "id = 1" )); |
629 QVERIFY( cur2.next() ); |
634 QVERIFY( cur2.next() ); |
630 QCOMPARE( cur2.value( 0 ).toInt(), 1 ); |
635 QCOMPARE( cur2.value( 0 ).toInt(), 1 ); |
631 |
636 |
632 Q3SqlCursor cur3( qTableName( "qtest" ), true, db ); |
637 Q3SqlCursor cur3( qtest, true, db ); |
633 QVERIFY_SQL(cur3, select( cur3.primaryIndex( false ) )); |
638 QVERIFY_SQL(cur3, select( cur3.primaryIndex( false ) )); |
634 QVERIFY( cur3.next() ); |
639 QVERIFY( cur3.next() ); |
635 QVERIFY( cur3.next() ); |
640 QVERIFY( cur3.next() ); |
636 QCOMPARE( cur3.value( 0 ).toInt(), 1 ); |
641 QCOMPARE( cur3.value( 0 ).toInt(), 1 ); |
637 |
642 |
638 Q3SqlCursor cur4( qTableName( "qtest" ), true, db ); |
643 Q3SqlCursor cur4( qtest, true, db ); |
639 QSqlIndex idx = cur4.primaryIndex( false ); |
644 QSqlIndex idx = cur4.primaryIndex( false ); |
640 QCOMPARE( (int)idx.count(), 2 ); |
645 QCOMPARE( (int)idx.count(), 2 ); |
641 if ( tst_Databases::isMSAccess( db ) ) { |
646 if ( tst_Databases::isMSAccess( db ) ) { |
642 QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") ); |
647 QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") ); |
643 QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") ); |
648 QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") ); |
644 } else { |
649 } else { |
645 QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") ); |
650 QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") ); |
646 QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") ); |
651 QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") ); |
647 } |
652 } |
648 |
653 |
649 #ifdef QT_DEBUG |
654 #ifdef QT_DEBUG |
650 // Ignore debugging message advising users of a potential pitfall. |
655 // Ignore debugging message advising users of a potential pitfall. |
651 QTest::ignoreMessage(QtDebugMsg, "Q3SqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete()."); |
656 QTest::ignoreMessage(QtDebugMsg, "Q3SqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete()."); |
665 { |
670 { |
666 QFETCH( QString, dbName ); |
671 QFETCH( QString, dbName ); |
667 QSqlDatabase db = QSqlDatabase::database( dbName ); |
672 QSqlDatabase db = QSqlDatabase::database( dbName ); |
668 CHECK_DATABASE( db ); |
673 CHECK_DATABASE( db ); |
669 |
674 |
670 Q3SqlCursor c2( qTableName( "qtest" ), true, db ); |
675 Q3SqlCursor c2( qtest, true, db ); |
671 QCOMPARE( c2.name(), qTableName( "qtest" ) ); |
676 QCOMPARE( c2.name(), qtest ); |
672 QCOMPARE( c2.fieldName( 0 ).lower(), QString( "id" ) ); |
677 QCOMPARE( c2.fieldName( 0 ).lower(), QString( "id" ) ); |
673 |
678 |
674 Q3SqlCursor c( QString(), true, db ); |
679 Q3SqlCursor c( QString(), true, db ); |
675 c.setName( qTableName( "qtest" ) ); |
680 c.setName( qtest ); |
676 QCOMPARE( c.name(), qTableName( "qtest" ) ); |
681 QCOMPARE( c.name(), qtest ); |
677 QCOMPARE( c.fieldName( 0 ).lower(), QString( "id" ) ); |
682 QCOMPARE( c.fieldName( 0 ).lower(), QString( "id" ) ); |
678 |
683 |
679 c.setName( qTableName( "qtest_precision" ) ); |
684 c.setName( qTableName( "qtest_precision", __FILE__ ) ); |
680 QCOMPARE( c.name(), qTableName( "qtest_precision" ) ); |
685 QCOMPARE( c.name(), qTableName( "qtest_precision", __FILE__ ) ); |
681 QCOMPARE( c.fieldName( 0 ).lower(), QString( "col1" ) ); |
686 QCOMPARE( c.fieldName( 0 ).lower(), QString( "col1" ) ); |
682 } |
687 } |
683 |
688 |
684 /* Database independent test */ |
689 /* Database independent test */ |
685 void tst_Q3SqlCursor::updateNoPK() |
690 void tst_Q3SqlCursor::updateNoPK() |
686 { |
691 { |
687 QFETCH( QString, dbName ); |
692 QFETCH( QString, dbName ); |
688 QSqlDatabase db = QSqlDatabase::database( dbName ); |
693 QSqlDatabase db = QSqlDatabase::database( dbName ); |
689 CHECK_DATABASE( db ); |
694 CHECK_DATABASE( db ); |
690 |
695 QSet<int> validReturns(QSet<int>() << -1 << 1); |
|
696 |
691 QSqlQuery q(db); |
697 QSqlQuery q(db); |
692 QVERIFY_SQL(q, exec("create table " + qTableName( "qtestPK" ) + " (id int, name varchar(20), num numeric)")); |
698 QVERIFY_SQL(q, exec("create table " + qTableName( "qtestPK", __FILE__ ) + " (id int, name varchar(20), num numeric)")); |
693 |
699 |
694 Q3SqlCursor cur(qTableName("qtestPK"), true, db); |
700 Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db); |
695 QSqlRecord* rec = cur.primeInsert(); |
701 QSqlRecord* rec = cur.primeInsert(); |
696 Q_ASSERT(rec); |
702 Q_ASSERT(rec); |
697 rec->setNull(0); |
703 rec->setNull(0); |
698 rec->setNull(1); |
704 rec->setNull(1); |
699 rec->setNull(2); |
705 rec->setNull(2); |
700 QVERIFY_SQL(cur, insert() == 1); |
706 QVERIFY(validReturns.contains(cur.insert())); |
701 if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { |
707 if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { |
702 |
708 |
703 // Only QPSQL, QMYSQL, QODBC and QOCI drivers currently use escape identifiers for column names |
709 // Only QPSQL, QMYSQL, QODBC and QOCI drivers currently use escape identifiers for column names |
704 if (db.driverName().startsWith("QPSQL") || |
710 if (db.driverName().startsWith("QPSQL") || |
705 db.driverName().startsWith("QMYSQL") || |
711 db.driverName().startsWith("QMYSQL") || |
706 db.driverName().startsWith("QODBC") || |
712 db.driverName().startsWith("QODBC") || |
707 db.driverName().startsWith("QOCI")) { |
713 db.driverName().startsWith("QOCI")) { |
708 QString query = QString::fromLatin1("insert into " + qTableName("qtestPK") + |
714 QString query = QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) + |
709 " (" + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName) + ',' |
715 " (" + db.driver()->escapeIdentifier("id", QSqlDriver::FieldName) + ',' |
710 + db.driver()->escapeIdentifier("name", QSqlDriver::FieldName) + ',' |
716 + db.driver()->escapeIdentifier("name", QSqlDriver::FieldName) + ',' |
711 + db.driver()->escapeIdentifier("num", QSqlDriver::FieldName) + ')' |
717 + db.driver()->escapeIdentifier("num", QSqlDriver::FieldName) + ')' |
712 + " values (NULL,NULL,NULL)"); |
718 + " values (NULL,NULL,NULL)"); |
713 QCOMPARE(cur.lastQuery(), query); |
719 QCOMPARE(cur.lastQuery(), query); |
714 } else { |
720 } else { |
715 QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK") + |
721 QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) + |
716 " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)")); |
722 " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)")); |
717 } |
723 } |
718 } |
724 } |
719 |
725 |
720 rec = cur.primeUpdate(); |
726 rec = cur.primeUpdate(); |
721 Q_ASSERT(rec); |
727 Q_ASSERT(rec); |
722 rec->setValue(0, 1); |
728 rec->setValue(0, 1); |
723 rec->setNull(1); |
729 rec->setNull(1); |
724 rec->setNull(2); |
730 rec->setNull(2); |
725 // Sqlite returns 2, don't ask why. |
731 // Sqlite returns 2, don't ask why. |
726 QVERIFY(cur.update() != 0); |
732 QVERIFY(cur.update() != 0); |
727 QString expect = "update " + qTableName("qtestPK") + |
733 QString expect = "update " + qTableName("qtestPK", __FILE__) + |
728 " set "+db.driver()->escapeIdentifier("id", QSqlDriver::FieldName)+" = 1 , " |
734 " set "+db.driver()->escapeIdentifier("id", QSqlDriver::FieldName)+" = 1 , " |
729 +db.driver()->escapeIdentifier("name", QSqlDriver::FieldName)+" = NULL , " |
735 +db.driver()->escapeIdentifier("name", QSqlDriver::FieldName)+" = NULL , " |
730 +db.driver()->escapeIdentifier("num", QSqlDriver::FieldName)+" = NULL where " + qTableName("qtestPK") + ".id" |
736 +db.driver()->escapeIdentifier("num", QSqlDriver::FieldName)+" = NULL where " + qTableName("qtestPK", __FILE__) + ".id" |
731 " IS NULL and " + qTableName("qtestPK") + ".name IS NULL and " + |
737 " IS NULL and " + qTableName("qtestPK", __FILE__) + ".name IS NULL and " + |
732 qTableName("qtestPK") + ".num IS NULL"; |
738 qTableName("qtestPK", __FILE__) + ".num IS NULL"; |
733 if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { |
739 if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { |
734 if (!db.driverName().startsWith("QSQLITE")) { |
740 if (!db.driverName().startsWith("QSQLITE")) { |
735 QCOMPARE(cur.lastQuery(), expect); |
741 QCOMPARE(cur.lastQuery(), expect); |
736 } |
742 } |
737 } |
743 } |
738 QVERIFY(cur.select(cur.index(QString("id")))); |
744 QVERIFY(cur.select(cur.index(QString("id")))); |
739 QVERIFY(cur.next()); |
745 QVERIFY(cur.next()); |
740 QCOMPARE(cur.value("id").toInt(), 1); |
746 QCOMPARE(cur.value("id").toInt(), 1); |