From 6e8e0e0101a9438cfccdf8feba47aed01b01f0e9 Mon Sep 17 00:00:00 2001 From: j-weissen Date: Mon, 12 Dec 2022 11:35:53 +0100 Subject: [PATCH] added Model classes --- backend/README.md | 16 +++++++- backend/api/.dockerignore | 2 + backend/api/src/Database.ts | 24 ++++++++++++ backend/api/src/app.ts | 37 +++++++++++-------- backend/api/src/exampleEndpoints.ts | 16 -------- backend/api/src/leaderboardRouter.ts | 11 ++++++ .../api/src/manager/LeaderBoardSerializer.ts | 3 ++ backend/api/src/manager/UserDataManager.ts | 20 ++++++++++ .../manager/UserDataPgPromiseSerializer.ts | 19 ++++++++++ backend/api/src/manager/UserDataSerializer.ts | 6 +++ backend/api/src/model/Leaderboard.ts | 5 +++ backend/api/src/model/LeaderboardEntry.ts | 5 +++ backend/api/src/model/Time.ts | 6 +++ backend/api/src/model/UserData.ts | 8 ++++ 14 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 backend/api/.dockerignore create mode 100644 backend/api/src/Database.ts delete mode 100644 backend/api/src/exampleEndpoints.ts create mode 100644 backend/api/src/leaderboardRouter.ts create mode 100644 backend/api/src/manager/LeaderBoardSerializer.ts create mode 100644 backend/api/src/manager/UserDataManager.ts create mode 100644 backend/api/src/manager/UserDataPgPromiseSerializer.ts create mode 100644 backend/api/src/manager/UserDataSerializer.ts create mode 100644 backend/api/src/model/Leaderboard.ts create mode 100644 backend/api/src/model/LeaderboardEntry.ts create mode 100644 backend/api/src/model/Time.ts create mode 100644 backend/api/src/model/UserData.ts diff --git a/backend/README.md b/backend/README.md index bbb4279..e70fd37 100644 --- a/backend/README.md +++ b/backend/README.md @@ -24,4 +24,18 @@ erDiagram int average_score int games_played } -``` \ No newline at end of file + + lb_highscore { + int rank + string username + int highscore + } + + lb_total_playtime { + int rank + string username + time total_playtime + } +``` + +## API Endpoints diff --git a/backend/api/.dockerignore b/backend/api/.dockerignore new file mode 100644 index 0000000..3e2e84b --- /dev/null +++ b/backend/api/.dockerignore @@ -0,0 +1,2 @@ +build/ +node_modules/ diff --git a/backend/api/src/Database.ts b/backend/api/src/Database.ts new file mode 100644 index 0000000..99d789d --- /dev/null +++ b/backend/api/src/Database.ts @@ -0,0 +1,24 @@ +import pgPromise from "pg-promise"; + + +export abstract class Database { + static db = null; + get db() { + if (Database.db == null) { + Database.db = pgPromise({})('postgres://postgres:postgres@db:5432/rr') + } + return Database.db; + } + + static async catcher(request): Promise { + let data; + try { + data = await request(); + } catch (e) { + console.log((e as Error).message) + } + return data; + } + + +} \ No newline at end of file diff --git a/backend/api/src/app.ts b/backend/api/src/app.ts index ee69f12..9b08420 100644 --- a/backend/api/src/app.ts +++ b/backend/api/src/app.ts @@ -1,9 +1,13 @@ import express from 'express'; +import {Database} from "./Database.js"; -import pgPromise from "pg-promise"; import helmet from "helmet"; import bodyParser from "body-parser"; import morgan from 'morgan'; +import {UserDataManager} from "./manager/UserDataManager.js"; +import {UserDataPgPromiseSerializer} from "./manager/UserDataPgPromiseSerializer.js"; +import {leaderboardRouter} from "./leaderboardRouter.js"; + const app = express() const port = 3000 @@ -14,30 +18,31 @@ app.use(helmet()) let morganFormatted = morgan('[:date[iso]] :method :url - :status') app.use(morganFormatted); -// init database connection -const pgp = pgPromise({}); -const db = pgp('postgres://postgres:postgres@db:5432/rr') +app.use('/leaderboard', leaderboardRouter) app.get('/helloworld', (req, res) => { res.json({message: "Hello World!"}) }) app.get('/highscore', async (req, res) => { - let data = await dbQueryCatcher(async () => - await db.manyOrNone('SELECT * FROM lb_highscore;') - ) + let data = await Database.db.manyOrNone('SELECT * FROM lb_highscore;') + .catch((error) => console.log(error.message)) res.json(data) }) -async function dbQueryCatcher(request): Promise { - let data; - try { - data = await request(); - } catch (e) { - console.log((e as Error).message) - } - return data; -} +app.get('/user/:username', async (req, res) => { + let data = await Database.db.oneOrNone( + 'SELECT * FROM user_data WHERE username = $1;', + [req.params.username]) + .catch((error) => console.log(error.message) + ) + let userDataManager: UserDataManager = new UserDataManager(data, new UserDataPgPromiseSerializer); + res.json(userDataManager.userData); +}) + + + + app.listen(port, () => { console.log(`Server started at http://localhost:3000`); diff --git a/backend/api/src/exampleEndpoints.ts b/backend/api/src/exampleEndpoints.ts deleted file mode 100644 index 4b3afb7..0000000 --- a/backend/api/src/exampleEndpoints.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as express from 'express'; -import * as bodyParser from "body-parser"; - -let router = express.Router(); - -router.use(bodyParser.json()) - -router.get('/helloworld', (req, res) => { - res.json({message: "Hello World!"}) -}) - -router.post('/echo', (req, res) => { - res.json(req.body) -}) - -module.exports = router \ No newline at end of file diff --git a/backend/api/src/leaderboardRouter.ts b/backend/api/src/leaderboardRouter.ts new file mode 100644 index 0000000..d4b0deb --- /dev/null +++ b/backend/api/src/leaderboardRouter.ts @@ -0,0 +1,11 @@ +import express from 'express'; +export const leaderboardRouter = express.Router() + + +leaderboardRouter.get('/highscore', (req, res) => { + res.send('highscore') +}) + +leaderboardRouter.get('/totalplaytime', (req, res) => { + res.send('total play time') +}) \ No newline at end of file diff --git a/backend/api/src/manager/LeaderBoardSerializer.ts b/backend/api/src/manager/LeaderBoardSerializer.ts new file mode 100644 index 0000000..41a6a68 --- /dev/null +++ b/backend/api/src/manager/LeaderBoardSerializer.ts @@ -0,0 +1,3 @@ +export interface LeaderBoardSerializer { + +} \ No newline at end of file diff --git a/backend/api/src/manager/UserDataManager.ts b/backend/api/src/manager/UserDataManager.ts new file mode 100644 index 0000000..c28aad8 --- /dev/null +++ b/backend/api/src/manager/UserDataManager.ts @@ -0,0 +1,20 @@ +import {UserData} from "../model/UserData.js"; +import {UserDataSerializer} from "./UserDataSerializer.js"; + +export class UserDataManager { + private _userData: UserData; + private serializer: UserDataSerializer; + + constructor(data: any, serializer: UserDataSerializer) { + this.serializer = serializer; + this._userData = this.serializer.serialize(data); + } + + get userData(): UserData { + return this._userData; + } + + set userData(value: UserData) { + this._userData = value; + } +} \ No newline at end of file diff --git a/backend/api/src/manager/UserDataPgPromiseSerializer.ts b/backend/api/src/manager/UserDataPgPromiseSerializer.ts new file mode 100644 index 0000000..4721740 --- /dev/null +++ b/backend/api/src/manager/UserDataPgPromiseSerializer.ts @@ -0,0 +1,19 @@ +import {UserData} from "../model/UserData.js"; +import {UserDataSerializer} from "./UserDataSerializer.js"; + +export class UserDataPgPromiseSerializer implements UserDataSerializer { + deserialize(userData: UserData): any { + throw new Error("Method not implemented") + } + + serialize(data: any): UserData { + return { + username: data.username, + highscore: data.highscore, + totalScore: data.total_score, + totalPlaytime: data.total_playtime, + averageScore: data.averageScore, + gamesPlayed: data.games_played, + } + } +} \ No newline at end of file diff --git a/backend/api/src/manager/UserDataSerializer.ts b/backend/api/src/manager/UserDataSerializer.ts new file mode 100644 index 0000000..9d54880 --- /dev/null +++ b/backend/api/src/manager/UserDataSerializer.ts @@ -0,0 +1,6 @@ +import {UserData} from "../model/UserData.js"; + +export interface UserDataSerializer { + serialize(data: any): UserData, + deserialize(userData: UserData): any, +} \ No newline at end of file diff --git a/backend/api/src/model/Leaderboard.ts b/backend/api/src/model/Leaderboard.ts new file mode 100644 index 0000000..406962a --- /dev/null +++ b/backend/api/src/model/Leaderboard.ts @@ -0,0 +1,5 @@ +import {LeaderboardEntry} from "./LeaderboardEntry.js"; + +export class Leaderboard { + content: LeaderboardEntry[]; +} \ No newline at end of file diff --git a/backend/api/src/model/LeaderboardEntry.ts b/backend/api/src/model/LeaderboardEntry.ts new file mode 100644 index 0000000..b43f6dd --- /dev/null +++ b/backend/api/src/model/LeaderboardEntry.ts @@ -0,0 +1,5 @@ +export interface LeaderboardEntry { + rank: number, + username: string, + score: T, +} \ No newline at end of file diff --git a/backend/api/src/model/Time.ts b/backend/api/src/model/Time.ts new file mode 100644 index 0000000..69cf57b --- /dev/null +++ b/backend/api/src/model/Time.ts @@ -0,0 +1,6 @@ +export interface Time { + seconds: number, + minutes?: number, + hours?: number, + days?: number, +} \ No newline at end of file diff --git a/backend/api/src/model/UserData.ts b/backend/api/src/model/UserData.ts new file mode 100644 index 0000000..8845351 --- /dev/null +++ b/backend/api/src/model/UserData.ts @@ -0,0 +1,8 @@ +export interface UserData { + username: string, + highscore: number, + totalScore: number, + totalPlaytime: string, + averageScore: number, + gamesPlayed: number, +} \ No newline at end of file