From 1179684a74251b530853b5899bed7e532df2a5ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor=20Tozatti=20Risso?= <jvtr12@inf.ufpr.br> Date: Mon, 31 Oct 2016 12:42:30 -0200 Subject: [PATCH] Refactor location module to include response formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move concurrent query execution into dbExecAll function * Add custom response formatting through route labels. For each query in the set, there is an associated label, which will then be used to identify the corresponding result in the response JSON object. For example: - labels = [ "a", "b" ] - querySet = [ squel.select().from('y'), squel.select().from('x') ] - response = { "result" : { "a" : { // result for query a }, "b" : { //result for query b } } Signed-off-by: João Victor Tozatti Risso <jvtr12@inf.ufpr.br> --- src/libs/routes/location.js | 191 +++++++++++++++++------------------- 1 file changed, 92 insertions(+), 99 deletions(-) diff --git a/src/libs/routes/location.js b/src/libs/routes/location.js index a7d86f5b..7a870e5f 100644 --- a/src/libs/routes/location.js +++ b/src/libs/routes/location.js @@ -34,6 +34,38 @@ function locationIdToStr(locationId) { return locationStr; } +function processResultSet(querySet, querySetLabels = ["result"]) { + const resultMap = new Map(); + if (querySetLabels.length === 1 && querySetLabels[0] === "result") { + resultMap["result"] = []; + // loop relies on the fact that Promise.all maintains the order of the original iterable + for(let result of querySet) { + // each query only returns one object in an array, so we get rid of the array + const resultObj = result[0]; + resultMap["result"].push(resultObj); + resultIdx++; + } + } else { + let resultIdx = 0; + // loop relies on the fact that Promise.all maintains the order of the original iterable + for(let result of querySet) { + const resultLbl = querySetLabels[resultIdx]; + // each query only returns one object in an array, so we get rid of the array + const resultObj = result[0]; + resultMap[resultLbl] = resultObj; + resultIdx++; + } + } + log.debug(resultMap); + return resultMap; +} + +function dbExecAll(querySet = []) { + // Issue all queries concurrently to the database, for every query object in the iterable + // NOTE: Array.map() returns a copy of the original array with each object 'mapped'. + return querySet.map((qry) => { return sqlQuery(qry.toString()); }); +} + locationApp.get('/sociodemographic', (req, res, next) => { const populationYearQry = squel.select() .field('MAX(ibge_populacao.ano_censo)') @@ -95,17 +127,12 @@ locationApp.get('/sociodemographic', (req, res, next) => { .where(`adh_gini.ano_censo IN (${giniYearQry.toString()})`) .group('adh_gini.ano_censo'); - const queries = [populationQry, pibQry, idhQry, analfabQry, giniQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - req.result.push(result[0]); - } + // map query objects to their respective response labels + const queryLabels = [ "population", "pib", "idh", "analfab", "gini" ]; + const querySet = [ populationQry, pibQry, idhQry, analfabQry, giniQry ]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); next(); }).catch((error) => { log.error(`[SQL query error] ${error}`); @@ -220,18 +247,12 @@ locationApp.get('/sociodemographic/region/:id', (req, res, next) => { .group('regiao.nome') .group('adh_gini.ano_censo') .order('regiao.nome'); - - const queries = [populationQry, pibQry, idhQry, analfabQry, giniQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - req.result.push(result[0]); - } + // map query objects to their respective response labels + const queryLabels = [ "population", "pib", "idh", "analfab", "gini" ]; + const querySet = [ populationQry, pibQry, idhQry, analfabQry, giniQry ]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); next(); }).catch((error) => { log.error(`[SQL query error] ${error}`); @@ -336,18 +357,12 @@ locationApp.get('/sociodemographic/state/:id', (req, res, next) => { .group('estado.nome') .group('adh_gini.ano_censo') .order('estado.nome'); - - const queries = [populationQry, pibQry, idhQry, analfabQry, giniQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - req.result.push(result[0]); - } + // map query objects to their respective response labels + const queryLabels = [ "population", "pib", "idh", "analfab", "gini" ]; + const querySet = [ populationQry, pibQry, idhQry, analfabQry, giniQry ]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); next(); }).catch((error) => { log.error(`[SQL query error] ${error}`); @@ -442,18 +457,12 @@ locationApp.get('/sociodemographic/city/:id', (req, res, next) => { .group('municipio.nome') .group('adh_gini.ano_censo') .order('municipio.nome'); - - const queries = [populationQry, pibQry, idhQry, analfabQry, giniQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - req.result.push(result[0]); - } + // map query objects to their respective response labels + const queryLabels = [ "population", "pib", "idh", "analfab", "gini" ]; + const querySet = [ populationQry, pibQry, idhQry, analfabQry, giniQry ]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); next(); }).catch((error) => { log.error(`[SQL query error] ${error}`); @@ -535,19 +544,15 @@ locationApp.get('/educational', (req, res, next) => { .order('dependencia_adm.nome') .order('etapa_ensino.desc_etapa'); - const queries = [totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - for(let row of result) { - row.location = locationIdToStr(row.location); - req.result.push(row); - } + const queryLabels = [ "school", "school_per_location", "enrollment", "enrollment_per_adm_dep", + "enrollment_per_school_level" ]; + const querySet = [ totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, + enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); + for(let label in req.result) { + req.result[label].location = locationIdToStr(req.result[label].location); } next(); }).catch((error) => { @@ -657,19 +662,15 @@ locationApp.get('/educational/region/:id', (req, res, next) => { .order('dependencia_adm.nome') .order('etapa_ensino.desc_etapa'); - const queries = [totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - for(let row of result) { - row.location = locationIdToStr(row.location); - req.result.push(row); - } + const queryLabels = [ "school", "school_per_location", "enrollment", "enrollment_per_adm_dep", + "enrollment_per_school_level" ]; + const querySet = [ totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, + enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); + for(let label in req.result) { + req.result[label].location = locationIdToStr(req.result[label].location); } next(); }).catch((error) => { @@ -775,19 +776,15 @@ locationApp.get('/educational/state/:id', (req, res, next) => { .order('dependencia_adm.nome') .order('etapa_ensino.desc_etapa'); - const queries = [totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - for(let row of result) { - row.location = locationIdToStr(row.location); - req.result.push(row); - } + const queryLabels = [ "school", "school_per_location", "enrollment", "enrollment_per_adm_dep", + "enrollment_per_school_level" ]; + const querySet = [ totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, + enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); + for(let label in req.result) { + req.result[label].location = locationIdToStr(req.result[label].location); } next(); }).catch((error) => { @@ -893,19 +890,15 @@ locationApp.get('/educational/city/:id', (req, res, next) => { .order('dependencia_adm.nome') .order('etapa_ensino.desc_etapa'); - const queries = [totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry].map((qry) => { - return sqlQuery(qry.toString()); - }); - - // execute all queries concurrently - Promise.all(queries).then((queryResults) => { - req.result = []; - for(let result of queryResults) { - log.debug(result); - for(let row of result) { - row.location = locationIdToStr(row.location); - req.result.push(row); - } + const queryLabels = [ "school", "school_per_location", "enrollment", "enrollment_per_adm_dep", + "enrollment_per_school_level" ]; + const querySet = [ totalSchoolsQry, schoolsPerLocationQry, enrollmentsQry, + enrollmentsPerAdmDepQry, enrollmentsPerSchoolLevelQry]; + // wait until all queries finish or one of them fail + Promise.all(dbExecAll(querySet)).then((queryResults) => { + req.result = processResultSet(queryResults, queryLabels); + for(let label in req.result) { + req.result[label].location = locationIdToStr(req.result[label].location); } next(); }).catch((error) => { -- GitLab