Package su.onno.ui
Class CatalogQueryService
java.lang.Object
su.onno.ui.CatalogQueryService
Read-side queries for catalogs, shared by the REST API and the DivKit emitters
so the SQL and ref-resolution live in one place. Pure data access — access
control stays with the callers.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaggregate(CatalogDescriptor desc, String metric, String field, String filter) A single aggregate value for a count/metric card —countof rows, orsum|avg|min|maxof one numeric column — restricted to live records and narrowed by an optional safefilterpredicate (seeWidgetFilter).aggregateBuckets(CatalogDescriptor desc, WidgetBuckets.Request request) Grouped aggregate buckets for a chart/stat widget — a server-sideGROUP BYreturning O(buckets) rows instead of the whole table (#199).children(CatalogDescriptor desc, UUID parent) longcount(CatalogDescriptor desc) longcount(CatalogDescriptor desc, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter) Total live rows matching the search (+ declarative filters + widget filter) — for the virtual scroller.estimateCount(CatalogDescriptor desc, boolean filtered) A cheap live-row estimate for the scroll-height hint, ornullwhen none is available.The catalog descriptor for a domain class, ornullif it isn't a registered catalog.get(CatalogDescriptor desc, UUID id) groups(CatalogDescriptor desc, String groupColumn, String granularity, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter, List<ListGroups.Agg> aggregates) Group a catalog list bygroupColumn(a validated sortable column): one header per distinct value, or — for a date/time column — pergranularitybucket, over the same WHERE (search + declarative + widget filters) as the flat list.keysetPage(CatalogDescriptor desc, String cursorToken, int limit, String sortColumn, boolean descending, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter) One keyset-paginated window — the constant-time default for the list grid.newDraft(CatalogDescriptor desc) The seed row for a new catalog form: a fresh instance's field-initializer defaults in the same column-keyed, ref-resolved shapeget(su.onno.metadata.CatalogDescriptor, java.util.UUID)returns for an existing record, so the New form pre-fills declared defaults instead of opening blank (issue #181).newDraft(CatalogDescriptor desc, Map<String, String> prefill) AsnewDraft(CatalogDescriptor), but overlays caller-supplied initial values (from the New-form navigation query, keyed by attribute field name) onto the seed row before ref/enum resolution — so a deep link like…/new?field=valuepre-fills those fields.relatedRows(CatalogDescriptor desc, String viaColumn, UUID parentId) Live rows of a join catalog whoseviaColumnref points atparentId— the read side of a related-list panel (seeRelatedList).rowsByIds(CatalogDescriptor desc, List<UUID> ids) Fetch specific live rows by id, decorated like keyset rows (refs resolved, secrets redacted) so a client can refresh just the rows that changed without re-paging the whole window.search(CatalogDescriptor desc, String query, int limit) Server-side typeahead for ref pickers: case-insensitive match across the same text columns the paged list search covers — code, description, and every (non-secret) String attribute — so a record is findable by a secondary attribute like a phone, not just its name (issue #184).search(CatalogDescriptor desc, String query, int limit, String filter) Assearch(CatalogDescriptor, String, int), additionally narrowed by aWidgetFilterpredicate — the cascading ref picker sends its resolvedrefFilterhere (e.g.Column names that may be sorted on: the system columns + every attribute column.tree(CatalogDescriptor desc)
-
Constructor Details
-
CatalogQueryService
-
-
Method Details
-
require
-
forClass
The catalog descriptor for a domain class, ornullif it isn't a registered catalog. -
search
Server-side typeahead for ref pickers: case-insensitive match across the same text columns the paged list search covers — code, description, and every (non-secret) String attribute — so a record is findable by a secondary attribute like a phone, not just its name (issue #184). Capped atlimit, so a 2000-row catalog never ships whole to the client. -
search
public List<Map<String,Object>> search(CatalogDescriptor desc, String query, int limit, String filter) Assearch(CatalogDescriptor, String, int), additionally narrowed by aWidgetFilterpredicate — the cascading ref picker sends its resolvedrefFilterhere (e.g."supplier = <uuid>"), so only compatible records are offered. Ref/enum columns bind as typed uuids (PG-strict); a null/blank/invalid predicate is simply no filter. -
newDraft
The seed row for a new catalog form: a fresh instance's field-initializer defaults in the same column-keyed, ref-resolved shapeget(su.onno.metadata.CatalogDescriptor, java.util.UUID)returns for an existing record, so the New form pre-fills declared defaults instead of opening blank (issue #181). -
newDraft
AsnewDraft(CatalogDescriptor), but overlays caller-supplied initial values (from the New-form navigation query, keyed by attribute field name) onto the seed row before ref/enum resolution — so a deep link like…/new?field=valuepre-fills those fields. -
count
-
aggregate
A single aggregate value for a count/metric card —countof rows, orsum|avg|min|maxof one numeric column — restricted to live records and narrowed by an optional safefilterpredicate (seeWidgetFilter). -
aggregateBuckets
Grouped aggregate buckets for a chart/stat widget — a server-sideGROUP BYreturning O(buckets) rows instead of the whole table (#199). SeeWidgetBuckets. -
keysetPage
public KeysetPage keysetPage(CatalogDescriptor desc, String cursorToken, int limit, String sortColumn, boolean descending, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter) One keyset-paginated window — the constant-time default for the list grid. Seeks pastcursorToken(null/blank for the first window) instead of counting past an offset, so page 1 and page 10 000 cost the same. Applies server-side sort/search/filters, fetches one extra row to reporthasMorewithout a COUNT, and mints the next cursor from the last row. A cursor minted for a different sort is ignored (paging restarts), and a sort by a column the framework doesn't keep populated uses the NULL-safe seek shape. -
estimateCount
A cheap live-row estimate for the scroll-height hint, ornullwhen none is available. Uses PostgreSQL planner statistics (pg_class.reltuples) so it never scans the table; returnsnullon H2 or whenever a search/filter is active (the estimate can't reflect a predicate). Callers wanting an exact figure usecount(su.onno.metadata.CatalogDescriptor)instead. -
rowsByIds
Fetch specific live rows by id, decorated like keyset rows (refs resolved, secrets redacted) so a client can refresh just the rows that changed without re-paging the whole window. Drives the list island's surgical single-row live patch. Returns only the rows that still exist and aren't deletion-marked, in no particular order; an empty/blank input yields an empty list. -
count
public long count(CatalogDescriptor desc, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter) Total live rows matching the search (+ declarative filters + widget filter) — for the virtual scroller. -
groups
public ListGroups.GroupResult groups(CatalogDescriptor desc, String groupColumn, String granularity, String search, List<String> eq, List<String> in, List<String> like, List<String> prefix, List<String> ge, List<String> le, String widgetFilter, List<ListGroups.Agg> aggregates) Group a catalog list bygroupColumn(a validated sortable column): one header per distinct value, or — for a date/time column — pergranularitybucket, over the same WHERE (search + declarative + widget filters) as the flat list. Each header carries its row count, the requestedaggregates, and theexpandfilter the client replays on the normal feed to load that group's rows. Headers are capped atListGroups.MAX_GROUPS. -
sortableColumns
Column names that may be sorted on: the system columns + every attribute column. -
children
-
tree
-
get
-