Skip to content

fix(rows): keep row counters fresh and reduce count queries#2781

Open
hweihwang wants to merge 2 commits into
mainfrom
fix/451-rows-counter
Open

fix(rows): keep row counters fresh and reduce count queries#2781
hweihwang wants to merge 2 commits into
mainfrom
fix/451-rows-counter

Conversation

@hweihwang

Copy link
Copy Markdown
Contributor

Keeps the navigation and dashboard row counters fresh after row create/update/delete without a full reload, and reduces counting cost:

  • Frontend: sync the active table/view count from loaded rows on each row change; refresh affected views' counts from the backend (debounced) since a row change can move a row in/out of any filtered view.
  • Backend: countRowsForView() now counts in SQL instead of materialising all row ids (no-filter views reuse the table count); table row counts are batched into one grouped query when listing, removing the per-table N+1.

Closes #451
Related: #725, #731

@hweihwang hweihwang requested review from blizzz and enjeck as code owners June 30, 2026 17:17
@hweihwang hweihwang removed request for blizzz and enjeck June 30, 2026 17:28
@hweihwang hweihwang self-assigned this Jun 30, 2026
hweihwang added 2 commits July 1, 2026 15:51
The navigation and dashboard row counters are read from the table/view
objects in the tables store, which were only refreshed on a full table
list reload. Row create/update/delete updated the loaded rows in the
data store but never the stored rowsCount, so counters stayed stale
until the page was reloaded.

Frontend: sync the active table/view rowsCount from the loaded rows
length after each row load/create/update/delete, and adjust the parent
table count by +/-1 when rows are created or deleted through a view.
Because a row change can also add or remove the row from any filtered
view of the same table - which the client cannot determine locally -
the affected views' counts are reloaded from the backend, debounced to
coalesce bursts of edits. A Playwright test covers the table and a
sibling view counter both updating after adding a row, without reload.

Backend: countRowsForView() fetched every matching row id into PHP and
counted the array. It now counts matching sleeves directly in SQL - a
view without filters reuses the cheap table count, and filtered views
run a single COUNT(*) reusing the existing filter expressions. Because
filters are applied as `sleeves.id IN (subselect)` the outer count is
never inflated and no GROUP BY is required.

Related to #451, #725, #731

Signed-off-by: Hoang Pham <hoangmaths96@gmail.com>
Listing tables enhanced each table individually, running one COUNT query
per table to populate its row counter. For a user with many tables this
is a classic N+1.

Fetch all table row counts in a single grouped query before the enhance
loop and pass the result into enhanceTable(). The per-table read-rows
permission gate is preserved (unreadable tables report 0, matching the
previous getRowsCount() fallback), and the single-table enhance path is
unchanged. Context tables are no longer enhanced twice.

This addresses the table side of the listing N+1. View counts still run
one query per view, as a cheap stored/cached view counter depends on
per-user and value-dependent filters and needs a separate design.

Related to #451

Signed-off-by: Hoang Pham <hoangmaths96@gmail.com>
@hweihwang hweihwang force-pushed the fix/451-rows-counter branch from c4c972a to c652292 Compare July 1, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update rows counter

2 participants