From c93188a5a7b95d6e4b0203abf0a8de79ff15acee Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Sun, 16 Aug 2020 10:50:58 +0200 Subject: [PATCH] Add event POST middleware to API --- lib/www/server/api/index.js | 2 +- lib/www/server/api/middleware/event/post.js | 15 +++ lib/www/server/lib/db/event/post.js | 122 ++++++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/lib/www/server/api/index.js b/lib/www/server/api/index.js index e192b2c..530ebbf 100644 --- a/lib/www/server/api/index.js +++ b/lib/www/server/api/index.js @@ -84,7 +84,7 @@ app.map({ // '/project/:project/event/': { get: [ mw.event.list ], -// post: [ mw.event.post ], + post: [ mw.event.post ], }, // '/project/:project/event/:event': { // get: [ mw.event.get ], diff --git a/lib/www/server/api/middleware/event/post.js b/lib/www/server/api/middleware/event/post.js index e69de29..c841a49 100644 --- a/lib/www/server/api/middleware/event/post.js +++ b/lib/www/server/api/middleware/event/post.js @@ -0,0 +1,15 @@ + +const { event } = require('../../../lib/db'); + +module.exports = async function (req, res, next) { + + try { + await event.post(req.params.project, req.body, req.query); + res.status(201).send(); + next(); + } catch (err) { + console.error(err); + next(err); + } + +}; diff --git a/lib/www/server/lib/db/event/post.js b/lib/www/server/lib/db/event/post.js index e69de29..60d5dc5 100644 --- a/lib/www/server/lib/db/event/post.js +++ b/lib/www/server/lib/db/event/post.js @@ -0,0 +1,122 @@ +const { setSurvey, transaction } = require('../connection'); + +async function insertSeqRemarks(remarks, shotNumber, sequence, client) { + const text = ` + INSERT INTO events_seq (remarks, shot_number, sequence) + VALUES ($1, $2, $3) + RETURNING id; + `; + + console.log("insertSeqRemarks", text, remarks, shotNumber, sequence); + return (await client.query(text, [remarks, shotNumber, sequence]))[0].id; +} + +async function insertSeqLabel(label, eventId, client) { + const text = ` + INSERT INTO events_seq_labels (label, id) + VALUES ($1, $2); + `; + + console.log("insertSeqLabel", text, label, eventId); + return await client.query(text, [label, eventId]); +} + +async function insertShotLabel(label, shotNumber, sequence, client) { + const text = ` + INSERT INTO events_seq_shots_labels (label, shot_number, sequence) + VALUES ($1, $2, $3); + `; + + console.log("insertShotLabel", text, label, shotNumber, sequence); + return await client.query(text, [label, shotNumber, sequence]); +} + +async function insertTimedEventLabel(label, eventId, client) { + const text = ` + INSERT INTO events_timed_labels (label, id) + VALUES ($1, $2); + `; + + console.log("insertTimedEventLabel", text, label, eventId); + return await client.query(text, [label, eventId]); +} + +/** + * Inserts events into the database. + * + * Events may have the following forms: + * + * Event associated with a time: + * + * { + * remarks: "…", + * ts0: "…", + * ts1: "…", + * labels: [ "…", "…", … ] + * } + * + * Events associated with a shotpoint: + * + * { + * remarks: "…", + * shotNumber: 0000, + * sequence: 000, + * labels: [ "…", "…", … ] + * } + * + * In both cases, either remarks or labels may be omitted. + */ +async function post (projectId, payload, opts = {}) { + console.log("post event", projectId, payload); + + const client = await setSurvey(projectId); + await transaction.begin(client); + try { + if (!Array.isArray(payload)) { + payload = [payload]; + } + + for (const event of payload) { + console.log("Event", event); + if (event.sequence && event.shotNumber) { + // A shot event + console.log("Shot event"); + if (event.remarks) { + const eventId = await insertSeqRemarks(event.remarks, event.shotNumber, event.sequence, client); + console.log("eventId", eventId); + if (event.labels) { + for (const label of event.labels) { + await insertSeqLabel(label, eventId, client); + } + } + } else if (event.labels) { + // A label event + for (const label of event.labels) { + await insertShotLabel(label, event.shotNumber, event.sequence, client); + } + } + } else if (event.ts0) { + // A timed event + + // Called even if remarks is blank, as timed labels are always associated + // with an event id from events_timed. + const eventId = await insertTimedEvent(event.remarks, event.ts0, event.ts1, client); + + if (event.labels) { + for (const label of event.labels) { + await insertTimedEventLabel(label, eventId, client); + } + } + + } + } + + transaction.commit(client); + } catch (err) { + transaction.rollback(client) + } finally { + client.release(); + } +} + +module.exports = post;