OWASP / OWASP/SecurityShepherd
Convert ResultSet-returning Getter methods to bounded collections (DAO refactor follow-up)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.5k
- Forks
- 515
- Avg merge
- 3h 46m
- Merged PRs (30d)
- 1
Description
Context
Three Getter methods return ResultSet-typed objects to callers:
Getter.getClassInfo(String)— all classesGetter.getPlayersByClass(String, String)— players in a classGetter.getAdmins(String)— all admins
These were fixed in #838 to release pooled DB connections immediately by materializing into a javax.sql.rowset.CachedRowSet. That closes the connection-pool leak but inherits one limitation of the previous API: the entire result set is held in memory at materialization time.
A protective setMaxRows(10000) cap was added in #838 as a stopgap — well above realistic Security Shepherd workloads (class rosters of tens to a few hundred students) but enough to prevent a runaway query from OOMing the JVM. That's a guardrail, not a fix.
Proposal
Replace the ResultSet-typed API with proper Java collections / DTOs:
| Method | Proposed return |
|---|---|
getClassInfo(String) |
List<ClassInfo> (or ClassInfo[]) |
getPlayersByClass(String, String) |
List<PlayerSummary> |
getAdmins(String) |
List<AdminSummary> |
Benefits:
- Type-safe — no
getString(1)/getString(2)magic-index access at call sites. - No risk of leaking
ResultSetsemantics to the caller (cursor position, scrollability, etc.). - Easier to unit test with mock data.
- Enables proper pagination when one of these methods grows past its current bounded use case.
Out of scope (for now)
- Pagination. Realistic class sizes don't require it. If a deployment ever hits the
setMaxRowscap, that's the trigger to design a proper paginated API. - Stored-procedure changes. The procs (
classesGetData,playersByClass,playersWithoutClass,adminGetAll) work fine; this is purely a Java-side API change.
Relationship to #815
This is one concrete chunk of the broader DAO refactor proposed in #815. Could be done as part of that effort, or as a standalone first step if #815 stays parked.
Acceptance criteria
- Three methods return
List<DTO>instead ofResultSet. - DTO classes (or records, once a min-JDK bump allows) live alongside
Getteror in adbProcs.dtopackage. - Callers updated to iterate the lists directly (no
while (next())/getString(...)patterns). -
setMaxRows(10000)from #838 can be reconsidered — likely keep as a safety net, but the value can be revisited once the API uses bounded collections.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the Getter class and its getClassInfo, getPlayersByClass, and getAdmins methods, then trace their callers for ResultSet iteration and indexed access. Review the CachedRowSet and setMaxRows(10000) changes from #838 before defining the DTOs. Done means all three methods return typed lists, callers iterate those lists, and the existing stored procedures remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- database
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100