From 91e6bf6c4d595ba6dba65689b6b33897f2828d85 Mon Sep 17 00:00:00 2001 From: Eamon Date: Fri, 14 Apr 2023 17:25:32 +0200 Subject: [PATCH] feat: add support for text pagination --- src/constants.ts | 2 ++ src/data-access/texts.ts | 20 +++++++++++++++----- src/routes/texts.ts | 14 +++++++------- src/services/texts.ts | 22 +++++++++++++++++----- 4 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 src/constants.ts diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..93ce330 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,2 @@ +/* eslint-disable import/prefer-default-export */ +export const DEFAULT_OFFSET = 10; diff --git a/src/data-access/texts.ts b/src/data-access/texts.ts index 05d2202..0bbd656 100644 --- a/src/data-access/texts.ts +++ b/src/data-access/texts.ts @@ -2,6 +2,7 @@ import { QueryResult } from 'pg'; import dbQuery from '../model/db-query'; import { Text } from '../types'; +import { DEFAULT_OFFSET } from '../constants'; const getAll = async function (): Promise { const ALL_TEXTS: string = ` @@ -24,14 +25,23 @@ const getById = async function (textId: number): Promise { const getByUserAndLanguage = async function ( userId: number, - languageId: string + languageId: string, + page: number ): Promise { const TEXTS_BY_USER: string = ` - SELECT * FROM texts - WHERE user_id = %L AND language_id = %L - ORDER BY upload_time DESC NULLS LAST`; + SELECT *, COUNT(*) OVER () as totalTexts + FROM texts + WHERE user_id = %L AND language_id = %L + ORDER BY upload_time DESC NULLS LAST + OFFSET %L FETCH NEXT %L ROWS ONLY`; - const result = await dbQuery(TEXTS_BY_USER, userId, languageId); + const result = await dbQuery( + TEXTS_BY_USER, + userId, + languageId, + DEFAULT_OFFSET * page, + DEFAULT_OFFSET + ); return result; }; diff --git a/src/routes/texts.ts b/src/routes/texts.ts index c9e2553..f49b95a 100644 --- a/src/routes/texts.ts +++ b/src/routes/texts.ts @@ -1,19 +1,19 @@ import express from 'express'; import texts from '../services/texts'; import users from '../services/users'; -import { Text } from '../types'; +import { TextPagination, Text } from '../types'; const router: express.Router = express.Router(); -router.get('/language/:languageId/', async (req, res): Promise => { +router.get('/language/:languageId/:page/', async (req, res): Promise => { const { user } = res.locals; - const { languageId } = req.params; - - const allTexts: Array = await texts.getByUserAndLanguage( + const { languageId, page } = req.params; + const textPagination: TextPagination = await texts.getByUserAndLanguage( Number(user.id), - languageId + languageId, + page ); - res.json(allTexts); + res.json(textPagination); }); router.get('/:id', async (req, res): Promise => { diff --git a/src/services/texts.ts b/src/services/texts.ts index decd742..16d4202 100644 --- a/src/services/texts.ts +++ b/src/services/texts.ts @@ -1,7 +1,8 @@ import boom from '@hapi/boom'; import { QueryResult } from 'pg'; import textData from '../data-access/texts'; -import { convertTextTypes, Text, TextDB } from '../types'; +import { convertTextTypes, TextPagination, Text, TextDB } from '../types'; +import { DEFAULT_OFFSET } from '../constants'; const getAll = async function (): Promise> { const result: QueryResult = await textData.getAll(); @@ -20,14 +21,25 @@ const getById = async function (textId: number): Promise { const getByUserAndLanguage = async function ( userId: number, - languageId: string -): Promise> { + languageId: string, + pageNumber: string +): Promise { const result: QueryResult = await textData.getByUserAndLanguage( userId, - languageId + languageId, + Number(pageNumber) - 1 ); - return result.rows.map((dbItem: TextDB) => convertTextTypes(dbItem)); + const totalTexts = result.rows[0]?.totaltexts || 0; + const paginatedTexts: TextPagination = { + currentPage: Number(pageNumber), + totalPages: Math.ceil(totalTexts / DEFAULT_OFFSET), + totalTexts, + nextPage: Number(pageNumber) + 1, + prevPage: Number(pageNumber) - 1, + data: result.rows.map((dbItem: TextDB) => convertTextTypes(dbItem)), + }; + return paginatedTexts; }; const addNew = async function (textObject: Text): Promise {