A list in numbered pages, read from the query's page (since 0.18.0). The host counts
its rows and reads one page of them; this namespace decides which page that is, and
what a page that no longer exists answers. No SQL and no markup: the statement and the
pager's words are the host's.
A page goes past the end without anyone typing it: the last row of the last page moves
out of a filter, a colleague's move does it, a tab sits open. A well-formed page past
the end therefore answers a 303 to the last page, with the rest of the query kept —
never a 404 for a link that worked a second ago, and never the last page rendered under
a URL that names another. A page nobody could have linked to — junk, zero, a leading
zero, sent twice — is a 404.
keyset (since 0.21.0) pages by position in the order instead of by count: the next page
begins after the last row shown, so a row that leaves the list — a work queue filtered by
a state the work changes — never makes the next page skip one. It gives up "page N of M"
and jumping to a page.
A list in numbered pages, read from the query's `page` (since 0.18.0). The host counts its rows and reads one page of them; this namespace decides which page that is, and what a page that no longer exists answers. No SQL and no markup: the statement and the pager's words are the host's. A page goes past the end without anyone typing it: the last row of the last page moves out of a filter, a colleague's move does it, a tab sits open. A well-formed page past the end therefore answers a 303 to the last page, with the rest of the query kept — never a 404 for a link that worked a second ago, and never the last page rendered under a URL that names another. A `page` nobody could have linked to — junk, zero, a leading zero, sent twice — is a 404. `keyset` (since 0.21.0) pages by position in the order instead of by count: the next page begins after the last row shown, so a row that leaves the list — a work queue filtered by a state the work changes — never makes the next page skip one. It gives up "page N of M" and jumping to a page.
(cursor-path request direction cursor)The path of the same list from a cursor: direction :after or :before, or nil for
its first page. The router's path, with every query parameter but the cursors kept.
The path of the same list from a cursor: `direction` `:after` or `:before`, or nil for its first page. The router's path, with every query parameter but the cursors kept.
(keyset request {:keys [size cursor decode fetch]} f)(f {:rows … :next path-or-nil :previous path-or-nil}) for the page the query asks of
a list read by position. The host gives
:size, rows to a page;:cursor, a row's cursor — a string of URL-safe characters, its key in the order;:decode, a cursor back to the key it names, or nil for any cursor it cannot read
or whose row is gone — never a throw, which would answer a crafted link with a 500;:fetch, called with {:direction :first|:after|:before :key k :limit l}, answering up
to l rows in the list's order from the start, after k, or — for :before — before
k nearest first, so in the reverse order: ORDER BY k DESC for a list read
ORDER BY k.
It asks for one row more than a page to know whether there is another, and gives the
:before rows back in the list's order.For a list ordered by a column a that may tie, and then by a unique id, the key is
the anchor row's [a id], and fetch reads, after it, the rows whose a is greater,
or equal with a greater id — a > ? OR (a = ? AND id > ?), ordered a, id — and
before it the mirror: a < ? OR (a = ? AND id < ?), ordered a DESC, id DESC. The
anchor is read again by decode, scoped as the list is, so a cursor from another
list's row is no cursor here.
Test :before with at least three pages, and a cursor on a row that ties with the one
before it. With two, every before reaches the start, which is a 303 to the first page
whatever the SQL says: a < written >, an ascending order or a flipped tie term all
stay green (measured by a host, academy FRICTION A24).
A cursor whose row is gone, a page with no rows under a cursor, and a before that
reaches the start each answer a 303 to the first page: the start has one spelling, and a
link that worked a second ago is never a 404. A cursor of a shape nobody builds is a
404. A :sessionless route is refused, as in paged.
`(f {:rows … :next path-or-nil :previous path-or-nil})` for the page the query asks of
a list read by position. The host gives
- `:size`, rows to a page;
- `:cursor`, a row's cursor — a string of URL-safe characters, its key in the order;
- `:decode`, a cursor back to the key it names, or nil for any cursor it cannot read
or whose row is gone — never a throw, which would answer a crafted link with a 500;
- `:fetch`, called with `{:direction :first|:after|:before :key k :limit l}`, answering up
to `l` rows in the list's order from the start, after `k`, or — for `:before` — before
`k` nearest first, so in the reverse order: `ORDER BY k DESC` for a list read
`ORDER BY k`.
It asks for one row more than a page to know whether there is another, and gives the
`:before` rows back in the list's order.
For a list ordered by a column `a` that may tie, and then by a unique `id`, the key is
the anchor row's `[a id]`, and `fetch` reads, after it, the rows whose `a` is greater,
or equal with a greater `id` — `a > ? OR (a = ? AND id > ?)`, ordered `a, id` — and
before it the mirror: `a < ? OR (a = ? AND id < ?)`, ordered `a DESC, id DESC`. The
anchor is read again by `decode`, scoped as the list is, so a cursor from another
list's row is no cursor here.
Test `:before` with at least three pages, and a cursor on a row that ties with the one
before it. With two, every `before` reaches the start, which is a 303 to the first page
whatever the SQL says: a `<` written `>`, an ascending order or a flipped tie term all
stay green (measured by a host, academy FRICTION A24).
A cursor whose row is gone, a page with no rows under a cursor, and a `before` that
reaches the start each answer a 303 to the first page: the start has one spelling, and a
link that worked a second ago is never a 404. A cursor of a shape nobody builds is a
404. A `:sessionless` route is refused, as in `paged`.(paged request total size f)(f {:page p :pages m :offset o :limit size}) for the page the query asks of a list
of total rows, size to a page, or a 303 to the last page when the one asked is
past it. An empty list has one page, empty. A page nobody could have linked to is a
404. The count and the page are the host's two reads: a row that leaves between them
makes the last page short, never a redirect.
A :sessionless route is refused: it is answered before the query is parsed, so every
page would read as page 1, in silence.
`(f {:page p :pages m :offset o :limit size})` for the page the query asks of a list
of `total` rows, `size` to a page, or a 303 to the last page when the one asked is
past it. An empty list has one page, empty. A `page` nobody could have linked to is a
404. The count and the page are the host's two reads: a row that leaves between them
makes the last page short, never a redirect.
A `:sessionless` route is refused: it is answered before the query is parsed, so every
`page` would read as page 1, in silence.(path request n)The path of page n of the list request asked for: the path the router matched, so
only one of the host's routes can become a Location, with every query parameter but
page kept — a filter survives. Page 1 is spelt without page, so a link and a
redirect to it agree. A request the router did not answer has no such path, and is
refused.
The path of page `n` of the list `request` asked for: the path the router matched, so only one of the host's routes can become a Location, with every query parameter but `page` kept — a filter survives. Page 1 is spelt without `page`, so a link and a redirect to it agree. A request the router did not answer has no such path, and is refused.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |