feat: allow user to choose between limit/offset and take/skip. (#508)
This commit is contained in:
parent
629b5fb4b5
commit
735b7905c3
31
README.md
31
README.md
@ -259,6 +259,14 @@ const paginateConfig: PaginateConfig<CatEntity> {
|
||||
* Description: Overrides the origin of absolute resource links if set.
|
||||
*/
|
||||
origin: 'http://cats.example',
|
||||
|
||||
/**
|
||||
* Required: false
|
||||
* Type: string
|
||||
* Description: Allow user to choose between limit/offset and take/skip.
|
||||
* Default: PaginationType.TAKE_AND_SKIP
|
||||
*/
|
||||
paginationType: PaginationType.LIMIT_AND_OFFSET,
|
||||
}
|
||||
```
|
||||
|
||||
@ -343,6 +351,29 @@ const config: PaginateConfig<CatEntity> = {
|
||||
const result = await paginate<CatEntity>(query, catRepo, config)
|
||||
```
|
||||
|
||||
## Usage of pagination type
|
||||
|
||||
You can use either `limit`/`offset` or `take`/`skip` to return paginated results.
|
||||
|
||||
### Example
|
||||
|
||||
#### Code
|
||||
|
||||
```typescript
|
||||
const config: PaginateConfig<CatEntity> = {
|
||||
paginationType: PaginationType.LIMIT_AND_OFFSET,
|
||||
// Or
|
||||
paginationType: PaginationType.TAKE_AND_SKIP,
|
||||
}
|
||||
|
||||
const result = await paginate<CatEntity>(query, catRepo, config)
|
||||
```
|
||||
|
||||
> However, using `limit`/`offset` can return unexpected results.
|
||||
> For more information
|
||||
> see [#477](https://github.com/ppetzold/nestjs-paginate/issues/477), [#4742](https://github.com/typeorm/typeorm/issues/4742)
|
||||
> and [#5670](https://github.com/typeorm/typeorm/issues/5670).
|
||||
|
||||
## Single Filters
|
||||
|
||||
Filter operators must be whitelisted per column in `PaginateConfig`.
|
||||
|
@ -52,6 +52,11 @@ export class Paginated<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export enum PaginationType {
|
||||
LIMIT_AND_OFFSET = 'limit',
|
||||
TAKE_AND_SKIP = 'take',
|
||||
}
|
||||
|
||||
export interface PaginateConfig<T> {
|
||||
relations?: FindOptionsRelations<T> | RelationColumn<T>[]
|
||||
sortableColumns: Column<T>[]
|
||||
@ -69,11 +74,13 @@ export interface PaginateConfig<T> {
|
||||
withDeleted?: boolean
|
||||
relativePath?: boolean
|
||||
origin?: string
|
||||
paginationType?: PaginationType
|
||||
}
|
||||
|
||||
export const DEFAULT_MAX_LIMIT = 100
|
||||
export const DEFAULT_LIMIT = 20
|
||||
export const NO_PAGINATION = 0
|
||||
export const DEFAULT_PAGINATE_TYPE = PaginationType.TAKE_AND_SKIP
|
||||
|
||||
export async function paginate<T extends ObjectLiteral>(
|
||||
query: PaginateQuery,
|
||||
@ -85,6 +92,7 @@ export async function paginate<T extends ObjectLiteral>(
|
||||
const defaultLimit = config.defaultLimit || DEFAULT_LIMIT
|
||||
const maxLimit = positiveNumberOrDefault(config.maxLimit, DEFAULT_MAX_LIMIT)
|
||||
const queryLimit = positiveNumberOrDefault(query.limit, defaultLimit)
|
||||
const paginationType = config.paginationType || DEFAULT_PAGINATE_TYPE
|
||||
|
||||
const isPaginated = !(queryLimit === NO_PAGINATION && maxLimit === NO_PAGINATION)
|
||||
|
||||
@ -159,10 +167,14 @@ export async function paginate<T extends ObjectLiteral>(
|
||||
if (isPaginated) {
|
||||
// Switch from take and skip to limit and offset
|
||||
// due to this problem https://github.com/typeorm/typeorm/issues/5670
|
||||
// (anyway this creates more clean query without double dinstict)
|
||||
// (anyway this creates more clean query without double distinct)
|
||||
// queryBuilder.limit(limit).offset((page - 1) * limit)
|
||||
if (paginationType === PaginationType.LIMIT_AND_OFFSET) {
|
||||
queryBuilder.limit(limit).offset((page - 1) * limit)
|
||||
} else {
|
||||
queryBuilder.take(limit).skip((page - 1) * limit)
|
||||
}
|
||||
}
|
||||
|
||||
if (config.relations) {
|
||||
// relations: ["relation"]
|
||||
|
Loading…
Reference in New Issue
Block a user