Refactor layer API endpoint and database functions.

- A single get() function is used both to list all available
  layers, if no layer name is given, or a single layer.
- The database no longer holds the actual layer contents,
  only the path to the layer file(s), so the list() function
  is now redundant as we return the full payload in every case.
- The /gis/layer and /gis/layer/:name endpoints now have the same
  payload structure.
This commit is contained in:
D. Berge
2023-09-12 11:10:00 +02:00
parent f9a70e0145
commit 707889be42
7 changed files with 16 additions and 50 deletions

View File

@@ -124,7 +124,7 @@ app.map({
get: [ mw.gis.project.final ] get: [ mw.gis.project.final ]
}, },
'/project/:project/gis/layer': { '/project/:project/gis/layer': {
get: [ mw.etag.noSave, mw.gis.project.layer.list ] get: [ mw.etag.noSave, mw.gis.project.layer.get ]
}, },
'/project/:project/gis/layer/:name': { '/project/:project/gis/layer/:name': {
get: [ mw.etag.noSave, mw.gis.project.layer.get ] get: [ mw.etag.noSave, mw.gis.project.layer.get ]

View File

@@ -4,8 +4,12 @@ const { gis } = require('../../../../../lib/db');
module.exports = async function (req, res, next) { module.exports = async function (req, res, next) {
try { try {
res.set("Cache-Control", "public, max-age=21600"); const layers = await gis.project.layer.get(req.params.project, req.params.name);
res.status(200).send(await gis.project.layer.get(req.params.project, req.params.name)); if (req.params.name && (!layers || !layers.length)) {
res.status(404).json({message: "Not found"});
} else {
res.status(200).send(layers ?? []);
}
next(); next();
} catch (err) { } catch (err) {
next(err); next(err);

View File

@@ -1,4 +1,3 @@
module.exports = { module.exports = {
list: require('./list'),
get: require('./get') get: require('./get')
}; };

View File

@@ -1,14 +0,0 @@
const { gis } = require('../../../../../lib/db');
module.exports = async function (req, res, next) {
try {
res.set("Cache-Control", "public, max-age=180");
res.status(200).send(await gis.project.layer.list(req.params.project));
next();
} catch (err) {
next(err);
}
};

View File

@@ -1,16 +1,19 @@
const { setSurvey } = require('../../../connection'); const { setSurvey } = require('../../../connection');
async function get (projectId, layerName, options = {}) { async function get (projectId, layerName = null, options = {}) {
const client = await setSurvey(projectId); const client = await setSurvey(projectId);
const text = ` const text = `
SELECT (data->>'data')::json data SELECT path, (data - 'type') data
FROM file_data FROM files f
INNER JOIN file_data
USING (hash)
WHERE data->>'type' = 'map_layer' WHERE data->>'type' = 'map_layer'
AND data->>'format' = 'geojson' AND data->>'format' = 'geojson'
AND data->>'name' = $1; AND (data->>'name' = $1
OR $1 IS NULL);
`; `;
const values = [ layerName ]; const values = [ layerName ];
@@ -19,9 +22,9 @@ async function get (projectId, layerName, options = {}) {
client.release(); client.release();
if (res.rows && res.rows.length) { if (res.rows && res.rows.length) {
return res.rows.map(row => row.data); return res.rows.map(row => ({...row.data, path: row.path}));
} else { } else {
throw {status: 404}; throw {status: 404, message: "Not found"};
} }
} }

View File

@@ -1,5 +1,4 @@
module.exports = { module.exports = {
list: require('./list'),
get: require('./get') get: require('./get')
}; };

View File

@@ -1,25 +0,0 @@
const { setSurvey } = require('../../../connection');
async function list (projectId, options = {}) {
const client = await setSurvey(projectId);
const text = `
SELECT DISTINCT data->>'name' name
FROM file_data
WHERE data->>'type' = 'map_layer'
AND data->>'format' = 'geojson';
`;
const res = await client.query(text);
client.release();
if (res.rows && res.rows.length) {
return res.rows.map(row => row.name);
} else {
throw {status: 404};
}
}
module.exports = list;