diff --git a/src/libs/routes/location.js b/src/libs/routes/location.js new file mode 100644 index 0000000000000000000000000000000000000000..a42892721a38812a51983d6d12850f55beac50f8 --- /dev/null +++ b/src/libs/routes/location.js @@ -0,0 +1,657 @@ +const express = require('express'); + +const libs = `${process.cwd()}/libs`; + +const squel = require('squel'); + +const log = require(`${libs}/log`)(module); + +const query = require(`${libs}/middlewares/query`); + +const sqlQuery = require(`${libs}/db/query_exec`); + +const response = require(`${libs}/middlewares/response`); + +const locationApp = express(); + +function locationIdToStr(locationId) { + let locationStr = 'Todas'; + switch(locationId) { + case 1: + locationStr = 'Urbana'; + break; + case 2: + locationStr = 'Rural'; + break; + } + return locationStr; +} + +locationApp.get('/sociodemographic', (req, res, next) => { + const populationYearQry = squel.select() + .field('MAX(ibge_populacao.ano_censo)') + .from('ibge_populacao'); + + const populationQry = squel.select() + .field('\'Brasil\'', 'location') + .field('SUM(populacao)', 'population') + .field('ibge_populacao.ano_censo') + .from('ibge_populacao') + .where(`ibge_populacao.ano_censo IN (${populationYearQry.toString()})`) + .group('ibge_populacao.ano_censo'); + + const pibYearQry = squel.select() + .field('MAX(ibge_pib.ano_censo)') + .from('ibge_pib'); + + const pibQry = squel.select() + .field('\'Brasil\'', 'location') + .field('AVG(ibge_pib.pib_per_capita)', 'gdp_per_capita') + .field('ibge_pib.ano_censo') + .from('ibge_pib') + .where(`ibge_pib.ano_censo IN (${pibYearQry.toString()})`) + .group('ibge_pib.ano_censo'); + + const idhYearQry = squel.select() + .field('MAX(adh_idh.ano_censo)') + .from('adh_idh'); + + const idhQry = squel.select() + .field('\'Brasil\'', 'location') + .field('AVG(idhm)', 'idhm') + .field('adh_idh.ano_censo') + .from('adh_idh') + .where(`adh_idh.ano_censo IN (${idhYearQry.toString()})`) + .group('adh_idh.ano_censo'); + + const analfabYearQry = squel.select() + .field('MAX(adh_analfabetismo.ano_censo)') + .from('adh_analfabetismo'); + + const analfabQry = squel.select() + .field('\'Brasil\'', 'location') + .field('AVG(t_analf15m)', 'analfabetism') + .field('adh_analfabetismo.ano_censo') + .from('adh_analfabetismo') + .where(`adh_analfabetismo.ano_censo IN (${analfabYearQry.toString()})`) + .group('adh_analfabetismo.ano_censo'); + + const giniYearQry = squel.select() + .field('MAX(adh_gini.ano_censo)') + .from('adh_gini'); + + const giniQry = squel.select() + .field('\'Brasil\'', 'location') + .field('AVG(gini)', 'gini') + .field('adh_gini.ano_censo') + .from('adh_gini') + .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]); + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/sociodemographic/region/:id', (req, res, next) => { + const regionId = parseInt(req.params.id, 10); + + const populationYearQry = squel.select() + .field('MAX(ibge_populacao.ano_censo)') + .from('ibge_populacao'); + + const populationQry = squel.select() + .field('regiao.nome', 'location') + .field('SUM(populacao)', 'population') + .field('ano_censo', 'census_year') + .from('ibge_populacao') + .from('municipio') + .from('estado') + .from('regiao') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`ibge_populacao.ano_censo IN (${populationYearQry.toString()})`) + .where('ibge_populacao.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .group('regiao.nome') + .group('ibge_populacao.ano_censo') + .order('regiao.nome'); + + const pibYearQry = squel.select() + .field('MAX(ibge_pib.ano_censo)') + .from('ibge_pib'); + + const pibQry = squel.select() + .field('regiao.nome', 'location') + .field('AVG(ibge_pib.pib_per_capita)', 'gdp_per_capita') + .field('ano_censo', 'census_year') + .from('ibge_pib') + .from('municipio') + .from('estado') + .from('regiao') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`ibge_pib.ano_censo IN (${pibYearQry.toString()})`) + .where('ibge_pib.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .group('regiao.nome') + .group('ibge_pib.ano_censo') + .order('regiao.nome'); + + const idhYearQry = squel.select() + .field('MAX(adh_idh.ano_censo)') + .from('adh_idh'); + + const idhQry = squel.select() + .field('regiao.nome', 'location') + .field('AVG(idhm)', 'idhm') + .field('ano_censo', 'census_year') + .from('adh_idh') + .from('municipio') + .from('estado') + .from('regiao') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`adh_idh.ano_censo IN (${idhYearQry.toString()})`) + .where('adh_idh.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .group('regiao.nome') + .group('adh_idh.ano_censo') + .order('regiao.nome'); + + const analfabYearQry = squel.select() + .field('MAX(adh_analfabetismo.ano_censo)') + .from('adh_analfabetismo'); + + const analfabQry = squel.select() + .field('regiao.nome', 'location') + .field('AVG(t_analf15m)', 'analfabetism') + .field('ano_censo', 'census_year') + .from('adh_analfabetismo') + .from('municipio') + .from('estado') + .from('regiao') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`adh_analfabetismo.ano_censo IN (${analfabYearQry.toString()})`) + .where('adh_analfabetismo.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .group('regiao.nome') + .group('adh_analfabetismo.ano_censo') + .order('regiao.nome'); + + const giniYearQry = squel.select() + .field('MAX(adh_gini.ano_censo)') + .from('adh_gini'); + + const giniQry = squel.select() + .field('regiao.nome', 'location') + .field('AVG(gini)', 'gini') + .field('ano_censo', 'census_year') + .from('adh_gini') + .from('municipio') + .from('estado') + .from('regiao') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`adh_gini.ano_censo IN (${giniYearQry.toString()})`) + .where('adh_gini.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .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]); + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/sociodemographic/state/:id', (req, res, next) => { + const stateId = parseInt(req.params.id, 10); + + const populationYearQry = squel.select() + .field('MAX(ibge_populacao.ano_censo)') + .from('ibge_populacao'); + // load all cities by state and compute the sociodemographic and educational information + const populationQry = squel.select() + .field('estado.nome', 'location') + .field('SUM(populacao)', 'population') + .field('ibge_populacao.ano_censo', 'census_year') + .from('ibge_populacao') + .from('municipio') + .from('estado') + .where(`estado.pk_estado_id = ${stateId}`) + .where(`ibge_populacao.ano_censo IN (${populationYearQry.toString()})`) + .where('ibge_populacao.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .group('estado.nome') + .group('ibge_populacao.ano_censo') + .order('estado.nome'); + + const pibYearQry = squel.select() + .field('MAX(ibge_pib.ano_censo)') + .from('ibge_pib'); + + const pibQry = squel.select() + .field('estado.nome', 'location') + .field('AVG(ibge_pib.pib_per_capita)', 'gdp_per_capita') + .field('ibge_pib.ano_censo', 'census_year') + .from('ibge_pib') + .from('municipio') + .from('estado') + .where(`estado.pk_estado_id = ${stateId}`) + .where(`ibge_pib.ano_censo IN (${pibYearQry.toString()})`) + .where('ibge_pib.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .group('estado.nome') + .group('ibge_pib.ano_censo') + .order('estado.nome'); + + const idhYearQry = squel.select() + .field('MAX(adh_idh.ano_censo)') + .from('adh_idh'); + + const idhQry = squel.select() + .field('estado.nome', 'location') + .field('AVG(idhm)', 'idhm') + .field('adh_idh.ano_censo', 'census_year') + .from('adh_idh') + .from('municipio') + .from('estado') + .where(`estado.pk_estado_id = ${stateId}`) + .where(`adh_idh.ano_censo IN (${idhYearQry.toString()})`) + .where('adh_idh.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .group('estado.nome') + .group('adh_idh.ano_censo') + .order('estado.nome'); + + const analfabYearQry = squel.select() + .field('MAX(adh_analfabetismo.ano_censo)') + .from('adh_analfabetismo'); + + const analfabQry = squel.select() + .field('estado.nome', 'location') + .field('AVG(t_analf15m)', 'analfabetism') + .field('adh_analfabetismo.ano_censo', 'census_year') + .from('adh_analfabetismo') + .from('municipio') + .from('estado') + .where(`estado.pk_estado_id = ${stateId}`) + .where(`adh_analfabetismo.ano_censo IN (${analfabYearQry.toString()})`) + .where('adh_analfabetismo.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .group('estado.nome') + .group('adh_analfabetismo.ano_censo') + .order('estado.nome'); + + const giniYearQry = squel.select() + .field('MAX(adh_gini.ano_censo)') + .from('adh_gini'); + + const giniQry = squel.select() + .field('estado.nome', 'location') + .field('AVG(gini)', 'gini') + .field('adh_gini.ano_censo', 'census_year') + .from('adh_gini') + .from('municipio') + .from('estado') + .where(`estado.pk_estado_id = ${stateId}`) + .where(`adh_gini.ano_censo IN (${giniYearQry.toString()})`) + .where('adh_gini.fk_municipio_id = municipio.pk_cod_ibge') + .where('municipio.fk_estado_id = estado.pk_estado_id') + .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]); + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/sociodemographic/city/:id', (req, res, next) => { + const cityId = parseInt(req.params.id, 10); + + const populationYearQry = squel.select() + .field('MAX(ibge_populacao.ano_censo)') + .from('ibge_populacao'); + // load all cities by state and compute the sociodemographic and educational information + const populationQry = squel.select() + .field('municipio.nome', 'location') + .field('SUM(populacao)', 'population') + .field('ibge_populacao.ano_censo', 'census_year') + .from('ibge_populacao') + .from('municipio') + .where(`municipio.pk_cod_ibge = ${cityId}`) + .where(`ibge_populacao.ano_censo IN (${populationYearQry.toString()})`) + .where('ibge_populacao.fk_municipio_id = municipio.pk_cod_ibge') + .group('municipio.nome') + .group('ibge_populacao.ano_censo') + .order('municipio.nome'); + + const pibYearQry = squel.select() + .field('MAX(ibge_pib.ano_censo)') + .from('ibge_pib'); + + const pibQry = squel.select() + .field('municipio.nome', 'location') + .field('AVG(ibge_pib.pib_per_capita)', 'gdp_per_capita') + .field('ibge_pib.ano_censo', 'census_year') + .from('ibge_pib') + .from('municipio') + .where(`municipio.pk_cod_ibge = ${cityId}`) + .where(`ibge_pib.ano_censo IN (${pibYearQry.toString()})`) + .where('ibge_pib.fk_municipio_id = municipio.pk_cod_ibge') + .group('municipio.nome') + .group('ibge_pib.ano_censo') + .order('municipio.nome'); + + const idhYearQry = squel.select() + .field('MAX(adh_idh.ano_censo)') + .from('adh_idh'); + + const idhQry = squel.select() + .field('municipio.nome', 'location') + .field('AVG(idhm)', 'idhm') + .field('adh_idh.ano_censo', 'census_year') + .from('adh_idh') + .from('municipio') + .where(`municipio.pk_cod_ibge = ${cityId}`) + .where(`adh_idh.ano_censo IN (${idhYearQry.toString()})`) + .where('adh_idh.fk_municipio_id = municipio.pk_cod_ibge') + .group('municipio.nome') + .group('adh_idh.ano_censo') + .order('municipio.nome'); + + const analfabYearQry = squel.select() + .field('MAX(adh_analfabetismo.ano_censo)') + .from('adh_analfabetismo'); + + const analfabQry = squel.select() + .field('municipio.nome', 'location') + .field('AVG(t_analf15m)', 'analfabetism') + .field('adh_analfabetismo.ano_censo', 'census_year') + .from('adh_analfabetismo') + .from('municipio') + .where(`municipio.pk_cod_ibge = ${cityId}`) + .where(`adh_analfabetismo.ano_censo IN (${analfabYearQry.toString()})`) + .where('adh_analfabetismo.fk_municipio_id = municipio.pk_cod_ibge') + .group('municipio.nome') + .group('adh_analfabetismo.ano_censo') + .order('municipio.nome'); + + const giniYearQry = squel.select() + .field('MAX(adh_gini.ano_censo)') + .from('adh_gini'); + + const giniQry = squel.select() + .field('municipio.nome', 'location') + .field('AVG(gini)', 'gini') + .field('adh_gini.ano_censo', 'census_year') + .from('adh_gini') + .from('municipio') + .where(`municipio.pk_cod_ibge = ${cityId}`) + .where(`adh_gini.ano_censo IN (${giniYearQry.toString()})`) + .where('adh_gini.fk_municipio_id = municipio.pk_cod_ibge') + .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]); + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/educational', (req, res, next) => { + const censusYearQry = squel.select() + .field('MAX(escola.ano_censo)', 'ano_censo') + .from('escola') + .toString(); + + const totalSchoolsQry = squel.select() + .field('0', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .where(`escola.ano_censo IN (${censusYearQry})`); + + const schoolsPerLocationQry = squel.select() + .field('escola.id_localizacao', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('escola.id_localizacao'); + + const queries = [totalSchoolsQry, schoolsPerLocationQry].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); + } + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/educational/region/:id', (req, res, next) => { + const regionId = parseInt(req.params.id, 10); + + const censusYearQry = squel.select() + .field('MAX(escola.ano_censo)', 'ano_censo') + .from('escola') + .toString(); + + const totalSchoolsQry = squel.select() + .field('regiao.nome') + .field('0', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('estado') + .from('regiao') + .where('escola.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('regiao.nome'); + + const schoolsPerLocationQry = squel.select() + .field('regiao.nome') + .field('escola.id_localizacao', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('estado') + .from('regiao') + .where('escola.fk_estado_id = estado.pk_estado_id') + .where('estado.fk_regiao_id = regiao.pk_regiao_id') + .where(`regiao.pk_regiao_id = ${regionId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('regiao.nome') + .group('escola.id_localizacao'); + + const queries = [totalSchoolsQry, schoolsPerLocationQry].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); + } + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/educational/state/:id', (req, res, next) => { + const stateId = parseInt(req.params.id, 10); + + const censusYearQry = squel.select() + .field('MAX(escola.ano_censo)', 'ano_censo') + .from('escola') + .toString(); + + const totalSchoolsQry = squel.select() + .field('estado.nome') + .field('0', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('estado') + .where('escola.fk_estado_id = estado.pk_estado_id') + .where(`escola.fk_estado_id = ${stateId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('estado.nome'); + + const schoolsPerLocationQry = squel.select() + .field('estado.nome') + .field('escola.id_localizacao', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('estado') + .where('escola.fk_estado_id = estado.pk_estado_id') + .where(`escola.fk_estado_id = ${stateId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('estado.nome') + .group('escola.id_localizacao'); + + const queries = [totalSchoolsQry, schoolsPerLocationQry].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); + } + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +locationApp.get('/educational/city/:id', (req, res, next) => { + const cityId = parseInt(req.params.id, 10); + + const censusYearQry = squel.select() + .field('MAX(escola.ano_censo)', 'ano_censo') + .from('escola') + .toString(); + + const totalSchoolsQry = squel.select() + .field('municipio.nome') + .field('0', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('municipio') + .where('escola.fk_municipio_id = municipio.pk_cod_ibge') + .where(`escola.fk_municipio_id = ${cityId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('municipio.nome'); + + const schoolsPerLocationQry = squel.select() + .field('municipio.nome') + .field('escola.id_localizacao', 'location') + .field('COUNT(DISTINCT(escola.cod_entidade))', 'total') + .from('escola') + .from('municipio') + .where('escola.fk_municipio_id = municipio.pk_cod_ibge') + .where(`escola.fk_municipio_id = ${cityId}`) + .where(`escola.ano_censo IN (${censusYearQry})`) + .group('municipio.nome') + .group('escola.id_localizacao'); + + const queries = [totalSchoolsQry, schoolsPerLocationQry].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); + } + } + next(); + }).catch((error) => { + log.error(`[SQL query error] ${error}`); + next(error); + }); +}, response('location')); + +module.exports = locationApp;