From 80e8ccef9cd6826706c09f0bb94b0d430ace87f9 Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Sun, 20 Sep 2020 18:11:33 +0200 Subject: [PATCH] Add endpoints for setting and retrieving metadata --- lib/www/server/api/index.js | 13 ++++ lib/www/server/api/middleware/index.js | 3 +- lib/www/server/api/middleware/meta/delete.js | 0 lib/www/server/api/middleware/meta/get.js | 18 +++++ lib/www/server/api/middleware/meta/index.js | 8 ++ lib/www/server/api/middleware/meta/list.js | 0 lib/www/server/api/middleware/meta/post.js | 0 lib/www/server/api/middleware/meta/put.js | 16 ++++ lib/www/server/lib/db/index.js | 1 + lib/www/server/lib/db/meta/delete.js | 0 lib/www/server/lib/db/meta/get.js | 43 +++++++++++ lib/www/server/lib/db/meta/index.js | 7 ++ lib/www/server/lib/db/meta/post.js | 0 lib/www/server/lib/db/meta/put.js | 77 ++++++++++++++++++++ 14 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 lib/www/server/api/middleware/meta/delete.js create mode 100644 lib/www/server/api/middleware/meta/get.js create mode 100644 lib/www/server/api/middleware/meta/index.js create mode 100644 lib/www/server/api/middleware/meta/list.js create mode 100644 lib/www/server/api/middleware/meta/post.js create mode 100644 lib/www/server/api/middleware/meta/put.js create mode 100644 lib/www/server/lib/db/meta/delete.js create mode 100644 lib/www/server/lib/db/meta/get.js create mode 100644 lib/www/server/lib/db/meta/index.js create mode 100644 lib/www/server/lib/db/meta/post.js create mode 100644 lib/www/server/lib/db/meta/put.js diff --git a/lib/www/server/api/index.js b/lib/www/server/api/index.js index eaac96a..672fc07 100644 --- a/lib/www/server/api/index.js +++ b/lib/www/server/api/index.js @@ -129,6 +129,19 @@ app.map({ get: [ mw.info.get ], // post: [ mw.info.post ], }, + '/project/:project/meta/': { + put: [ mw.meta.put ], + }, + '/project/:project/meta/:path(*)': { + // Path examples: + // GET: + // `/raw/sequences/qc/missing_shots`, + // `/final/points/qc/sync_warn/results + get: [ mw.meta.get ], +// // PUT: +// // `/raw/qc/missing_shots` ← { sequence: …, value: … } +// put: [ mw.meta.put ] + }, // // '/project/:id/permissions/:mode(read|write)?': { // get: [ mw.permissions.get ], diff --git a/lib/www/server/api/middleware/index.js b/lib/www/server/api/middleware/index.js index 70a65f4..fef5468 100644 --- a/lib/www/server/api/middleware/index.js +++ b/lib/www/server/api/middleware/index.js @@ -9,5 +9,6 @@ module.exports = { label: require('./label'), navdata: require('./navdata'), configuration: require('./configuration'), - info: require('./info') + info: require('./info'), + meta: require('./meta') }; diff --git a/lib/www/server/api/middleware/meta/delete.js b/lib/www/server/api/middleware/meta/delete.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/www/server/api/middleware/meta/get.js b/lib/www/server/api/middleware/meta/get.js new file mode 100644 index 0000000..edc1212 --- /dev/null +++ b/lib/www/server/api/middleware/meta/get.js @@ -0,0 +1,18 @@ + +const { meta } = require('../../../lib/db'); + +module.exports = async function (req, res, next) { + + try { + res.status(200).json(await meta.get(req.params.project, req.params.path, req.query)); + } catch (err) { + if (err instanceof TypeError) { + res.status(404).json(null); + } else { + next(err); + return; + } + } + next(); + +}; diff --git a/lib/www/server/api/middleware/meta/index.js b/lib/www/server/api/middleware/meta/index.js new file mode 100644 index 0000000..1b5fb45 --- /dev/null +++ b/lib/www/server/api/middleware/meta/index.js @@ -0,0 +1,8 @@ + +module.exports = { + list: require('./list'), + get: require('./get'), + post: require('./post'), + put: require('./put'), + delete: require('./delete') +} diff --git a/lib/www/server/api/middleware/meta/list.js b/lib/www/server/api/middleware/meta/list.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/www/server/api/middleware/meta/post.js b/lib/www/server/api/middleware/meta/post.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/www/server/api/middleware/meta/put.js b/lib/www/server/api/middleware/meta/put.js new file mode 100644 index 0000000..167b4a0 --- /dev/null +++ b/lib/www/server/api/middleware/meta/put.js @@ -0,0 +1,16 @@ + +const { meta } = require('../../../lib/db'); + +module.exports = async function (req, res, next) { + + try { + const payload = req.body; + + await meta.put(req.params.project, payload); + res.status(201).send(); + next(); + } catch (err) { + next(err); + } + +}; diff --git a/lib/www/server/lib/db/index.js b/lib/www/server/lib/db/index.js index 543c295..8167b10 100644 --- a/lib/www/server/lib/db/index.js +++ b/lib/www/server/lib/db/index.js @@ -8,5 +8,6 @@ module.exports = { label: require('./label'), configuration: require('./configuration'), info: require('./info'), + meta: require('./meta'), navdata: require('./navdata') }; diff --git a/lib/www/server/lib/db/meta/delete.js b/lib/www/server/lib/db/meta/delete.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/www/server/lib/db/meta/get.js b/lib/www/server/lib/db/meta/get.js new file mode 100644 index 0000000..fe2b552 --- /dev/null +++ b/lib/www/server/lib/db/meta/get.js @@ -0,0 +1,43 @@ +const { setSurvey } = require('../connection'); + +async function get (projectId, path, opts = {}) { + const client = await setSurvey(projectId); + const [type, kind, ...jsonpath] = path.split("/"); + + const tables = { + sequences: { + raw: ["raw_lines", ["sequence"]], + final: ["final_lines", ["sequence"]], + }, + points: { + raw: ["raw_shots", ["sequence", "point"]], + final: ["final_shots", ["sequence", "point"]], + }, + lines: { + preplot: ["preplot_points", ["line", "point"]], + } + }; + + try { + const table = tables[kind][type][0]; + const fields = tables[kind][type][1]; + + const text = ` + SELECT ${fields.join(", ")}, meta #> $1 AS data + FROM ${table} + WHERE meta #> $1 IS NOT NULL + ORDER BY ${fields.join(", ")}; + `; + + console.log(text, jsonpath); + const res = await client.query(text, [jsonpath]); + + return res.rows; + } catch (err) { + throw err; + } finally { + client.release(); + } +} + +module.exports = get; diff --git a/lib/www/server/lib/db/meta/index.js b/lib/www/server/lib/db/meta/index.js new file mode 100644 index 0000000..ab357e0 --- /dev/null +++ b/lib/www/server/lib/db/meta/index.js @@ -0,0 +1,7 @@ + +module.exports = { + get: require('./get'), + post: require('./post'), + put: require('./put'), + delete: require('./delete') +} diff --git a/lib/www/server/lib/db/meta/post.js b/lib/www/server/lib/db/meta/post.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/www/server/lib/db/meta/put.js b/lib/www/server/lib/db/meta/put.js new file mode 100644 index 0000000..f50c2d8 --- /dev/null +++ b/lib/www/server/lib/db/meta/put.js @@ -0,0 +1,77 @@ +const { setSurvey, transaction } = require('../connection'); + +async function put (projectId, payload, opts = {}) { + const client = await setSurvey(projectId); +// const [type, ...jsonpath] = (path||"").split("/"); + + const tables = { + sequences: { + raw: ["raw_lines", ["sequence"]], + final: ["final_lines", ["sequence"]], + }, + points: { + raw: ["raw_shots", ["sequence", "point"]], + final: ["final_shots", ["sequence", "point"]], + }, + lines: { + preplot: ["preplot_points", ["line", "point"]], + } + }; + + try { + + if (!Array.isArray(payload)) { + payload = [payload]; + } + + transaction.begin(client); + for (const rec of payload) { + console.log("RECORD", rec); + const type = rec.type || "raw"; + if (rec.point && rec.sequence) { + const table = tables.points[type][0] + const text = ` + UPDATE ${table} + SET meta = jsonb_set(meta, $1, $2) + WHERE sequence = $3 AND point = $4; + ` + const values = [ rec.path, JSON.stringify(rec.value), rec.sequence, rec.point ]; + + await client.query(text, values); + } else if (rec.sequence) { + const table = tables.sequences[type][0] + const text = ` + UPDATE ${table} + SET meta = jsonb_set(meta, $1, $2) + WHERE sequence = $3; + ` + const values = [ rec.path, JSON.stringify(rec.value), rec.sequence ]; + + await client.query(text, values); + } else if (rec.point && rec.line) { + const table = tables.points[type][0] + const text = ` + UPDATE ${table} + SET meta = jsonb_set(meta, $1, $2) + WHERE line = $3 AND point = $4; + ` + const values = [ rec.path, JSON.stringify(rec.value), rec.line, rec.point ]; + + await client.query(text, values); + } else { + // Ignore, but report + console.error("I do not know where to store this meta", record); + } + } + transaction.commit(client); + + } catch (err) { + console.error("ERROR", err); + transaction.rollback(client); + throw err; + } finally { + client.release(); + } +} + +module.exports = put;