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 ]
},
'/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': {
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) {
try {
res.set("Cache-Control", "public, max-age=21600");
res.status(200).send(await gis.project.layer.get(req.params.project, req.params.name));
const layers = 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();
} catch (err) {
next(err);

View File

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

View File

@@ -1,5 +1,4 @@
module.exports = {
list: require('./list'),
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;