1

I have implemented an Oracle database. I use Qt for the GUI of my application and as an interface for the db. Setting up the connection to my db and displaying tables in a QTableView works fine. Edit of all cells is generally natively supported using QSqlTableModel. However, Qt does not seem to consider any constraints defined by the database when the associated default ItemDelegate edits a cell.

Say I edit a cell which is a foreign key value, not only does Qt let me enter none key values, but submitting these changes queries the db to perform an update. This obviously will not work, due to set constraints. Now, I get how it might be a bit too much to ask, to expect the default ItemDelegate for my view to check for valid values on edit.

The real problem occurs when I submit an unsupported value. The view still applies the value change, suggesting the edit is valid. No error is handled, nor is an error message delivered. From there on the view will not allow edits on some rows, until I revert the change to value that obeys my constraints.

I find it hard to believe, that I would have to setup my own itemDelegate, to validate value changes against constraints in the db.

Since I expect whoever is able to answer this post, knows how to set up the connection, I'll brake down the code a bit:

bool driverSuccess = validDriver(driver);
if(driverSuccess) {
    _db = QSqlDatabase::addDatabase(driver);
    _db.setHostName(host);
    _db.setDatabaseName(dbName);
    _db.setPort(port);
    _db.setUserName(user);
    _db.setPassword(pwd);

    _db.open();
    //... validate connection
}

// setup table model and connect to view
QSqlRelationalTableModel* model = new QSqlRelationalTableModel;
model->setTable(tableName);
model->select()

QTableView* table_view = new QTableView(0);
table_view->setModel(model);

//...
_db.close()

I'd appreciate any help. Thanks!

Basti Vagabond
  • 1,458
  • 1
  • 18
  • 26

1 Answers1

1

This is to be expected. The database driver doesn't do any constraint validation either. The database does that. All you can do is submit a query that fails. That's all that Qt does, too. Perhaps the table model could react properly to errors by reverting the changes, instead of indicating that they succeeded. I'm not sure offhand if there's a setting/flag that affects that behavior on Qt's side.

If you wish to understand what can be expected, do the queries manually through the SQLPLUS text client or a similar utility.

Now it is technically possible for a client to retrieve the constraints from the administrative tables, and then somehow enforce them on the UI. You'd have to implement it yourself, though - Qt doesn't do it.

If you're only interested in the constraints inherent due to the relations in QSqlRelationalTableModel, you could enforce them without writing additional queries - but the delegate doesn't know anything about them. Only the model knows, and there's no standard mechanism for the model to expose this to a delegate. You'd have to invent your own way, and have a custom delegate that can handle it.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • 1
    Thanks, that does make a lot of sense. I would have wished for some sort of error population, through the `QSqlRelationalTableModel`. handling edits before the model commits the data sounds resonable. I thought about triggering the actual SQL UPDATE myself and do error handling just then. I really like the `QSqlQuery::lastError` function which comes with `QSqlRelationalTableModel` as well but I do not want to update the database on every edit. – Basti Vagabond Aug 13 '15 at 00:08
  • I guess what I want is, to get a list of all cells that changed and that are about to be committed. Then I would want to take over from there and manually commit them using `QSqlQuery`. There doesn't seem to be a `dataAboutToBeCommitted(...)` signal. Do you know a clean way to handle it? – Basti Vagabond Aug 13 '15 at 00:08
  • @BastiVagabond Not at the moment. I might come back and give it some thought later. – Kuba hasn't forgotten Monica Aug 13 '15 at 17:07