简体   繁体   English

使用表中的更改更新列表视图

[英]Update list view with changes in a table

I have a SQLite database that contains a huge set of log messages. 我有一个包含大量日志消息的SQLite数据库。

I want to display this in a list view (using wxWidgets). 我想在列表视图中显示(使用wxWidgets)。

The user can reorder the list (by pressing the column header), apply a filter on the result set and navigate through it as a usual list, using the scroll bar. 用户可以对列表进行重新排序(通过按列标题),在结果集上应用过滤器,并使用滚动条像通常的列表一样浏览它。 The user can also select one or multiple entries in the list and delete them. 用户还可以在列表中选择一个或多个条目并将其删除。

I have a virtual list model: the list view asks the model for the content of a particular row. 我有一个虚拟的列表模型:列表视图向模型询问特定行的内容。 The model issues a select-query with the current filter-conditions and order and returns the corresponding row from the result. 该模型使用当前过滤条件和顺序发出选择查询,并从结果中返回相应的行。

To make it faster I keep page-caches of results: when a row is requested i fetch a whole page (~100 rows) using LIMIT and OFFSET and return the particular row from the page. 为了使速度更快,我保留了结果的页面缓存:当请求一行时,我使用LIMIT和OFFSET提取整个页面(约100行),并从页面返回特定行。 I store a number of pages, and next time a row is requested I first look if it is available in one of the cached pages. 我存储了许多页面,下次请求行时,我首先查看其中一个缓存页面是否可用。 This technique has proven to be fast and responsive even with lots of entries (50k+). 事实证明,即使有很多条目(50k +),该技术也能快速响应。

The problem 问题

My problem is how to handle updates/inserts/deletes. 我的问题是如何处理更新/插入/删除。 I have one trigger for each so the model is notified whenever an insert/update/delete happens. 我每个都有一个触发器,因此每当发生插入/更新/删除时都会通知模型。 The trigger also tell the model the ID (primary key) of the affected entry. 触发器还告诉模型受影响条目的ID(主键)。

My first version simply made a complete reset of the model after each trigger. 我的第一个版本只是在每次触发后完全重置了模型。 This was not very fast, but fast enough. 这不是很快,但是足够快。 The problem was that if the user had made a selection of one or a couple of rows, the selection was lost. 问题是,如果用户选择了一行或几行,则选择将丢失。

The base class of the model (wxDataViewVirtualListModel) contains methods that should be called when a change happens: 模型的基类(wxDataViewVirtualListModel)包含发生更改时应调用的方法:

  • RowInserted (row) RowInserted(行)
  • RowDeleted (row) 行已删除(行)
  • RowChanged (row) RowChanged(行)

If I used them the selection problem would be solved, however there are problems: 如果我使用它们,选择问题将得到解决,但是存在一些问题:

  • How do I know if the changed row is within the currently filtered set? 我如何知道更改后的行是否在当前过滤的集合内?
  • How do I know which row in the list view was affected? 我如何知道列表视图中的哪一行受到了影响?

The first problem could be solved by creating a method that check if the entry belongs to the set. 第一个问题可以通过创建一种检查条目是否属于集合的方法来解决。 It must behave exactly like the SQL-conditions, but it is doable. 它的行为必须完全像SQL条件一样,但是它是可行的。

The second problem I have simply no idea about how to solve. 第二个问题我根本不知道如何解决。

I've used a bogus (0 or last row) row-number to force the view to be updated, but the problem is if the row was inserted/deleted before the selection, the selection points to wrong rows afterwards, and so on. 我使用了伪造的(0或最后一行)行号来强制更新视图,但是问题是如果在选择之前插入/删除了该行,选择之后指向了错误的行,依此类推。

How would you do? 你会怎么做? Keep an advanced data structure with all entries in memory? 在内存中保留所有条目的高级数据结构?

This question is related to another question: Display large result set 此问题与另一个问题有关: 显示大结果集

I would design this around two different SELECT operations, one getting only the primary key and a timestamp (of the INSERT / UPDATE) for all rows, the other getting all data for a single page of rows. 我将围绕两个不同的SELECT操作进行设计,一个对所有行仅获取主键和时间戳(INSERT / UPDATE的时间戳),另一个对单个行页面获取所有数据。 On a modern machine keeping the complete list of primary keys and timestamps in memory should not be a problem even for several 100000 rows. 在现代机器上,即使对于几万行,将完整的主键和时间戳列表保存在内存中也不成问题。

Whenever the filter criteria change or a trigger fires I would retrieve the list of primary keys and timestamps again. 每当过滤条件发生变化或触发触发器时,我都会再次检索主键和时间戳列表。 The model maintains a list of primary keys and matching timestamps, and a comparison between the model and the new list shows which rows need to be inserted, invalidated or removed. 该模型维护一个主键和匹配时间戳的列表,并且该模型与新列表之间的比较显示了哪些行需要插入,无效或删除。 Cached rows whose timestamp has changed get deleted from the cache, cached rows with the same timestamp need not be retrieved again. 时间戳已更改的高速缓存行将从高速缓存中删除,具有相同时间戳的高速缓存行无需再次检索。 The oldest entries of the cache would be removed when it gets too large. 缓存中的最旧条目过大会被删除。

The selection of the list can be identified via its primary key value, so unless the row has been deleted it is always possible to reselect it after changes to the model, even when it is now in a completely different position. 可以通过列表的主键值来标识列表的选择,因此,除非删除了该行,否则始终可以在更改模型后重新选择它,即使它现在处于完全不同的位置。 I find this to be much more intuitive than keeping the same row position when the ordering changes, which selects a completely different row. 我发现这比更改顺序时保持相同的行位置要直观得多,因为顺序会选择完全不同的行。

Edit: 编辑:

This works for concurrent data changes from other database clients, I have implemented it this way for applications using the Firebird database server. 这适用于其他数据库客户端的并发数据更改,我已经使用Firebird数据库服务器的应用程序以这种方式实现了它。 If there's no way the data can be changed from outside it may not be necessary to always retrieve the full list of primary keys and timestamps. 如果无法从外部更改数据,则不必总是检索主键和时间戳的完整列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM