1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32#include "qsqlrecord.h"
33#include "qsqlfield.h"
34#include "qstringlist.h"
35
36#include <qsqlrecord.h>
37
38#define NUM_FIELDS 4
39
40class tst_QSqlRecord : public QObject
41{
42Q_OBJECT
43
44public:
45 tst_QSqlRecord();
46 virtual ~tst_QSqlRecord();
47
48
49public slots:
50 void init();
51 void cleanup();
52private slots:
53 void value();
54 void setValue_data();
55 void setValue();
56 void setNull();
57 void setGenerated();
58 void remove();
59 void position();
60 void operator_Assign();
61 void isNull();
62 void isGenerated();
63 void isEmpty();
64 void insert();
65 void fieldName();
66 void field();
67 void count();
68 void contains();
69 void clearValues_data();
70 void clearValues();
71 void clear();
72 void append();
73
74private:
75 QSqlRecord* rec;
76 QSqlField* fields[ NUM_FIELDS ];
77 void createTestRecord();
78};
79
80tst_QSqlRecord::tst_QSqlRecord()
81{
82 rec = 0;
83 for ( int i = 0; i < NUM_FIELDS; ++i )
84 fields[ i ] = 0;
85}
86
87tst_QSqlRecord::~tst_QSqlRecord()
88{
89 delete rec;
90 for ( int i = 0; i < NUM_FIELDS; ++i )
91 delete fields[ i ];
92 rec = 0;
93}
94
95void tst_QSqlRecord::init()
96{
97 cleanup();
98}
99
100void tst_QSqlRecord::cleanup()
101{
102 delete rec;
103 for ( int i = 0; i < NUM_FIELDS; ++i ) {
104 delete fields[ i ];
105 fields[ i ] = 0;
106 }
107 rec = 0;
108}
109
110void tst_QSqlRecord::createTestRecord()
111{
112 delete rec;
113 rec = new QSqlRecord();
114 fields[0] = new QSqlField(QStringLiteral("string"), QVariant::String, QStringLiteral("stringtable"));
115 fields[1] = new QSqlField(QStringLiteral("int"), QVariant::Int, QStringLiteral("inttable"));
116 fields[2] = new QSqlField(QStringLiteral("double"), QVariant::Double, QStringLiteral("doubletable"));
117 fields[3] = new QSqlField(QStringLiteral("bool"), QVariant::Bool);
118 for ( int i = 0; i < NUM_FIELDS; ++i )
119 rec->append( field: *(fields[ i ] ) );
120}
121
122
123void tst_QSqlRecord::append()
124{
125 delete rec;
126 rec = new QSqlRecord();
127 rec->append(field: QSqlField("string", QVariant::String, QStringLiteral("stringtable")));
128 QCOMPARE( rec->field( 0 ).name(), (QString) "string" );
129 QCOMPARE(rec->field(0).tableName(), QStringLiteral("stringtable"));
130 QVERIFY( !rec->isEmpty() );
131 QCOMPARE( (int)rec->count(), 1 );
132 rec->append(field: QSqlField("int", QVariant::Int, QStringLiteral("inttable")));
133 QCOMPARE( rec->field( 1 ).name(), (QString) "int" );
134 QCOMPARE(rec->field(1).tableName(), QStringLiteral("inttable"));
135 QCOMPARE( (int)rec->count(), 2 );
136 rec->append( field: QSqlField( "double", QVariant::Double ) );
137 QCOMPARE( rec->field( 2 ).name(), (QString) "double" );
138 QCOMPARE( (int)rec->count(), 3 );
139 rec->append( field: QSqlField( "bool", QVariant::Bool ) );
140 QCOMPARE( rec->field( 3 ).name(), (QString) "bool" );
141 QCOMPARE( (int)rec->count(), 4 );
142 QCOMPARE( rec->indexOf( "string" ), 0 );
143 QCOMPARE( rec->indexOf( "int" ), 1 );
144 QCOMPARE( rec->indexOf( "double" ), 2 );
145 QCOMPARE( rec->indexOf( "bool" ), 3 );
146}
147
148void tst_QSqlRecord::clear()
149{
150 createTestRecord();
151
152 rec->clear();
153 QCOMPARE( (int)rec->count(), 0 );
154 QVERIFY( rec->isEmpty() );
155 QVERIFY( !rec->contains( fields[0]->name() ) );
156}
157
158void tst_QSqlRecord::clearValues_data()
159{
160 QTest::addColumn<QString>(name: "prefix");
161 QTest::addColumn<QString>(name: "sep");
162 QTest::addColumn<int>(name: "ival");
163 QTest::addColumn<QString>(name: "sval");
164 QTest::addColumn<double>(name: "dval");
165 QTest::addColumn<int>(name: "bval");
166
167 QTest::newRow( dataTag: "data0" ) << QString::fromLatin1(str: "tablename") << QString::fromLatin1(str: ",") << 10
168 << QString::fromLatin1(str: "Trond K.") << 2222.231234441 << 0;
169 QTest::newRow( dataTag: "data1" ) << QString::fromLatin1(str: "mytable") << QString::fromLatin1(str: ".") << 12
170 << QString::fromLatin1(str: "Josten") << 544444444444423232.32334441 << 1;
171 QTest::newRow( dataTag: "data2" ) << QString::fromLatin1(str: "tabby") << QString::fromLatin1(str: "-") << 12
172 << QString::fromLatin1(str: "Odvin") << 899129389283.32334441 << 1;
173 QTest::newRow( dataTag: "data3" ) << QString::fromLatin1(str: "per") << QString::fromLatin1(str: "00") << 12
174 << QString::fromLatin1(str: "Brge") << 29382939182.99999919 << 0;
175}
176
177void tst_QSqlRecord::clearValues()
178{
179 int i;
180 QFETCH( int, ival );
181 QFETCH( QString, sval );
182 QFETCH( double, dval );
183 QFETCH( int, bval );
184
185 if(rec)
186 delete rec;
187
188 rec = new QSqlRecord();
189 rec->append( field: QSqlField( "string", QVariant::String ) );
190 QCOMPARE( rec->field(0).name(), (QString) "string" );
191 QVERIFY( !rec->isEmpty() );
192 QCOMPARE( (int)rec->count(), 1 );
193 rec->append( field: QSqlField( "int", QVariant::Int ) );
194 QCOMPARE( rec->field(1).name(), (QString) "int" );
195 QCOMPARE( (int)rec->count(), 2 );
196 rec->append( field: QSqlField( "double", QVariant::Double ) );
197 QCOMPARE( rec->field(2).name(), (QString) "double" );
198 QCOMPARE( (int)rec->count(), 3 );
199 rec->append( field: QSqlField( "bool", QVariant::Bool ) );
200 QCOMPARE( rec->field(3).name(), (QString) "bool" );
201 QCOMPARE( (int)rec->count(), 4 );
202 QCOMPARE( rec->indexOf( "string" ), 0 );
203 QCOMPARE( rec->indexOf( "int" ), 1 );
204 QCOMPARE( rec->indexOf( "double" ), 2 );
205 QCOMPARE( rec->indexOf( "bool" ), 3 );
206 for ( i = 0; i < 4; ++i )
207 rec->setNull( i );
208
209 rec->setValue( i: 0, val: sval );
210 rec->setValue( i: 1, val: ival );
211 rec->setValue( i: 2, val: dval );
212 rec->setValue( i: 3, val: QVariant(bval) );
213 QVERIFY( rec->value( 0 ) == sval );
214 QVERIFY( rec->value( 1 ) == ival );
215 QVERIFY( rec->value( 2 ) == dval );
216 QVERIFY( rec->value( 3 ) == QVariant(bval) );
217
218 rec->clearValues();
219
220 for ( i = 0; i < 4; ++i )
221 QVERIFY( rec->isNull( i ) );
222
223}
224
225void tst_QSqlRecord::contains()
226{
227 createTestRecord();
228 for ( int i = 0; i < NUM_FIELDS; ++i )
229 QVERIFY( rec->contains( fields[ i ]->name() ) );
230 QVERIFY( !rec->contains( "__Harry__" ) );
231}
232
233void tst_QSqlRecord::count()
234{
235 createTestRecord();
236 QCOMPARE( (int)rec->count(), NUM_FIELDS );
237 rec->remove( pos: 3 );
238 QCOMPARE( (int)rec->count(), NUM_FIELDS - 1 );
239 rec->clear();
240 QCOMPARE( (int)rec->count(), 0 );
241 QCOMPARE( (int)QSqlRecord().count(), 0 );
242}
243
244void tst_QSqlRecord::field()
245{
246 createTestRecord();
247
248 int i;
249 for ( i = 0; i < NUM_FIELDS; ++i )
250 QVERIFY( rec->field( i ) == *fields[ i ] );
251
252 for ( i = 0; i < NUM_FIELDS; ++i )
253 QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
254 QVERIFY( rec->indexOf( "_This should give a warning!_" ) == -1 );
255}
256
257void tst_QSqlRecord::fieldName()
258{
259 createTestRecord();
260
261 for ( int i = 0; i < NUM_FIELDS; ++i )
262 QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
263 QVERIFY( rec->fieldName( NUM_FIELDS ).isNull() );
264}
265
266void tst_QSqlRecord::insert()
267{
268 QSqlRecord iRec;
269 int i;
270 for ( i = 0; i <= 100; ++i ) {
271 iRec.insert( pos: i, field: QSqlField( QString::number( i ), QVariant::Int ) );
272 }
273 for ( i = 0; i <= 100; ++i ) {
274 QCOMPARE( iRec.fieldName( i ), QString::number( i ) );
275 }
276// iRec.insert( 505, QSqlField( "Harry", QVariant::Double ) );
277// QCOMPARE( iRec.fieldName( 505 ), (QString)"Harry" );
278// QVERIFY( iRec.field( 505 ).type() == QVariant::Double );
279
280 iRec.insert( pos: 42, field: QSqlField( "Everything", QVariant::String ) );
281 QCOMPARE( iRec.fieldName( 42 ), (QString)"Everything" );
282 QVERIFY( iRec.field( 42 ).type() == QVariant::String );
283}
284
285void tst_QSqlRecord::isEmpty()
286{
287 QSqlRecord eRec;
288 QVERIFY( eRec.isEmpty() );
289 eRec.append( field: QSqlField( "Harry", QVariant::String ) );
290 QVERIFY( !eRec.isEmpty() );
291 eRec.remove( pos: 0 );
292 QVERIFY( eRec.isEmpty() );
293 eRec.insert( pos: 0, field: QSqlField( "Harry", QVariant::String ) );
294 QVERIFY( !eRec.isEmpty() );
295 eRec.clear();
296 QVERIFY( eRec.isEmpty() );
297}
298
299void tst_QSqlRecord::isGenerated()
300{
301 createTestRecord();
302
303 int i;
304 for ( i = 0; i < NUM_FIELDS; ++i )
305 QVERIFY( rec->isGenerated( i ) );
306
307 for ( i = 0; i < NUM_FIELDS; ++i )
308 QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
309
310 for ( i = 0; i < NUM_FIELDS; ++i ) {
311 if ( i % 2 )
312 rec->setGenerated( i, generated: false );
313 }
314 rec->setGenerated( NUM_FIELDS * 2, generated: false ); // nothing should happen here
315
316 for ( i = 0; i < NUM_FIELDS; ++i ) {
317 if ( i % 2 ) {
318 QVERIFY( !rec->isGenerated( i ) );
319 } else {
320 QVERIFY( rec->isGenerated( i ) );
321 }
322 }
323
324 for ( i = 0; i < NUM_FIELDS; ++i )
325 if ( i % 2 ) {
326 QVERIFY( !rec->isGenerated( fields[ i ]->name() ) );
327 } else {
328 QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
329 }
330
331 rec->setGenerated( name: "_This should give a warning!_", generated: false ); // nothing should happen here
332}
333
334void tst_QSqlRecord::isNull()
335{
336 createTestRecord();
337
338 int i;
339 for ( i = 0; i < NUM_FIELDS; ++i ) {
340 QVERIFY( rec->isNull( i ) );
341 QVERIFY( rec->isNull( fields[ i ]->name() ) );
342 }
343
344 for ( i = 0; i < NUM_FIELDS; ++i ) {
345 if ( i % 2 )
346 rec->setNull( i );
347 }
348 rec->setNull( NUM_FIELDS ); // nothing should happen here
349
350 for ( i = 0; i < NUM_FIELDS; ++i ) {
351 if ( i % 2 ) {
352 QVERIFY( rec->isNull( i ) );
353 QVERIFY( rec->isNull( fields[ i ]->name() ) );
354 }
355 }
356
357 for ( i = 0; i < NUM_FIELDS; ++i ) {
358 rec->setNull( fields[ i ]->name() );
359 }
360 rec->setNull( "_This should give a warning!_" ); // nothing should happen here
361
362 for ( i = 0; i < NUM_FIELDS; ++i ) {
363 QVERIFY( rec->isNull( i ) );
364 QVERIFY( rec->isNull( fields[ i ]->name() ) );
365 }
366}
367
368void tst_QSqlRecord::operator_Assign()
369{
370 createTestRecord();
371 int i;
372 QSqlRecord buf2, buf3, buf4; // since buffers are implicitely shared, we exaggerate a bit here
373 buf2 = *rec;
374 buf3 = *rec;
375 buf4 = *rec;
376 for ( i = 0; i < NUM_FIELDS; ++i ) {
377 QVERIFY( buf2.field( i ) == *fields[ i ] );
378 QVERIFY( buf3.field( i ) == *( fields[ i ] ) );
379 QVERIFY( buf4.field( i ) == *( fields[ i ] ) );
380 }
381 for ( i = 0; i < NUM_FIELDS; ++i )
382 buf3.setNull( i );
383 buf3.remove( NUM_FIELDS - 1 );
384 QSqlRecord buf5 = buf3;
385 for ( i = 0; i < NUM_FIELDS - 1; ++i ) {
386 QSqlField fi(fields[i]->name(), fields[i]->type(), fields[i]->tableName());
387 fi.clear();
388 QVERIFY( buf5.field( i ) == fi );
389 QVERIFY( buf5.isGenerated( i ) );
390 }
391}
392
393void tst_QSqlRecord::position()
394{
395 createTestRecord();
396 int i;
397 for ( i = 0; i < NUM_FIELDS; ++i ) {
398 QCOMPARE( rec->indexOf( fields[ i ]->name() ), i );
399 if (!fields[i]->tableName().isEmpty())
400 QCOMPARE(rec->indexOf(fields[i]->tableName() + QChar('.') + fields[i]->name()), i);
401 }
402}
403
404void tst_QSqlRecord::remove()
405{
406 createTestRecord();
407 int i;
408 for ( i = 0; i < NUM_FIELDS; ++i ) {
409 rec->setGenerated( i, generated: false );
410 QCOMPARE( (int)rec->count(), NUM_FIELDS - i );
411 rec->remove( pos: 0 );
412 QCOMPARE( (int)rec->count(), NUM_FIELDS - i - 1 );
413 }
414 rec->remove( NUM_FIELDS * 2 ); // nothing should happen
415 for ( i = 0; i < NUM_FIELDS; ++i ) {
416 rec->insert( pos: i, field: QSqlField( fields[ i ]->name(), fields[ i ]->type() ) );
417 QVERIFY( rec->isGenerated( i ) );
418 }
419}
420
421void tst_QSqlRecord::setGenerated()
422{
423 isGenerated();
424}
425
426void tst_QSqlRecord::setNull()
427{
428 isNull();
429}
430
431void tst_QSqlRecord::setValue_data()
432{
433 clearValues_data();
434}
435
436void tst_QSqlRecord::setValue()
437{
438 int i;
439
440 delete rec;
441 rec = new QSqlRecord();
442 rec->append( field: QSqlField( "string", QVariant::String ) );
443 QCOMPARE( rec->field( 0 ).name(), (QString) "string" );
444 QVERIFY( !rec->isEmpty() );
445 QCOMPARE( (int)rec->count(), 1 );
446 rec->append( field: QSqlField( "int", QVariant::Int ) );
447 QCOMPARE( rec->field( 1 ).name(), (QString) "int" );
448 QCOMPARE( (int)rec->count(), 2 );
449 rec->append( field: QSqlField( "double", QVariant::Double ) );
450 QCOMPARE( rec->field( 2 ).name(), (QString) "double" );
451 QCOMPARE( (int)rec->count(), 3 );
452 rec->append( field: QSqlField( "bool", QVariant::Bool ) );
453 QCOMPARE( rec->field( 3 ).name(), (QString) "bool" );
454 QCOMPARE( (int)rec->count(), 4 );
455 QCOMPARE( rec->indexOf( "string" ), 0 );
456 QCOMPARE( rec->indexOf( "int" ), 1 );
457 QCOMPARE( rec->indexOf( "double" ), 2 );
458 QCOMPARE( rec->indexOf( "bool" ), 3 );
459
460 QFETCH( int, ival );
461 QFETCH( QString, sval );
462 QFETCH( double, dval );
463 QFETCH( int, bval );
464
465 for ( i = 0; i < 4; ++i )
466 rec->setNull( i );
467
468 rec->setValue( i: 0, val: sval );
469 rec->setValue( i: 1, val: ival );
470 rec->setValue( i: 2, val: dval );
471 rec->setValue( i: 3, val: QVariant(bval) );
472 QVERIFY( rec->value( 0 ) == sval );
473 QVERIFY( rec->value( 1 ) == ival );
474 QVERIFY( rec->value( 2 ) == dval );
475 QVERIFY( rec->value( 3 ) == QVariant(bval) );
476 for ( i = 0; i < 4; ++i )
477 QVERIFY( !rec->isNull( i ) );
478
479 QSqlRecord rec2 = *rec;
480 QVERIFY( rec2.value( 0 ) == sval );
481 QVERIFY( rec2.value( 1 ) == ival );
482 QVERIFY( rec2.value( 2 ) == dval );
483 QVERIFY( rec2.value( 3 ) == QVariant(bval) );
484
485 rec2.setValue( name: "string", val: "__Harry__" );
486 QCOMPARE(rec2.value(0).toString(), QLatin1String("__Harry__"));
487
488 for ( i = 0; i < 4; ++i )
489 QVERIFY( !rec2.isNull( i ) );
490
491 QCOMPARE( rec->value( 0 ).toString(), sval );
492 QCOMPARE( rec->value( 1 ).toInt(), ival );
493 QCOMPARE( rec->value( 2 ).toDouble(), dval );
494 QCOMPARE( rec->value( 3 ), QVariant(bval) );
495}
496
497void tst_QSqlRecord::value()
498{
499 // this test is already covered in setValue()
500 QSqlRecord rec2;
501 rec2.append( field: QSqlField( "string", QVariant::String ) );
502 rec2.setValue( name: "string", val: "Harry" );
503 QCOMPARE(rec2.value("string").toString(), QLatin1String("Harry"));
504}
505
506QTEST_MAIN(tst_QSqlRecord)
507#include "tst_qsqlrecord.moc"
508

source code of qtbase/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp