-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #975 from jboolean/pagination
Pagination for stories and outtakes
- Loading branch information
Showing
18 changed files
with
521 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/bash | ||
PGPASSWORD=$(aws ssm get-parameter --name fourtiesnyc-production-db-password --query Parameter.Value --output text --with-decryption) \ | ||
pg_dump \ | ||
--clean --if-exists --table stories \ | ||
--host $(aws ssm get-parameter --name fourtiesnyc-production-db-host --query Parameter.Value --output text --with-decryption) \ | ||
--port $(aws ssm get-parameter --name fourtiesnyc-production-db-port --query Parameter.Value --output text --with-decryption) \ | ||
--username $(aws ssm get-parameter --name fourtiesnyc-production-db-username --query Parameter.Value --output text --with-decryption) \ | ||
--dbname $(aws ssm get-parameter --name fourtiesnyc-production-db-database --query Parameter.Value --output text --with-decryption) \ | ||
| \ | ||
PGPASSWORD=$(aws ssm get-parameter --name fourtiesnyc-staging-db-password --query Parameter.Value --output text --with-decryption) \ | ||
psql --host $(aws ssm get-parameter --name fourtiesnyc-staging-db-host --query Parameter.Value --output text --with-decryption) \ | ||
--port $(aws ssm get-parameter --name fourtiesnyc-staging-db-port --query Parameter.Value --output text --with-decryption) \ | ||
--username $(aws ssm get-parameter --name fourtiesnyc-staging-db-username --query Parameter.Value --output text --with-decryption) \ | ||
--dbname $(aws ssm get-parameter --name fourtiesnyc-staging-db-database --query Parameter.Value --output text --with-decryption) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
interface Paginated<T> { | ||
items: T[]; | ||
total: number; | ||
hasNextPage: boolean; | ||
nextToken?: string; | ||
} | ||
|
||
export default Paginated; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
interface PaginationInput { | ||
pageToken?: string; | ||
pageSize: number; | ||
} | ||
|
||
export default PaginationInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { ObjectLiteral } from 'typeorm'; | ||
|
||
interface PaginationOptions<E extends ObjectLiteral> { | ||
key: string; | ||
sortDirection?: 'ASC' | 'DESC'; | ||
getSerializedToken: (entity: E) => string; | ||
deserializeToken: (token: string) => unknown; | ||
} | ||
|
||
export default PaginationOptions; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import map from 'lodash/map'; | ||
import Paginated from '../pagination/Paginated'; | ||
|
||
export default function mapPaginated<I, O>( | ||
paginated: Paginated<I>, | ||
fn: (I) => O | ||
): Paginated<O> { | ||
return { | ||
...paginated, | ||
items: map<I, O>(paginated.items, fn), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import last from 'lodash/last'; | ||
import { | ||
FindOperator, | ||
IsNull, | ||
LessThan, | ||
MoreThan, | ||
Not, | ||
ObjectLiteral, | ||
SelectQueryBuilder, | ||
} from 'typeorm'; | ||
import Paginated from '../business/pagination/Paginated'; | ||
import PaginationInput from '../business/pagination/PaginationInput'; | ||
import PaginationOptions from '../business/pagination/PaginationOptions'; | ||
import required from '../business/utils/required'; | ||
|
||
export async function getPaginated<E extends ObjectLiteral>( | ||
qb: SelectQueryBuilder<E>, | ||
{ | ||
key, | ||
sortDirection, | ||
getSerializedToken, | ||
deserializeToken, | ||
}: PaginationOptions<E>, | ||
{ pageToken: nextToken, pageSize }: PaginationInput | ||
): Promise<Paginated<E>> { | ||
let filterOp: FindOperator<unknown> = Not(IsNull()); | ||
if (nextToken) { | ||
const tokenDeserialized = deserializeToken(nextToken); | ||
filterOp = | ||
sortDirection === 'ASC' | ||
? MoreThan(tokenDeserialized) | ||
: LessThan(tokenDeserialized); | ||
} | ||
|
||
const hasWhere = qb.expressionMap.wheres.length > 0; | ||
|
||
// Note clone doesn't actually seem to do anything, so it's important to do count before adding where clauses | ||
const count = await qb.clone().getCount(); | ||
|
||
const results = await qb | ||
.clone() | ||
.orderBy(`${qb.alias}.${key}`, sortDirection) | ||
[hasWhere ? 'andWhere' : 'where']({ | ||
[key]: filterOp, | ||
}) | ||
.take(pageSize + 1) | ||
.getMany(); | ||
|
||
const items = results.slice(0, pageSize); | ||
const hasNextPage = results.length > pageSize; | ||
const nextNextToken = hasNextPage | ||
? getSerializedToken(required(last(items), 'last')) | ||
: undefined; | ||
return { | ||
items, | ||
total: count, | ||
hasNextPage, | ||
nextToken: nextNextToken, | ||
}; | ||
} |
Oops, something went wrong.