added Serializer & Manager classes

This commit is contained in:
j-weissen 2022-12-14 00:10:02 +01:00
parent d76110d06b
commit 2219ea93bf
24 changed files with 254 additions and 111 deletions

View file

@ -2,23 +2,11 @@ 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')
private static _db = null;
static get db() {
if (Database._db == null) {
Database._db = pgPromise({})('postgres://postgres:postgres@db:5432/rr')
}
return Database.db;
return Database._db;
}
static async catcher(request): Promise<any> {
let data;
try {
data = await request();
} catch (e) {
console.log((e as Error).message)
}
return data;
}
}

View file

@ -1,12 +1,8 @@
import express from 'express';
import {Database} from "./Database.js";
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";
import {leaderboardRoute} from "./leaderboardRoute.js";
import {userRoute} from "./userRoute.js";
const app = express()
@ -18,31 +14,13 @@ app.use(helmet())
let morganFormatted = morgan('[:date[iso]] :method :url - :status')
app.use(morganFormatted);
app.use('/leaderboard', leaderboardRouter)
app.use('/leaderboard', leaderboardRoute)
app.use('/user', userRoute)
app.get('/helloworld', (req, res) => {
res.json({message: "Hello World!"})
})
app.get('/highscore', async (req, res) => {
let data = await Database.db.manyOrNone('SELECT * FROM lb_highscore;')
.catch((error) => console.log(error.message))
res.json(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`);

View file

@ -0,0 +1,23 @@
import express from 'express';
import {Database} from "./Database.js";
import {TimeLeaderboardManager} from "./manager/TimeLeaderboardManager.js";
import {HighscoreLeaderboardManager} from "./manager/HighscoreLeaderboardManager.js";
import {
HighscoreLeaderboardPgPromiseSerializer
} from "./serializer/pgpromise/HighscoreLeaderboardPgPromiseSerializer.js";
import {TimeLeaderboardPgPromiseSerializer} from "./serializer/pgpromise/TimeLeaderboardPgPromiseSerializer.js";
export const leaderboardRoute = express.Router()
leaderboardRoute.get('/highscore', async (req, res) => {
let data = await Database.db.manyOrNone('SELECT * FROM lb_highscore INNER JOIN "user" ON user_id = id ORDER BY RANK;')
const leaderboardManager = new HighscoreLeaderboardManager(data, new HighscoreLeaderboardPgPromiseSerializer);
res.send(leaderboardManager.content)
})
leaderboardRoute.get('/totalplaytime', async (req, res) => {
let data = await Database.db.manyOrNone('SELECT * FROM lb_total_playtime INNER JOIN "user" ON user_id = id ORDER BY RANK;')
const leaderboardManager = new TimeLeaderboardManager(data, new TimeLeaderboardPgPromiseSerializer);
res.send(leaderboardManager.content)
})

View file

@ -1,11 +0,0 @@
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')
})

View file

@ -0,0 +1,32 @@
import {Leaderboard} from "../model/Leaderboard.js";
import {Manager} from "./Manager.js";
import {HighscoreLeaderboardSerializer} from "../serializer/HighscoreLeaderboardSerializer.js";
export class HighscoreLeaderboardManager implements Manager<Leaderboard<number>>{
private _content: Leaderboard<number>;
private _serializer: HighscoreLeaderboardSerializer;
constructor(rawData: any, serializer: HighscoreLeaderboardSerializer) {
this.serializer = serializer;
this._content = this.serializer.serialize(rawData);
}
//region getter&setter
get content() {
return this._content;
}
set content(value: Leaderboard<number>) {
this._content = value;
}
get serializer() {
return this._serializer;
}
set serializer(value: HighscoreLeaderboardSerializer) {
this._serializer = value;
}
//endregion
}

View file

@ -1,3 +0,0 @@
export interface LeaderBoardSerializer {
}

View file

@ -0,0 +1,8 @@
import {Serializer} from "../serializer/Serializer.js";
export interface Manager<T> {
get content(),
set content(value: T),
get serializer(),
set serializer(value: Serializer<T>),
}

View file

@ -0,0 +1,34 @@
import {Manager} from "./Manager.js";
import {Leaderboard} from "../model/Leaderboard.js";
import {Time} from "../model/Time.js";
import {TimeLeaderboardSerializer} from "../serializer/TimeLeaderboardSerializer.js";
import {TimeLeaderboardPgPromiseSerializer} from "../serializer/pgpromise/TimeLeaderboardPgPromiseSerializer.js";
export class TimeLeaderboardManager implements Manager<Leaderboard<Time>> {
private _content: Leaderboard<Time>;
private _serializer: TimeLeaderboardPgPromiseSerializer
constructor(data: any, serializer: TimeLeaderboardSerializer) {
this._serializer = serializer;
this._content = this._serializer.serialize(data);
}
//region getter&setter
get content() {
return this._content;
}
set content(value: Leaderboard<Time>) {
this._content = value;
}
get serializer(): TimeLeaderboardPgPromiseSerializer {
return this._serializer;
}
set serializer(value: TimeLeaderboardPgPromiseSerializer) {
this._serializer = value;
}
//endregion
}

View file

@ -1,20 +0,0 @@
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;
}
}

View file

@ -1,19 +0,0 @@
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,
}
}
}

View file

@ -1,6 +0,0 @@
import {UserData} from "../model/UserData.js";
export interface UserDataSerializer {
serialize(data: any): UserData,
deserialize(userData: UserData): any,
}

View file

@ -0,0 +1,33 @@
import {UserScores} from "../model/UserScores.js";
import { Serializer } from "../serializer/Serializer.js";
import {UserScoresSerializer} from "../serializer/UserScoresSerializer.js";
import {Manager} from "./Manager.js";
export class UserScoresManager implements Manager<UserScores> {
private _content: UserScores;
private _serializer: UserScoresSerializer;
constructor(rawData: any, serializer: UserScoresSerializer) {
this.serializer = serializer;
this._content = this.serializer.serialize(rawData);
}
//region getter&setter
get content() {
return this._content;
}
set content(value: UserScores) {
this._content = value;
}
get serializer() {
return this._serializer
}
set serializer(value: Serializer<UserScores>) {
this._serializer = value
}
//endregion
}

View file

@ -1,5 +1,7 @@
import {LeaderboardEntry} from "./LeaderboardEntry.js";
export type Leaderboard<T> = LeaderboardEntry<T>[];
export class Leaderboard<T> {
content: LeaderboardEntry<T>[];
export interface LeaderboardEntry<T> {
rank: number,
username: string,
score: T,
}

View file

@ -1,5 +0,0 @@
export interface LeaderboardEntry<T> {
rank: number,
username: string,
score: T,
}

View file

@ -1,4 +1,4 @@
export interface UserData {
export interface UserScores {
username: string,
highscore: number,
totalScore: number,

View file

@ -0,0 +1,4 @@
import {Serializer} from "./Serializer.js";
import {Leaderboard} from "../model/Leaderboard.js";
export interface HighscoreLeaderboardSerializer extends Serializer<Leaderboard<number>> {}

View file

@ -0,0 +1,4 @@
export interface Serializer<T> {
serialize(rawData: any): T,
deserialize(parsedData: T): any,
}

View file

@ -0,0 +1,5 @@
import {Serializer} from "./Serializer.js";
import {Leaderboard} from "../model/Leaderboard.js";
import {Time} from "../model/Time.js";
export interface TimeLeaderboardSerializer extends Serializer<Leaderboard<Time>> {}

View file

@ -0,0 +1,4 @@
import {UserScores} from "../model/UserScores.js";
import {Serializer} from "./Serializer.js";
export interface UserScoresSerializer extends Serializer<UserScores>{}

View file

@ -0,0 +1,20 @@
import {HighscoreLeaderboardSerializer} from "../HighscoreLeaderboardSerializer.js";
import {Leaderboard, LeaderboardEntry} from "../../model/Leaderboard.js";
export class HighscoreLeaderboardPgPromiseSerializer implements HighscoreLeaderboardSerializer {
deserialize(parsedData: Leaderboard<number>): any {
throw new Error("Method not implemented.")
}
serialize(rawData: any): Leaderboard<number> {
return rawData.map((item) => {
let newItem: LeaderboardEntry<number> = {
rank: item.rank,
username: item.name,
score: item.highscore,
}
return newItem
});
}
}

View file

@ -0,0 +1,20 @@
import {TimeLeaderboardSerializer} from "../TimeLeaderboardSerializer.js";
import {Leaderboard, LeaderboardEntry} from "../../model/Leaderboard.js";
import {Time} from "../../model/Time.js";
export class TimeLeaderboardPgPromiseSerializer implements TimeLeaderboardSerializer {
deserialize(parsedData: Leaderboard<Time>): any {
throw new Error("Method not implemented.")
}
serialize(rawData: any): Leaderboard<Time> {
return rawData.map((item) => {
let newItem: LeaderboardEntry<Time> = {
rank: item.rank,
username: item.name,
score: item.total_playtime,
}
return newItem
});
}
}

View file

@ -0,0 +1,20 @@
import {UserScores} from "../../model/UserScores.js";
import {UserScoresSerializer} from "../UserScoresSerializer.js";
export class UserScoresPgPromiseSerializer implements UserScoresSerializer {
deserialize(parsedData: UserScores): any {
throw new Error("Method not implemented");
}
serialize(rawData: any): UserScores {
return {
username: rawData.name,
highscore: rawData.highscore,
totalScore: rawData.total_score,
totalPlaytime: rawData.total_playtime,
averageScore: rawData.averageScore,
gamesPlayed: rawData.games_played,
};
}
}

View file

@ -0,0 +1,30 @@
import express from "express";
import {Database} from "./Database.js";
import {UserScoresManager} from "./manager/UserScoresManager.js";
import {UserScoresPgPromiseSerializer} from "./serializer/pgpromise/UserScoresPgPromiseSerializer.js";
import bodyParser from "body-parser";
export const userRoute = express.Router()
userRoute.use(bodyParser.json)
userRoute.get('/:username/scores', async (req, res) => {
let data = await Database.db.oneOrNone(
'SELECT * FROM user_scores INNER JOIN "user" ON user_scores.user_id = "user".id WHERE "user".name = $1;',
[req.params.username])
.catch((error) => console.log(error.message)
)
let userDataManager: UserScoresManager = new UserScoresManager(data, new UserScoresPgPromiseSerializer);
res.json(userDataManager.content);
})
userRoute.post('/register', async (req, res) => {
if (req.body.name == undefined) {
res.status(400).send("'name' was not defined");
return;
}
await Database.db.none(
'INSERT INTO "user" (name) VALUES ($1);', [req.body.name]
);
res.status(200).send();
})