This repository has been archived on 2020-08-13. You can view files and clone it, but cannot push or open issues or pull requests.
requestor/lib/DatabaseCrudHandler.ts
2020-05-04 20:14:56 +02:00

161 lines
4.2 KiB
TypeScript

import { Request, Response, Router } from 'express';
import { http } from '@scode/consts';
import { ControlModel, DatabaseModel } from '@scode/modelling';
import { CrudHandler } from './CrudHandler';
import { HttpHandler } from './HttpHandler';
import { DatabaseCrudOptionsReader } from './DatabaseCrudOptionsReader';
import { DatabaseCrudOptions } from './DatabaseCrudOptions';
export class DatabaseCrudHandler extends HttpHandler implements CrudHandler {
protected cm:
new (object: Record<string, string|number|boolean>) => ControlModel;
protected dm: new (id?: number) => DatabaseModel;
protected options: DatabaseCrudOptionsReader;
public constructor (
cm: new (object: Record<string, string|number|boolean>) => ControlModel,
dm: new (id?: number) => DatabaseModel,
options: DatabaseCrudOptions = {}
) {
super ();
this.cm = cm;
this.dm = dm;
this.options = new DatabaseCrudOptionsReader (options);
}
protected validate_body (
req: Request,
res: Response
): Promise<Record<string, unknown> | null> | Record<string, unknown> | null {
if (typeof req.body === 'undefined') {
res.status (http.status_bad_request);
res.end ('body was undefined');
return null;
}
try {
return JSON.parse (req.body);
}
catch (e) {
res.status (http.status_bad_request);
res.end ('invalid json input');
}
return null;
}
public async create (req: Request, res: Response): Promise<void> {
if (!await this.options.create_authorization (req, res))
return;
const body_data = await this.validate_body (req, res);
if (body_data === null)
return;
const cm = new this.cm (body_data as Record<string|string, number|boolean>);
cm.update ();
const dm = new this.dm;
dm.assign (cm);
await dm.write ();
res.status (http.status_created)
.end (dm.id);
}
public async read (req: Request, res: Response): Promise<void> {
if (!await this.options.read_authorization (req, res))
return;
if (typeof req.headers.id === 'undefined') {
res.status (http.status_bad_request)
.end ('id undefined');
return;
}
const dm = new this.dm (parseInt (req.headers.id as string));
const found = await dm.read ();
const cm = new this.cm (dm.get_data ());
cm.update ();
res.status (found ? http.status_ok : http.status_not_found)
.json (cm.get_data ());
}
public async update (req: Request, res: Response): Promise<void> {
if (!await this.options.update_authorization (req, res))
return;
const body_data = await this.validate_body (req, res);
if (body_data === null)
return;
if (typeof req.headers.id === 'undefined') {
res.status (http.status_bad_request)
.end ('id undefined');
return;
}
const dm = new this.dm (parseInt (req.headers.id as string));
const found = await dm.read ();
if (!found) {
res.status (http.status_not_found)
.end ();
return;
}
const cm = new this.cm (dm.get_data ());
cm.update ();
cm.assign_object (body_data);
cm.update ();
dm.assign (cm);
const written = await dm.write ();
res.status (written ? http.status_ok : http.status_internal_server_error)
.end ();
}
public async delete (req: Request, res: Response): Promise<void> {
if (!await this.options.delete_authorization (req, res))
return;
if (typeof req.headers.id === 'undefined') {
res.status (http.status_bad_request)
.end ('id undefined');
return;
}
const dm = new this.dm (parseInt (req.headers.id as string));
const found = await dm.read ();
if (!found) {
res.status (http.status_not_found)
.end ();
return;
}
const deleted = await dm.delete ();
res.status (deleted ? http.status_ok : http.status_internal_server_error)
.end ();
}
protected async create_or_update (
req: Request,
res: Response
): Promise<void> {
if (typeof req.headers.id === 'undefined')
await this.create (req, res);
else
await this.update (req, res);
}
public register_handlers (router: Router): void {
router.post ('/', this.create_or_update);
router.get ('/', this.read);
router.delete ('/', this.delete);
}
}