Abstract Paged List
Abstract base class for PagedList — a UI-model façade over the shared PagedQueryCore engine. Users do not instantiate this directly; use the platform-specific PagedList subclass instead (it provides language-idiomatic constructors for Kotlin and Java).
A PagedList implements kotlin.collections.AbstractList, so it behaves as a normal List<T> while loading pages on demand from the database. Filtering and sorting are defined through Facet objects set up at configuration time. The list caches the current page and the total size, and supports a "selected" entity that always appears first.
When to use PagedList
PagedList is intended for UI consumers — desktop/embedded grids (ZK, Compose, Swing, JavaFX) where a single long-lived list instance drives a view. It is not appropriate for stateless server-side request handling: its per-column filter/sort state is mutable and shared, and its cached page / size / selected entity have no meaning across independent REST requests.
For REST/stateless server use, use PagedQuery — configure once at startup, call execute(spec) per request.
The Stormify instance is not passed at construction. It is resolved lazily on first access via (in order):
The instance explicitly attached via Stormify.attach
The registered Stormify.defaultInstance
If neither is available when the list first needs to touch the database, an error is thrown.
Usage
val list = PagedList<Company>() // no stormify yet
stormify.attach(list) // binds the instance
list.addFacet("name") // text filter + sort
list.addFacet("contactPerson.firstName",
"contactPerson.lastName") // OR filter via FK
list.addSqlFacet("SUM(amount)", Facet.NUMERIC)
list.getFacet(0).filter = "Acme"
list.getFacet(1).sort = Facet.ASCENDING
val company = list[0] // triggers page load
val total = list.size // triggers COUNT queryParameters
The KClass of the entity type
Type Parameters
The entity type
Inheritors
Properties
Input parser for this list. Overrides Stormify.inputParser.
Whether the query should return only distinct results.
Total number of rows that match the current filters and constraints. The first access issues a COUNT(*) (or COUNT(*) FROM (SELECT DISTINCT ...) if isDistinct) query and caches the result for reuse.
Functions
Adds a column with one or more field paths. The column type is auto-detected from the field's Kotlin type. Multiple paths use OR logic for filtering.
Adds a column using type-safe KSP-generated path objects.
Adds an ENUM column with a custom display-name-to-DB-value map. Use this when the field is not a Kotlin enum but logically represents one (e.g., a status integer column with human-readable labels), or to override the auto-built map for a real enum field. The Map first argument distinguishes this overload from the scalar-typed variants at compile time.
Enum-column variant using typed paths — same rules as the Map + String overload.
Adds a column with an explicit type override. Use this when the auto-detected type (based on the field's Kotlin type) is not what you want — for example, to treat a string zip-code column as numeric.
Explicit-type variant of addFacet using typed paths.
Adds a raw/custom column backed by an arbitrary SQL expression.
Adds a raw/custom column with a custom Converter. The converter receives the column expression and the user's filter value, and returns a SQL fragment while staging bind parameters via SqlArgsCollector.
Registers a TableRef for the root entity table. The ref's TableRef.alias resolves to the underlying DB table name, so raw SQL in setConstraints or in an addSqlFacet expression can safely reference the root without hardcoding the table name.
Registers a TableRef for a table reached through the given dotted path (e.g. "address", "company.hq"). The final segment must be an FK reference, not a scalar field. The associated JOIN is activated in every subsequent SQL build while the ref's TableRef.isActive is true.
Registers a TableRef from a KSP-generated typed ReferencePath.
Streams every row matching the current filter / sort / constraint state through action via a cursor — a single query that does not materialize the full result set. Use this for exports or bulk processing where paginating through the list's index-based iterator() would issue N / pageSize queries.
Returns a new PagedAggregator bound to this list. Each call returns a fresh aggregator so users can build multiple independent aggregation chains without interference.
Re-applies a previously captured PagedListState. Keys present in state but missing from the current column set are silently ignored (the list's columns may have changed since the state was saved). Sort entries whose value is neither PagedListSort.ASC nor PagedListSort.DESC are treated as absent.
Captures the per-column filters / sorts / case-sensitivity flags plus the pageSize and isDistinct flag into a PagedListState. Intended for persisting a grid / picker screen's user state across navigation.
Sets a fixed constraint (WHERE clause) for this list. This constraint is always applied in addition to any column filters.