perf: push limit/offset to DB in PlayerService.get_players (#37) #43
No reviewers
Labels
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-database#43
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "ai/major-domo-database-37"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
.offset()/.limit()calls on the Peewee querytotal_countis now obtained viaquery.count()before pagination, rather thanlen(players_data)after materializing the full result setInMemoryQueryResult) continue to use Python-level slicing unchangedFiles Changed
app/services/player_service.py—PlayerService.get_players(lines 138–152)Test Results
No automated test suite. Changes verified by code review — the functional logic is unchanged for callers; only the execution strategy differs (DB-level vs Python-level pagination).
Other observations
QueryResultprotocol inapp/services/interfaces.pydoes not declareoffset/limitmethods. Pyright raises type warnings on the new calls (query.offset(),query.limit()). These are pre-existing protocol coverage gaps; the code is correct at runtime since theelsebranch is only reached for real Peewee queries.AI Code Review
Files Reviewed
app/services/player_service.py(modified)app/services/interfaces.py(read for context)Findings
Correctness
query.count()call happens on the fully-filtered, fully-sorted query object (after_apply_player_filtersand_apply_player_sorthave applied their.where()and.order_by()clauses), sototal_countcorrectly reflects the pre-pagination filtered set. ✓offset/limitare guarded byif is not Nonebefore calling.offset()/.limit(), soNoneis never passed to Peewee. ✓InMemoryQueryResultsupports__len__, solen(query)in the mock branch is correct and doesn't require an extra iteration. ✓isinstance(query, InMemoryQueryResult)branch correctly preserves pre-existing mock/test behavior. ✓offset=0is handled correctly — the guardif offset is not Nonepasses for0, and.offset(0)is a Peewee no-op. ✓Security
Style & Conventions
'→") and line-length reformatting are consistent with the surrounding codebase style.Suggestions
limit is None and offset is None, theelsebranch still issuesquery.count()before materializing the full result set. The old code did one query +len(players_data)in this case; the new code does two queries (COUNT + SELECT). For the players table this is unlikely to matter in practice — a COUNT query with an index is extremely cheap — but it's worth knowing the tradeoff. A simple optimization would be to skip the count query when neither limit nor offset is provided, computing it fromlen(players_data)after materialization instead. Not a blocker.QueryResultininterfaces.pydoes not declareoffset/limit. If type coverage is ever added to the service layer, these methods should be added to the protocol.Verdict: APPROVED
Correct, well-scoped performance improvement. DB-level pagination avoids materializing the full player table for paginated requests. The mock path is unchanged. No functional regressions or security issues.
Automated review by Claude PR Reviewer (posted as COMMENT — Gitea does not allow self-approval)