qt5base-lts/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
DaNiMoTh 23e4d1a517 Fixed behavior on NULL foreign keys
Instead of using a simple INNER JOIN, like:

SELECT a,b,rel.c FROM table1, table2 WHERE (table1.smthing =
table2.smthing)

which doesn't show row where foreign keys are NULL, allow use of LEFT
JOIN like:

SELECT a,b,rel.c FROM table1 LEFT JOIN table2 ON table1.smthing =
table2.smthing

The trick works also for multi-relational tables.
Just remember to use the new API setJoinMode.

Signed-off-by: DaNiMoTh <jjdanimoth@gmail.com>

Task-number:QTBUG-8217
Reviewed-by:Michael Goddard
Reviewed-by:Charles Yin

Merge-request: 2576
Reviewed-by: Charles Yin <charles.yin@nokia.com>
(cherry picked from commit c4280dbd9bb37cca21d007f5f8b9217f80b44043)

Change-Id: I349f9418e4859923977942add59872b000cac2c5
Reviewed-on: http://codereview.qt.nokia.com/1853
Reviewed-by: Charles Yin <charles.yin@nokia.com>
2011-07-20 08:24:59 +02:00

1472 lines
57 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtSql/QtSql>
#include "../qsqldatabase/tst_databases.h"
const QString reltest1(qTableName("reltest1", __FILE__)),
reltest2(qTableName("reltest2", __FILE__)),
reltest3(qTableName("reltest3", __FILE__)),
reltest4(qTableName("reltest4", __FILE__)),
reltest5(qTableName("reltest5", __FILE__));
//TESTED_CLASS=
//TESTED_FILES=
class tst_QSqlRelationalTableModel : public QObject
{
Q_OBJECT
public:
void recreateTestTables(QSqlDatabase);
tst_Databases dbs;
public slots:
void initTestCase_data();
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void data();
void setData();
void multipleRelation();
void insertRecord();
void setRecord();
void insertWithStrategies();
void removeColumn();
void filter();
void sort();
void revert();
void clearDisplayValuesCache();
void insertRecordDuplicateFieldNames();
void invalidData();
void relationModel();
void casing();
void escapedRelations();
void escapedTableName();
void whiteSpaceInIdentifiers();
void psqlSchemaTest();
private:
void dropTestTables( QSqlDatabase db );
};
void tst_QSqlRelationalTableModel::initTestCase_data()
{
dbs.open();
if (dbs.fillTestTable() == 0) {
qWarning("NO DATABASES");
QSKIP("No database drivers are available in this Qt configuration", SkipAll);
}
}
void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
{
dropTestTables(db);
QSqlQuery q(db);
QVERIFY_SQL( q, exec("create table " + reltest1 +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(1, 'harry', 1, 2)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(2, 'trond', 2, 1)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(3, 'vohi', 1, 2)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(4, 'boris', 2, 2)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)"));
QVERIFY_SQL( q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)"));
QVERIFY_SQL( q, exec("create table " + reltest2 + " (tid int not null primary key, title varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(1, 'herr')"));
QVERIFY_SQL( q, exec("insert into " + reltest2 + " values(2, 'mister')"));
QVERIFY_SQL( q, exec("create table " + reltest3 + " (id int not null primary key, name varchar(20), city_key int)"));
QVERIFY_SQL( q, exec("insert into " + reltest3 + " values(1, 'Gustav', 1)"));
QVERIFY_SQL( q, exec("insert into " + reltest3 + " values(2, 'Heidi', 2)"));
QVERIFY_SQL( q, exec("create table " + reltest4 + " (id int not null primary key, name varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest4 + " values(1, 'Oslo')"));
QVERIFY_SQL( q, exec("insert into " + reltest4 + " values(2, 'Trondheim')"));
QVERIFY_SQL( q, exec("create table " + reltest5 + " (title varchar(20) not null primary key, abbrev varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('herr', 'Hr')"));
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('mister', 'Mr')"));
if (testWhiteSpaceNames(db.driverName())) {
QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test6", QSqlDriver::TableName);
QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) +
" int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)"));
QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test7", QSqlDriver::TableName);
QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')"));
}
}
void tst_QSqlRelationalTableModel::initTestCase()
{
foreach (const QString &dbname, dbs.dbNames) {
QSqlDatabase db=QSqlDatabase::database(dbname);
if (db.driverName().startsWith("QIBASE"))
db.exec("SET DIALECT 3");
else if (tst_Databases::isSqlServer(db)) {
db.exec("SET ANSI_DEFAULTS ON");
db.exec("SET IMPLICIT_TRANSACTIONS OFF");
}
else if(tst_Databases::isPostgreSQL(db))
db.exec("set client_min_messages='warning'");
recreateTestTables(db);
}
}
void tst_QSqlRelationalTableModel::cleanupTestCase()
{
foreach (const QString &dbName, dbs.dbNames) {
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE( db );
dropTestTables( QSqlDatabase::database(dbName) );
}
dbs.close();
}
void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db )
{
QStringList tableNames;
tableNames << reltest1
<< reltest2
<< reltest3
<< reltest4
<< reltest5
<< (qTableName( "rel", __FILE__)+" test6")
<< (qTableName( "rel", __FILE__)+" test7")
<< qTableName("CASETEST1", db.driver() )
<< qTableName("casetest1", db.driver() );
tst_Databases::safeDropTables( db, tableNames );
db.exec("DROP SCHEMA "+qTableName("QTBUG_5373", __FILE__)+" CASCADE");
db.exec("DROP SCHEMA "+qTableName("QTBUG_5373_s2", __FILE__)+" CASCADE");
}
void tst_QSqlRelationalTableModel::init()
{
}
void tst_QSqlRelationalTableModel::cleanup()
{
}
void tst_QSqlRelationalTableModel::data()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.columnCount(), 4);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try a non-existent index
QVERIFY2(model.data(model.index(0,4)).isValid() == false,"Invalid index returned valid QVariant");
// check row with null relation: they are reported only in LeftJoin mode
QCOMPARE(model.rowCount(), 4);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(4, 0)).toInt(), 5);
QCOMPARE(model.data(model.index(4, 1)).toString(), QString("nat"));
QVERIFY2(model.data(model.index(4, 2)).isValid() == true, "NULL relation reported with invalid QVariant");
//check data retrieval when relational key is a non-integer type
//in this case a string
QSqlRelationalTableModel model2(0,db);
model2.setTable(reltest2);
model2.setRelation(1, QSqlRelation(reltest5,"title","abbrev"));
QVERIFY_SQL(model2, select());
QCOMPARE(model2.data(model2.index(0, 1)).toString(), QString("Hr"));
QCOMPARE(model2.data(model2.index(1, 1)).toString(), QString("Mr"));
}
void tst_QSqlRelationalTableModel::setData()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
// set the values using OnRowChange Strategy
{
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QVERIFY(model.setData(model.index(0, 1), QString("harry2")));
QVERIFY(model.setData(model.index(0, 2), 2));
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
model.submit();
QVERIFY(model.setData(model.index(3,1), QString("boris2")));
QVERIFY(model.setData(model.index(3, 2), 1));
QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
model.submit();
}
{ //verify values
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 2);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr"));
}
//set the values using OnFieldChange strategy
{
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setEditStrategy(QSqlTableModel::OnFieldChange);
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QVERIFY(model.setData(model.index(1,1), QString("trond2")));
QVERIFY(model.setData(model.index(2,2), 2));
QCOMPARE(model.data(model.index(1,1)).toString(), QString("trond2"));
QCOMPARE(model.data(model.index(2,2)).toString(), QString("mister"));
}
{ //verify values
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond2"));
QCOMPARE(model.data(model.index(2, 2)).toInt(), 2);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("mister"));
}
//set values using OnManualSubmit strategy
{
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
//sybase doesn't allow tables with the same alias used twice as col names
//so don't set up an identical relation when using the tds driver
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(reltest2, "tid", "title"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QVERIFY(model.setData(model.index(2, 1), QString("vohi2")));
QVERIFY(model.setData(model.index(3, 2), 1));
QVERIFY(model.setData(model.index(0, 3), 1));
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
QVERIFY_SQL(model, submitAll());
}
{ //verify values
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
}
//check setting of data when the relational key is a non-integer type
//in this case a string.
{
QSqlRelationalTableModel model(0, db);
model.setTable(reltest2);
model.setRelation(1, QSqlRelation(reltest5, "title", "abbrev"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Hr"));
QVERIFY(model.setData(model.index(0,1), QString("mister")));
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Mr"));
QVERIFY_SQL(model, submitAll());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Mr"));
}
// Redo same tests, with a LeftJoin
{
QSqlRelationalTableModel model(0, db);
model.setTable(reltest2);
model.setRelation(1, QSqlRelation(reltest5, "title", "abbrev"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Mr"));
QVERIFY(model.setData(model.index(0,1), QString("herr")));
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Hr"));
QVERIFY_SQL(model, submitAll());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Hr"));
}
}
void tst_QSqlRelationalTableModel::multipleRelation()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setRelation(3, QSqlRelation(reltest4, "id", "name"));
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim"));
// Redo same test in the LeftJoin mode
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setRelation(3, QSqlRelation(reltest4, "id", "name"));
model.setSort(0, Qt::AscendingOrder);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim"));
}
void tst_QSqlRelationalTableModel::insertRecord()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QSqlRecord rec;
QSqlField f1("id", QVariant::Int);
QSqlField f2("name", QVariant::String);
QSqlField f3("title_key", QVariant::Int);
QSqlField f4("another_title_key", QVariant::Int);
f1.setValue(7);
f2.setValue("test");
f3.setValue(1);
f4.setValue(2);
f1.setGenerated(true);
f2.setGenerated(true);
f3.setGenerated(true);
f4.setGenerated(true);
rec.append(f1);
rec.append(f2);
rec.append(f3);
rec.append(f4);
QVERIFY_SQL(model, insertRecord(-1, rec));
QCOMPARE(model.data(model.index(4, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(4, 1)).toString(), QString("test"));
QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr"));
// In LeftJoin mode, two additional rows are fetched
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(6, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(6, 1)).toString(), QString("test"));
QCOMPARE(model.data(model.index(6, 2)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::setRecord()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QSqlRecord rec;
QSqlField f1("id", QVariant::Int);
QSqlField f2("name", QVariant::String);
QSqlField f3("title_key", QVariant::Int);
QSqlField f4("another_title_key", QVariant::Int);
f1.setValue(7);
f2.setValue("tester");
f3.setValue(1);
f4.setValue(2);
f1.setGenerated(true);
f2.setGenerated(true);
f3.setGenerated(true);
f4.setGenerated(true);
rec.append(f1);
rec.append(f2);
rec.append(f3);
rec.append(f4);
QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("mister"));
QVERIFY_SQL(model, setRecord(1, rec));
QCOMPARE(model.data(model.index(1, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("tester"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("herr"));
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, submit());
QCOMPARE(model.data(model.index(3, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("tester"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::insertWithStrategies()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setSort(0, Qt::AscendingOrder);
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,0)).toInt(), 1);
QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister"));
else
QCOMPARE(model.data(model.index(0,3)).toInt(), 2);
model.insertRows(0, 1);
model.setData(model.index(0, 0), 1011);
model.setData(model.index(0, 1), "test");
model.setData(model.index(0, 2), 2);
model.setData(model.index(0, 3), 1);
QCOMPARE(model.data(model.index(0,0)).toInt(), 1011);
QCOMPARE(model.data(model.index(0,1)).toString(), QString("test"));
QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(0,3)).toInt(), 1);
QCOMPARE(model.data(model.index(1,0)).toInt(), 1);
QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister"));
else
QCOMPARE(model.data(model.index(1,3)).toInt(), 2);
QVERIFY_SQL(model, submitAll());
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
QCOMPARE(model.data(model.index(0,0)).toInt(), 1);
QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS")) {
QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister"));
model.setData(model.index(0,3),1);
QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr"));
} else {
QCOMPARE(model.data(model.index(0,3)).toInt(), 2);
model.setData(model.index(0,3),1);
QCOMPARE(model.data(model.index(0,3)).toInt(), 1);
}
model.insertRows(0, 2);
model.setData(model.index(0, 0), 1012);
model.setData(model.index(0, 1), "george");
model.setData(model.index(0, 2), 2);
model.setData(model.index(0, 3), 2);
model.setData(model.index(1, 0), 1013);
model.setData(model.index(1, 1), "kramer");
model.setData(model.index(1, 2), 2);
model.setData(model.index(1, 3), 1);
QCOMPARE(model.data(model.index(0,0)).toInt(),1012);
QCOMPARE(model.data(model.index(0,1)).toString(), QString("george"));
QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister"));
else
QCOMPARE(model.data(model.index(0,3)).toInt(), 2);
QCOMPARE(model.data(model.index(1,0)).toInt(),1013);
QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer"));
QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(1,3)).toInt(), 1);
QCOMPARE(model.data(model.index(2,0)).toInt(), 1);
QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(2,3)).toInt(), 1);
QVERIFY_SQL(model, submitAll());
}
void tst_QSqlRelationalTableModel::removeColumn()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QVERIFY_SQL(model, removeColumn(3));
QVERIFY_SQL(model, select());
QCOMPARE(model.columnCount(), 3);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(0, 3)), QVariant());
// try removing more than one column
QVERIFY_SQL(model, removeColumns(1, 2));
QCOMPARE(model.columnCount(), 1);
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)), QVariant());
// try in LeftJoin mode the same tests
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel lmodel(0, db);
lmodel.setTable(reltest1);
lmodel.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
lmodel.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(lmodel, select());
QVERIFY_SQL(lmodel, removeColumn(3));
QVERIFY_SQL(lmodel, select());
QCOMPARE(lmodel.columnCount(), 3);
QCOMPARE(lmodel.data(lmodel.index(0, 0)).toInt(), 1);
QCOMPARE(lmodel.data(lmodel.index(0, 1)).toString(), QString("harry"));
QCOMPARE(lmodel.data(lmodel.index(0, 2)).toString(), QString("herr"));
QCOMPARE(lmodel.data(lmodel.index(0, 3)), QVariant());
// try removing more than one column
QVERIFY_SQL(lmodel, removeColumns(1, 2));
QCOMPARE(lmodel.columnCount(), 1);
QCOMPARE(lmodel.data(lmodel.index(0, 0)).toInt(), 1);
QCOMPARE(lmodel.data(lmodel.index(0, 1)), QVariant());
}
void tst_QSqlRelationalTableModel::filter()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setFilter("title = 'herr'");
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("herr"));
// Redo same filter test in LeftJoin mode
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model,select());
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::sort()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(reltest2, "tid", "title"));
model.setSort(2, Qt::DescendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 4);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
model.setSort(3, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
if (!db.driverName().startsWith("QTDS")) {
QCOMPARE(model.rowCount(), 4);
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister"));
} else {
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
QCOMPARE(model.data(model.index(1, 3)).toInt(), 2);
QCOMPARE(model.data(model.index(2, 3)).toInt(), 2);
QCOMPARE(model.data(model.index(3, 3)).toInt(), 2);
}
// redo same test in LeftJoin mode
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
model.setSort(2, Qt::DescendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 6);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(1, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(4, 2)).toString(), QString(""));
QCOMPARE(model.data(model.index(5, 2)).toString(), QString(""));
model.setSort(3, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
if (!db.driverName().startsWith("QTDS")) {
QCOMPARE(model.rowCount(), 6);
QCOMPARE(model.data(model.index(0, 3)).toString(), QString(""));
QCOMPARE(model.data(model.index(1, 3)).toString(), QString("herr"));
QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(5, 3)).toString(), QString("mister"));
} else {
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
QCOMPARE(model.data(model.index(1, 3)).toInt(), 2);
QCOMPARE(model.data(model.index(2, 3)).toInt(), 2);
QCOMPARE(model.data(model.index(3, 3)).toInt(), 2);
}
}
static void testRevert(QSqlRelationalTableModel &model)
{
/* revert single row */
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
QVERIFY(model.setData(model.index(0, 2), 2, Qt::EditRole));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
model.revertRow(0);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
/* revert all */
QVERIFY(model.setData(model.index(0, 2), 2, Qt::EditRole));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
model.revertAll();
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
// the following only works for OnManualSubmit
if (model.editStrategy() != QSqlTableModel::OnManualSubmit)
return;
/* revert inserted rows */
int initialRowCount = model.rowCount();
QVERIFY(model.insertRows(4, 4));
QVERIFY(model.rowCount() == (initialRowCount + 4));
/* make sure the new rows are initialized to nothing */
QVERIFY(model.data(model.index(4, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(5, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(6, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(7, 2)).toString().isEmpty());
/* Set some values */
QVERIFY(model.setData(model.index(4, 0), 42, Qt::EditRole));
QVERIFY(model.setData(model.index(5, 0), 43, Qt::EditRole));
QVERIFY(model.setData(model.index(6, 0), 44, Qt::EditRole));
QVERIFY(model.setData(model.index(7, 0), 45, Qt::EditRole));
QVERIFY(model.setData(model.index(4, 2), 2, Qt::EditRole));
QVERIFY(model.setData(model.index(5, 2), 2, Qt::EditRole));
QVERIFY(model.setData(model.index(6, 2), 1, Qt::EditRole));
QVERIFY(model.setData(model.index(7, 2), 2, Qt::EditRole));
/* Now revert the newly inserted rows */
model.revertAll();
QVERIFY(model.rowCount() == initialRowCount);
/* Insert rows again */
QVERIFY(model.insertRows(4, 4));
/* make sure the new rows are initialized to nothing */
QVERIFY(model.data(model.index(4, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(5, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(6, 2)).toString().isEmpty());
QVERIFY(model.data(model.index(7, 2)).toString().isEmpty());
}
void tst_QSqlRelationalTableModel::revert()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setRelation(3, QSqlRelation(reltest4, "id", "name"));
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toString(), QString("1"));
testRevert(model);
if (QTest::currentTestFailed())
return;
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
testRevert(model);
/* and again with OnManualSubmit */
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
QVERIFY_SQL(model, select());
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
testRevert(model);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
testRevert(model);
}
void tst_QSqlRelationalTableModel::clearDisplayValuesCache()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(reltest2, "tid", "title"));
model.setSort(1, Qt::AscendingOrder);
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(3, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister"));
else
QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 );
model.insertRow(model.rowCount());
QVERIFY(model.setData(model.index(4, 0), 7, Qt::EditRole));
QVERIFY(model.setData(model.index(4, 1), "anders", Qt::EditRole));
QVERIFY(model.setData(model.index(4, 2), 1, Qt::EditRole));
QVERIFY(model.setData(model.index(4, 3), 1, Qt::EditRole));
model.submitAll();
QCOMPARE(model.data(model.index(0, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr"));
else
QCOMPARE(model.data(model.index(0, 3)).toInt(), 1);
QCOMPARE(model.data(model.index(4, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi"));
QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr"));
if (!db.driverName().startsWith("QTDS"))
QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister"));
else
QCOMPARE(model.data(model.index(4, 3)).toInt(), 2);
}
// For task 140782 and 176374: If the main table and the the related tables uses the same
// name for a column or display column then insertRecord() would return true though it
// actually failed.
void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest3);
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.setSort(0, Qt::AscendingOrder);
// Duplication of "name", used in both reltest3 and reltest4.
model.setRelation(2, QSqlRelation(reltest4, "id", "name"));
QVERIFY_SQL(model, select());
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
QCOMPARE(model.record(1).value((reltest4+QLatin1String("_name_2")).toUpper()).toString(),
QString("Trondheim"));
} else {
QCOMPARE(model.record(1).value((reltest4+QLatin1String("_name_2"))).toString(),
QString("Trondheim"));
}
QSqlRecord rec = model.record();
rec.setValue(0, 3);
rec.setValue(1, "Berge");
rec.setValue(2, 1); // Must insert the key value
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
QCOMPARE(rec.fieldName(0), QLatin1String("ID"));
QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table
} else {
QCOMPARE(rec.fieldName(0), QLatin1String("id"));
QCOMPARE(rec.fieldName(1), QLatin1String("name"));
}
// The duplicate field names is aliased because it's comes from the relation's display column.
if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"))
QCOMPARE(rec.fieldName(2), (reltest4+QLatin1String("_name_2")).toUpper());
else
QCOMPARE(rec.fieldName(2), reltest4+QLatin1String("_name_2"));
QVERIFY(model.insertRecord(-1, rec));
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo"));
QVERIFY(model.submitAll());
QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo"));
}
void tst_QSqlRelationalTableModel::invalidData()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
//try set a non-existent relational key
QVERIFY(model.setData(model.index(0, 2), 3) == false);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try to set data in non valid index
QVERIFY(model.setData(model.index(0,10),5) == false);
//same test with LeftJoin mode
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
//try set a non-existent relational key
QVERIFY(model.setData(model.index(0, 2), 3) == false);
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try to set data in non valid index
QVERIFY(model.setData(model.index(0,10),5) == false);
}
void tst_QSqlRelationalTableModel::relationModel()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QVERIFY(model.relationModel(0) == NULL);
QVERIFY(model.relationModel(1) == NULL);
QVERIFY(model.relationModel(2) != NULL);
QVERIFY(model.relationModel(3) == NULL);
QVERIFY(model.relationModel(4) == NULL);
model.setRelation(3, QSqlRelation(reltest4, "id", "name"));
QVERIFY_SQL(model, select());
QVERIFY(model.relationModel(0) == NULL);
QVERIFY(model.relationModel(1) == NULL);
QVERIFY(model.relationModel(2) != NULL);
QVERIFY(model.relationModel(3) != NULL);
QVERIFY(model.relationModel(4) == NULL);
QSqlTableModel *rel_model = model.relationModel(2);
QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr"));
//same test in JoinMode
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QVERIFY(model.relationModel(0) == NULL);
QVERIFY(model.relationModel(1) == NULL);
QVERIFY(model.relationModel(2) != NULL);
QVERIFY(model.relationModel(3) != NULL);
QVERIFY(model.relationModel(4) == NULL);
QSqlTableModel *rel_model2 = model.relationModel(2);
QCOMPARE(rel_model2->data(rel_model->index(0,1)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::casing()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QIBASE") || tst_Databases::isSqlServer(db))
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll);
QSqlQuery q(db);
QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
if( !q.exec("create table " + qTableName("casetest1", db.driver()) +
" (ident int not null primary key, name varchar(20), title_key int)"))
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll);
QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)"));
if (db.driverName().startsWith("QOCI")) {
//try an owner that doesn't exist
QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper());
QCOMPARE( rec.count(), 0);
//try an owner that does exist
rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper());
QCOMPARE( rec.count(), 4);
}
QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper());
QCOMPARE( rec.count(), 4);
rec = db.driver()->record(qTableName("casetest1", db.driver()));
QCOMPARE( rec.count(), 3);
QSqlTableModel upperCaseModel(0, db);
upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper());
QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper());
QVERIFY_SQL(upperCaseModel, select());
QCOMPARE(upperCaseModel.rowCount(), 4);
QSqlTableModel lowerCaseModel(0, db);
lowerCaseModel.setTable(qTableName("casetest1", db.driver()));
QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver()));
QVERIFY_SQL(lowerCaseModel, select());
QCOMPARE(lowerCaseModel.rowCount(), 3);
QSqlRelationalTableModel model(0, db);
model.setTable(qTableName("CASETEST1", db.driver()).toUpper());
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::escapedRelations()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
recreateTestTables(db);
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
//try with relation table name quoted
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2.toUpper(),QSqlDriver::TableName),
"tid",
"title"));
} else {
model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2,QSqlDriver::TableName),
"tid",
"title"));
}
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with index column quoted
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setRelation(2, QSqlRelation(reltest2,
db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(),
"title"));
} else {
model.setRelation(2, QSqlRelation(reltest2,
db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName),
"title"));
}
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with display column quoted
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setRelation(2, QSqlRelation(reltest2,
"tid",
db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper()));
} else {
model.setRelation(2, QSqlRelation(reltest2,
"tid",
db.driver()->escapeIdentifier("title", QSqlDriver::FieldName)));
}
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
//try with tablename and index and display columns quoted in the relation
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setRelation(2, QSqlRelation(reltest2,
"tid",
db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper()));
} else {
model.setRelation(2, QSqlRelation(reltest2,
"tid",
db.driver()->escapeIdentifier("title", QSqlDriver::FieldName)));
}
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
}
void tst_QSqlRelationalTableModel::escapedTableName()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
// set the values using OnRowChange Strategy with an escaped tablename
{
QSqlRelationalTableModel model(0, db);
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName));
} else {
model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName));
}
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QVERIFY(model.setData(model.index(0, 1), QString("harry2")));
QVERIFY(model.setData(model.index(0, 2), 2));
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
model.submit();
QVERIFY(model.setData(model.index(3,1), QString("boris2")));
QVERIFY(model.setData(model.index(3, 2), 1));
QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
model.submit();
}
{ //verify values
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 2);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr"));
}
//ok, now do same test with LeftJoin
{
QSqlRelationalTableModel model(0, db);
if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) {
model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName));
} else {
model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName));
}
model.setSort(0, Qt::AscendingOrder);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QVERIFY(model.setData(model.index(0, 1), QString("harry2")));
QVERIFY(model.setData(model.index(0, 2), 2));
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
model.submit();
QVERIFY(model.setData(model.index(3,1), QString("boris2")));
QVERIFY(model.setData(model.index(3, 2), 1));
QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
model.submit();
}
{ //verify values
QSqlRelationalTableModel model(0, db);
model.setTable(reltest1);
model.setSort(0, Qt::AscendingOrder);
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 2);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 1);
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister"));
QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr"));
}
}
void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
if (!testWhiteSpaceNames(db.driverName()))
QSKIP("White space test irrelevant for driver", SkipAll);
QSqlRelationalTableModel model(0, db);
model.setTable(db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test6", QSqlDriver::TableName));
model.setSort(0, Qt::DescendingOrder);
model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test7", QSqlDriver::TableName),
db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName),
db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName)));
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington"));
QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York"));
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington"));
QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York"));
model.setJoinMode(QSqlRelationalTableModel::InnerJoin);
QVERIFY_SQL(model, select());
QSqlRecord rec;
QSqlField f1("id", QVariant::Int);
QSqlField f2(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int);
QSqlField f3(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int);
f1.setValue(3);
f2.setValue(2);
f3.setValue(7);
f1.setGenerated(true);
f2.setGenerated(true);
f3.setGenerated(true);
rec.append(f1);
rec.append(f2);
rec.append(f3);
QVERIFY_SQL(model, insertRecord(-1, rec));
model.submitAll();
QCOMPARE(model.data(model.index(0, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 7);
//TODO: For some reson setting a record using manual submit fails
//model.setEditStrategy(QSqlTableModel::OnManualSubmit);
QSqlRecord recNew;
QSqlField f1New("id", QVariant::Int);
QSqlField f2New(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int);
QSqlField f3New(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int);
f1New.setValue(4);
f2New.setValue(1);
f3New.setValue(6);
f1New.setGenerated(true);
f2New.setGenerated(true);
f3New.setGenerated(true);
recNew.append(f1New);
recNew.append(f2New);
recNew.append(f3New);
QVERIFY_SQL(model, setRecord(0, recNew));
QCOMPARE(model.data(model.index(0, 0)).toInt(), 4);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 6);
QVERIFY_SQL(model, submitAll());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 4);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 6);
}
void tst_QSqlRelationalTableModel::psqlSchemaTest()
{
QFETCH_GLOBAL(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
if(!tst_Databases::isPostgreSQL(db)) {
QSKIP("Postgresql specific test", SkipSingle);
return;
}
QSqlRelationalTableModel model(0, db);
QSqlQuery q(db);
QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373", __FILE__)));
QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373_s2", __FILE__)));
QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373", __FILE__)+"."+qTableName("document", __FILE__)+"(document_id int primary key, relatingid int, userid int)"));
QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__)+"(userid int primary key, username char(40))"));
model.setTable(qTableName("QTBUG_5373", __FILE__)+"."+qTableName("document", __FILE__));
model.setRelation(1, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__), "userid", "username"));
model.setRelation(2, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__), "userid", "username"));
QVERIFY_SQL(model, select());
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
QVERIFY_SQL(model, select());
}
QTEST_MAIN(tst_QSqlRelationalTableModel)
#include "tst_qsqlrelationaltablemodel.moc"