Make it possible to update a related table after an external update

When a table that is related to in a QSqlRelationalTableModel gets
updated in some way (e.g. a new row, or the data is changed) then the
related model could not be updated without recreating the
QSqlRelationalTableModel.

Now, to get around this, select() can be called on the related model to
get it to be updated.

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

Change-Id: Ic589e840234f3a809bcb112a807a87afe0bc25ca
(cherry picked from commit 2c60a4f67f9fb02f3b711fe749b2f293a07b4e02)
Reviewed-on: http://codereview.qt.nokia.com/2224
Reviewed-by: Charles Yin <charles.yin@nokia.com>
This commit is contained in:
Andy Shaw 2011-06-03 08:17:40 +02:00 committed by Qt by Nokia
parent 85f05924f4
commit ade2ef0a3e
2 changed files with 57 additions and 2 deletions

View File

@ -119,6 +119,8 @@ QT_BEGIN_NAMESPACE
returns false.
*/
class QRelatedTableModel;
struct QRelation
{
public:
@ -135,7 +137,7 @@ struct QRelation
bool isValid();
QSqlRelation rel;
QSqlTableModel *model;
QRelatedTableModel *model;
QHash<QString, QVariant> dictionary;//maps keys to display values
private:
@ -143,6 +145,15 @@ struct QRelation
bool m_dictInitialized;
};
class QRelatedTableModel : public QSqlTableModel
{
public:
QRelatedTableModel(QRelation *rel, QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
bool select();
private:
bool firstSelect;
QRelation *relation;
};
/*
A QRelation must be initialized before it is considered valid.
Note: population of the model and dictionary are kept separate
@ -162,7 +173,7 @@ void QRelation::populateModel()
Q_ASSERT(m_parent != NULL);
if (!model) {
model = new QSqlTableModel(m_parent, m_parent->database());
model = new QRelatedTableModel(this, m_parent, m_parent->database());
model->setTable(rel.tableName());
model->select();
}
@ -219,6 +230,27 @@ bool QRelation::isValid()
return (rel.isValid() && m_parent != NULL);
}
QRelatedTableModel::QRelatedTableModel(QRelation *rel, QObject *parent, QSqlDatabase db) :
QSqlTableModel(parent, db), firstSelect(true), relation(rel)
{
}
bool QRelatedTableModel::select()
{
if (firstSelect) {
firstSelect = false;
return QSqlTableModel::select();
}
relation->clearDictionary();
bool res = QSqlTableModel::select();
if (res)
relation->populateDictionary();
return res;
}
class QSqlRelationalTableModelPrivate: public QSqlTableModelPrivate
{
Q_DECLARE_PUBLIC(QSqlRelationalTableModel)

View File

@ -92,6 +92,7 @@ private slots:
void escapedTableName();
void whiteSpaceInIdentifiers();
void psqlSchemaTest();
void selectAfterUpdate();
private:
void dropTestTables( QSqlDatabase db );
@ -1467,5 +1468,27 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest()
QVERIFY_SQL(model, select());
}
void tst_QSqlRelationalTableModel::selectAfterUpdate()
{
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(2)->rowCount() == 2);
{
QSqlQuery q(db);
QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(3, 'mrs')"));
model.relationModel(2)->select();
}
QVERIFY(model.relationModel(2)->rowCount() == 3);
QVERIFY(model.setData(model.index(0,2), 3));
QVERIFY(model.submitAll());
QCOMPARE(model.data(model.index(0,2)), QVariant("mrs"));
}
QTEST_MAIN(tst_QSqlRelationalTableModel)
#include "tst_qsqlrelationaltablemodel.moc"