| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Database.Esqueleto.Pagination
Description
This module provides efficient pagination over your database queries.
No OFFSET here - we use ranges to do this right!
The ideal "range" column for a datatype has a few properties:
- It should have an index. An index on the column will dramatically improve performance on pagination.
- It should be monotonic - that is, we shouldn't be able to insert new
data into the middle of a range. An example would be a
created_attimestamp field, or a auto-incrementing primary key.
This module offers two ways to page through a database. You can use the
streamingEntities to get a ConduitT of values
streaming out. Or, if you'd like finer control, you can use Entity recordgetPage
to get the first page of data, and then nextPage to get the next
possible page of data.
Synopsis
- data Page record typ = Page {
- pageRecords :: [Entity record]
- pageRecordCount :: Int
- pageRange :: Range typ
- pageDesiredRange :: DesiredRange typ
- pageField :: EntityField record typ
- pageFilters :: SqlExpr (Entity record) -> SqlExpr (Value Bool)
- pageSize :: PageSize
- pageSortOrder :: SortOrder
- streamEntities :: forall record backend typ m a. (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) => (SqlExpr (Entity record) -> SqlExpr (Value Bool)) -> EntityField record typ -> PageSize -> SortOrder -> DesiredRange typ -> ConduitT a (Entity record) (ReaderT backend m) ()
- rangeToFilters :: (PersistField typ, PersistEntity record) => Range (Maybe typ) -> EntityField record typ -> SqlExpr (Entity record) -> SqlQuery ()
- getPage :: forall record backend typ m. (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) => (SqlExpr (Entity record) -> SqlExpr (Value Bool)) -> EntityField record typ -> PageSize -> SortOrder -> DesiredRange typ -> ReaderT backend m (Maybe (Page record typ))
- nextPage :: (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) => Page record typ -> ReaderT backend m (Maybe (Page record typ))
- emptyQuery :: SqlExpr (Entity record) -> SqlExpr (Value Bool)
- module Database.Persist.Pagination.Types
Documentation
A describes a list of records and enough
information necessary to acquire the next page of records, if possible.Page record typ
This is a distinct type from the Page in Database.Persist.Pagination
because the pageFilters field needs a different type. As a result,
some of this stuff is duplicated. It's possible that this can be fixed
and more code could be shared.
Since: 0.1.1.0
Constructors
| Page | |
Fields
| |
Arguments
| :: forall record backend typ m a. (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) | |
| => (SqlExpr (Entity record) -> SqlExpr (Value Bool)) | The filters to apply. |
| -> EntityField record typ | The field to sort on. This field should have an index on it, and
ideally, the field should be monotonic - that is, you can only
insert values at either extreme end of the range. A |
| -> PageSize | How many records in a page |
| -> SortOrder | Ascending or descending |
| -> DesiredRange typ | The desired range. Provide |
| -> ConduitT a (Entity record) (ReaderT backend m) () |
Stream entities out of the database, only pulling a limited amount into memory at a time.
You should use this instead of selectSource because selectSource
doesn't really work. It doesn't work at all in MySQL, and it's somewhat
sketchy with PostgreSQL and SQLite. This function is guaranteed to use
only as much memory as a single page, and if you tune the page size
right, you'll get efficient queries from the database.
There's an open issue for selectSource not working:
GitHub Issue.
Since: 0.1.1.0
rangeToFilters :: (PersistField typ, PersistEntity record) => Range (Maybe typ) -> EntityField record typ -> SqlExpr (Entity record) -> SqlQuery () Source #
Convert a into a DesiredRange typSqlQuery that operates on the
range. The DesiredRange is treated as an exclusive range.
Since: 0.1.1.0
Arguments
| :: forall record backend typ m. (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) | |
| => (SqlExpr (Entity record) -> SqlExpr (Value Bool)) | The filters to apply. |
| -> EntityField record typ | The field to sort on. This field should have an index on it, and
ideally, the field should be monotonic - that is, you can only
insert values at either extreme end of the range. A |
| -> PageSize | How many records in a page |
| -> SortOrder | Ascending or descending |
| -> DesiredRange typ | The desired range. Provide |
| -> ReaderT backend m (Maybe (Page record typ)) |
Get the first Page according to the given criteria. This returns
a , because there may not actually be any records that
correspond to the query you issue. You can call Maybe PagepageRecords on the
result object to get the row of records for this page, and you can call
nextPage with the Page object to get the next page, if one exists.
This function gives you lower level control over pagination than the
streamEntities function.
Since: 0.1.1.0
nextPage :: (PersistRecordBackend record backend, PersistQueryRead backend, PersistUniqueRead backend, BackendCompatible SqlBackend backend, BackendCompatible SqlBackend (BaseBackend backend), Ord typ, PersistField typ, MonadIO m) => Page record typ -> ReaderT backend m (Maybe (Page record typ)) Source #
Retrieve the next Page of data, if possible.
Since: 0.1.1.0