У меня есть база данных SQLite, которая содержит огромный набор сообщений журнала.
Я хочу отобразить это в виде списка (используя wxWidgets).
Пользователь может изменить порядок списка (нажав заголовок столбца), применить фильтр к набору результатов и перемещаться по нему в виде обычного списка, используя полосу прокрутки. Пользователь также может выбрать одну или несколько записей в списке и удалить их.
У меня есть модель виртуального списка: представление списка запрашивает у модели содержимое определенной строки. Модель выдает запрос на выборку с текущими условиями и порядком фильтра и возвращает соответствующую строку из результата.
Чтобы сделать это быстрее, я сохраняю кэши страниц результатов: когда запрашивается строка, я выбираю целую страницу (~ 100 строк), используя LIMIT и OFFSET, и возвращаю конкретную строку со страницы. Я храню несколько страниц, и в следующий раз при запросе строки я сначала проверяю, доступна ли она на одной из кэшированных страниц. Этот метод оказался быстрым и отзывчивым даже при лотах записей (50k +).
Проблема
Моя проблема в том, как обрабатывать обновления / вставки / удаления. У меня есть один триггер для каждого, поэтому модель уведомляется всякий раз, когда происходит вставка / обновление / удаление. Триггер также сообщает модели идентификатор (первичный ключ) соответствующей записи.
Моя первая версия просто делала полный сброс модели после каждого запуска. Это было не очень быстро, но достаточно быстро. Проблема заключалась в том, что если пользователь сделал выбор из одной или нескольких строк, выбор был потерян.
Базовый класс модели (wxDataViewVirtualListModel) содержит методы, которые должны вызываться при изменении:
- RowInserted (строка)
- RowDeleted (строка)
- RowChanged (строка)
Если бы я использовал их, проблема выбора была бы решена, однако есть проблемы:
- Как узнать, находится ли измененная строка в текущем отфильтрованном наборе?
- Как узнать, какая строка в представлении списка была затронута?
Первая проблема может быть решена путем создания метода, который проверяет, принадлежит ли запись множеству. Он должен вести себя так же, как SQL-условия, но это выполнимо.
Вторая проблема, о которой я просто не знаю, как ее решить.
Я использовал фиктивный (0 или последний ряд) номер строки, чтобы принудительно обновить представление, но проблема в том, что строка была вставлена / удалена перед выбором, выбор указывает на неправильные строки после, и и так далее.
Как бы вы поступили? Сохранить расширенную структуру данных со всеми записями в памяти?
Этот вопрос связан с другим вопросом:
Показать большой набор результатов