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

161 lines
4.2 KiB
TypeScript
Raw Normal View History

2020-04-17 11:03:15 +02:00
import { Request, Response, Router } from 'express';
2020-04-17 08:31:14 +02:00
import { http } from '@scode/consts';
2020-05-02 21:29:25 +02:00
import { ControlModel, DatabaseModel } from '@scode/modelling';
2020-04-16 09:44:43 +02:00
import { CrudHandler } from './CrudHandler';
2020-04-17 11:03:15 +02:00
import { HttpHandler } from './HttpHandler';
2020-04-23 18:58:06 +02:00
import { DatabaseCrudOptionsReader } from './DatabaseCrudOptionsReader';
2020-05-02 21:48:22 +02:00
import { DatabaseCrudOptions } from './DatabaseCrudOptions';
2020-04-16 09:44:43 +02:00
2020-04-23 18:58:06 +02:00
export class DatabaseCrudHandler extends HttpHandler implements CrudHandler {
2020-05-02 21:48:22 +02:00
protected cm:
new (object: Record<string, string|number|boolean>) => ControlModel;
protected dm: new (id?: number) => DatabaseModel;
2020-04-23 18:58:06 +02:00
protected options: DatabaseCrudOptionsReader;
2020-04-16 09:44:43 +02:00
2020-05-02 21:48:22 +02:00
public constructor (
cm: new (object: Record<string, string|number|boolean>) => ControlModel,
dm: new (id?: number) => DatabaseModel,
options: DatabaseCrudOptions = {}
2020-04-16 09:44:43 +02:00
) {
2020-04-17 11:03:15 +02:00
super ();
2020-05-02 21:29:25 +02:00
this.cm = cm;
this.dm = dm;
2020-04-23 18:58:06 +02:00
this.options = new DatabaseCrudOptionsReader (options);
2020-04-17 08:31:14 +02:00
}
protected validate_body (
req: Request,
res: Response
2020-05-02 21:48:22 +02:00
): Promise<Record<string, unknown> | null> | Record<string, unknown> | null {
2020-04-17 08:31:14 +02:00
if (typeof req.body === 'undefined') {
res.status (http.status_bad_request);
2020-04-17 11:03:15 +02:00
res.end ('body was undefined');
2020-04-17 08:31:14 +02:00
return null;
}
2020-04-17 11:03:15 +02:00
try {
return JSON.parse (req.body);
}
catch (e) {
res.status (http.status_bad_request);
res.end ('invalid json input');
}
return null;
}
2020-04-16 11:09:04 +02:00
public async create (req: Request, res: Response): Promise<void> {
2020-04-17 11:03:15 +02:00
if (!await this.options.create_authorization (req, res))
2020-04-17 08:31:14 +02:00
return;
const body_data = await this.validate_body (req, res);
if (body_data === null)
return;
2020-04-17 11:03:15 +02:00
2020-05-02 21:48:22 +02:00
const cm = new this.cm (body_data as Record<string|string, number|boolean>);
2020-05-02 21:29:25 +02:00
cm.update ();
2020-04-17 11:03:15 +02:00
2020-05-02 21:29:25 +02:00
const dm = new this.dm;
2020-05-04 20:14:56 +02:00
dm.assign (cm);
2020-05-02 21:29:25 +02:00
await dm.write ();
2020-04-17 11:03:15 +02:00
res.status (http.status_created)
2020-05-02 21:29:25 +02:00
.end (dm.id);
2020-04-16 11:09:04 +02:00
}
public async read (req: Request, res: Response): Promise<void> {
2020-04-17 11:03:15 +02:00
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;
}
2020-04-16 11:09:04 +02:00
2020-05-02 21:48:22 +02:00
const dm = new this.dm (parseInt (req.headers.id as string));
2020-05-02 21:29:25 +02:00
const found = await dm.read ();
2020-05-03 16:10:13 +02:00
const cm = new this.cm (dm.get_data ());
2020-05-02 21:29:25 +02:00
cm.update ();
res.status (found ? http.status_ok : http.status_not_found)
2020-05-03 17:05:04 +02:00
.json (cm.get_data ());
2020-04-16 11:09:04 +02:00
}
public async update (req: Request, res: Response): Promise<void> {
2020-04-17 11:03:15 +02:00
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;
}
2020-05-02 21:48:22 +02:00
const dm = new this.dm (parseInt (req.headers.id as string));
2020-05-02 21:29:25 +02:00
const found = await dm.read ();
if (!found) {
res.status (http.status_not_found)
.end ();
return;
}
2020-05-03 16:10:13 +02:00
const cm = new this.cm (dm.get_data ());
2020-05-02 21:29:25 +02:00
cm.update ();
2020-04-16 11:09:04 +02:00
2020-05-04 20:14:56 +02:00
cm.assign_object (body_data);
2020-05-02 21:29:25 +02:00
cm.update ();
2020-05-04 20:14:56 +02:00
dm.assign (cm);
2020-05-02 21:48:22 +02:00
2020-05-02 21:29:25 +02:00
const written = await dm.write ();
res.status (written ? http.status_ok : http.status_internal_server_error)
2020-04-17 11:27:56 +02:00
.end ();
2020-04-16 11:09:04 +02:00
}
public async delete (req: Request, res: Response): Promise<void> {
2020-04-17 11:03:15 +02:00
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;
}
2020-05-02 21:48:22 +02:00
const dm = new this.dm (parseInt (req.headers.id as string));
2020-05-02 21:29:25 +02:00
const found = await dm.read ();
if (!found) {
res.status (http.status_not_found)
.end ();
return;
}
const deleted = await dm.delete ();
2020-04-17 11:03:15 +02:00
2020-05-02 21:29:25 +02:00
res.status (deleted ? http.status_ok : http.status_internal_server_error)
2020-04-17 11:03:15 +02:00
.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);
}
2020-04-16 11:09:04 +02:00
2020-04-17 11:03:15 +02:00
public register_handlers (router: Router): void {
router.post ('/', this.create_or_update);
router.get ('/', this.read);
router.delete ('/', this.delete);
2020-04-16 11:09:04 +02:00
}
2020-04-16 09:44:43 +02:00
}