diff --git a/backend/api/src/leaderboardRoute.ts b/backend/api/src/leaderboardRoute.ts index e77fb2e..0c5ce51 100644 --- a/backend/api/src/leaderboardRoute.ts +++ b/backend/api/src/leaderboardRoute.ts @@ -1,4 +1,5 @@ import express from 'express'; +import {query, validationResult} from 'express-validator'; import {TimeLeaderboardRepository} from "./repositories/TimeLeaderboardRepository.js"; import {TimeLeaderboardPgPromiseRepository} from "./repositories/pgPromise/TimeLeaderboardPgPromiseRepository.js"; import {HighscoreLeaderboardPgPromiseRepository} from "./repositories/pgPromise/HighscoreLeaderboardPgPromiseRepository.js"; @@ -8,6 +9,9 @@ import {HighscoreLeaderboard, TimeLeaderboard} from "./model/Leaderboard.js"; export const leaderboardRoute = express.Router() leaderboardRoute.get('/highscore', + query('pagination').toBoolean(), + query('entriesPerPage').optional().isInt({min: 1}).toInt(), + query('page').optional().isInt({min: 0}).toInt(), /** * Returns the highscore leaderboard as JSON response, fetched from DB * @param req @@ -15,8 +19,21 @@ leaderboardRoute.get('/highscore', */ async (req, res) => { try { + //region validate parameters + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(400).json({ errors: errors.array() }); + } + //endregion const highscoreLeaderboardRepo: HighscoreLeaderboardRepository = new HighscoreLeaderboardPgPromiseRepository; - const highscoreLeaderboard: HighscoreLeaderboard = await highscoreLeaderboardRepo.getAll(); + let highscoreLeaderboard: HighscoreLeaderboard; + if (req.query.pagination) { + const entriesPerPage = req.query.entriesPerPage; + const page = req.query.page; + highscoreLeaderboard = await highscoreLeaderboardRepo.getPage(entriesPerPage, page); + } else { + highscoreLeaderboard = await highscoreLeaderboardRepo.getAll(); + } res.send(highscoreLeaderboard); } catch (error) { // handle errors @@ -26,6 +43,9 @@ leaderboardRoute.get('/highscore', }) leaderboardRoute.get('/totalplaytime', + query('pagination').toBoolean(), + query('entriesPerPage').optional().isInt({min: 1}).toInt(), + query('page').optional().isInt({min: 0}).toInt(), /** * Returns the total playtime leaderboard as JSON response, fetched from DB * @param req @@ -33,8 +53,21 @@ leaderboardRoute.get('/totalplaytime', */ async (req, res) => { try { + //region validate parameters + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(400).json({ errors: errors.array() }); + } + //endregion const timeLeaderboardRepo: TimeLeaderboardRepository = new TimeLeaderboardPgPromiseRepository; - const timeLeaderboard: TimeLeaderboard = await timeLeaderboardRepo.getAll(); + let timeLeaderboard: TimeLeaderboard; + if (req.query.pagination) { + const entriesPerPage = req.query.entriesPerPage; + const page = req.query.page; + timeLeaderboard = await timeLeaderboardRepo.getPage(entriesPerPage, page); + } else { + timeLeaderboard = await timeLeaderboardRepo.getAll(); + } res.send(timeLeaderboard); } catch (error) { // handle errors diff --git a/backend/api/src/repositories/HighscoreLeaderboardRepository.ts b/backend/api/src/repositories/HighscoreLeaderboardRepository.ts index 204feff..d70d3d5 100644 --- a/backend/api/src/repositories/HighscoreLeaderboardRepository.ts +++ b/backend/api/src/repositories/HighscoreLeaderboardRepository.ts @@ -2,4 +2,5 @@ import {HighscoreLeaderboard} from "../model/Leaderboard.js"; export abstract class HighscoreLeaderboardRepository { abstract getAll(): Promise; + abstract getPage(entriesPerPage: number, page: number): Promise } \ No newline at end of file diff --git a/backend/api/src/repositories/TimeLeaderboardRepository.ts b/backend/api/src/repositories/TimeLeaderboardRepository.ts index ef9d8fe..8c02717 100644 --- a/backend/api/src/repositories/TimeLeaderboardRepository.ts +++ b/backend/api/src/repositories/TimeLeaderboardRepository.ts @@ -2,4 +2,5 @@ import {TimeLeaderboard} from "../model/Leaderboard.js"; export abstract class TimeLeaderboardRepository { abstract getAll(): Promise; + abstract getPage(entriesPerPage: number, page: number); } \ No newline at end of file diff --git a/backend/api/src/repositories/pgPromise/HighscoreLeaderboardPgPromiseRepository.ts b/backend/api/src/repositories/pgPromise/HighscoreLeaderboardPgPromiseRepository.ts index 8a7747c..36c9043 100644 --- a/backend/api/src/repositories/pgPromise/HighscoreLeaderboardPgPromiseRepository.ts +++ b/backend/api/src/repositories/pgPromise/HighscoreLeaderboardPgPromiseRepository.ts @@ -5,7 +5,15 @@ import {Database} from "../../Database.js"; export class HighscoreLeaderboardPgPromiseRepository extends HighscoreLeaderboardRepository { async getAll(): Promise { const raw: any = await Database.db.manyOrNone( - 'SELECT * FROM lb_highscore INNER JOIN "user" ON user_id = id ORDER BY RANK;' + 'SELECT * FROM lb_highscore INNER JOIN "user" ON user_id = id ORDER BY rank;' + ); + return this.serialize(raw); + } + + async getPage(entriesPerPage, page): Promise { + const raw: any = await Database.db.manyOrNone( + 'SELECT * FROM lb_highscore INNER JOIN "user" ON user_id = id ORDER BY rank LIMIT $1 OFFSET $2;', + [entriesPerPage, page * entriesPerPage] ); return this.serialize(raw); } diff --git a/backend/api/src/repositories/pgPromise/TimeLeaderboardPgPromiseRepository.ts b/backend/api/src/repositories/pgPromise/TimeLeaderboardPgPromiseRepository.ts index 1345562..b2b2ca8 100644 --- a/backend/api/src/repositories/pgPromise/TimeLeaderboardPgPromiseRepository.ts +++ b/backend/api/src/repositories/pgPromise/TimeLeaderboardPgPromiseRepository.ts @@ -5,7 +5,15 @@ import {Database} from "../../Database.js"; export class TimeLeaderboardPgPromiseRepository extends TimeLeaderboardRepository { async getAll(): Promise { const raw: any = await Database.db.manyOrNone( - 'SELECT * FROM lb_total_playtime INNER JOIN "user" ON user_id = id ORDER BY RANK;' + 'SELECT * FROM lb_total_playtime INNER JOIN "user" ON user_id = id ORDER BY rank;' + ); + return this.serialize(raw); + } + + async getPage(entriesPerPage: number, page: number): Promise { + const raw: any = await Database.db.manyOrNone( + 'SELECT * FROM lb_total_playtime INNER JOIN "user" ON user_id = id ORDER BY rank LIMIT $1 OFFSET $2;', + [entriesPerPage, page * entriesPerPage] ); return this.serialize(raw); } diff --git a/frontend/public/main.js b/frontend/public/main.js deleted file mode 100644 index aa986fc..0000000 --- a/frontend/public/main.js +++ /dev/null @@ -1,12 +0,0 @@ -function setup() { - createCanvas(400, 400); - } - -function draw() { - if (mouseIsPressed) { - fill(0); - } else { - fill(255); - } - ellipse(mouseX, mouseY, 80, 80); -} \ No newline at end of file