submitAll и кэш данных

Есть модель данных к примеру QSqlTableModel и есть визуальное отображение к примеру QTableView.

И есть еще на самом деле сама база данных, где хранятся долговременно данные. Это по сути данные на жестком диске в файловой системе.

QSqlTableModel работает с базой данных через класс QSqlQueryModel

QSqlQueryModel хранит данные,  полученные из базы в своем хранилище в оперативной памяти.

Кэш QSqlTableModel представлен при разных стратегиях редактирования разными храгилищами.

editBuffer используется при стратегии onRowChange и очень частично при OnFieldChange.

Хранилище cache используется при стратегии OnManualSbmit.

Какова роль метода submitAll в модели данных QSqlTableModel? .

submitAll записывает кэшированные данные помеченные как generated (это для editBuffer) в базу данных, то есть в editBuffer помечаются измененные ячейки строки как generated. После записи в базу пометки generated очищаются, как собственно и сам editBuffer..

До вызова submitAll данные отображаются для редактируемой строки в QTableView из editBuffer.

Иногда запись данных в базу данных происходит максимально быстро в зависимости от выбранной стратегии модели данных, например onFieldChanged.

А иногда запись в базу может вообще не происходить например при стратегии onManualSubmit и отсутствии вызова submitAll (в вашем коде).

В промежутке находится стратегия onRowChanged.

Важно понимать, что не смотря на то, что submitAll может быть еще не вызвана в модели, - данные в QTableView будут уже нормально отображаться (data работает нормально), так как данные будут браться из editBuffer или из cache.

И setData также записывает значения ячеек  в editBuffer, где они помечаются как generated или в cache .

Еще надо сказать, что запись в базу из модели данных это по сути QSqlQuery обычные запросы класса QSqlQueryModel.

В итоге можно прийти к выводу, что быстрее будет работать с целыми блоками строк, например накладная с товарами, ценами и т.д., со стратегией onManualSubmit, вызывая submitAll только при записи всего документа.

bool QSqlTableModel::submit()
{
    Q_D(QSqlTableModel);
    if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
        return submitAll();
    return true;
}


Сама функция QSqlTableModel::submitAll(). Очень интересно, что здесь происходит.

bool QSqlTableModel::submitAll()
{
    Q_D(QSqlTableModel);

    switch (d->strategy) {
    case OnFieldChange:
        if (d->insertIndex == -1)
            return true;
        // else fall through
    case OnRowChange:
        if (d->editBuffer.isEmpty())
            return true;
        if (d->insertIndex != -1) {
            if (!insertRowIntoTable(d->editBuffer))
                return false;
            d->bottom = d->bottom.sibling(d->bottom.row()   1, d->bottom.column());
        } else {
            if (!updateRowInTable(d->editIndex, d->editBuffer))
                return false;
        }
        d->clearEditBuffer();
        d->editIndex = -1;
        d->insertIndex = -1;
        return select();
    case OnManualSubmit:
        for (QSqlTableModelPrivate::CacheMap::ConstIterator it = d->cache.constBegin();
             it != d->cache.constEnd();   it) {
            switch (it.value().op) {
            case QSqlTableModelPrivate::Insert:
                if (!insertRowIntoTable(it.value().rec))
                    return false;
                d->bottom = d->bottom.sibling(d->bottom.row()   1, d->bottom.column());
                break;
            case QSqlTableModelPrivate::Update:
                if (!updateRowInTable(it.key(), it.value().rec))
                    return false;
                break;
            case QSqlTableModelPrivate::Delete:
                if (!deleteRowFromTable(it.key()))
                    return false;
                break;
            case QSqlTableModelPrivate::None:
                Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
                break;
            }
        }
        d->clearCache();
        return select();
    }
    return false;
}

Функции updateRowInTable , insertRowInTable и  deletaRowFromTable как раз вызывают запросы к базе данных. Логируйте их и все станет очень очевидно.

Примечание: если submitAll возвращает false - это повод для беспокойства. Такого быть не должно. Значит запрос к базе данных закончился не удачно.

Развиваем класс QSqlTableModel.