From c3283b1076e74468ce4fd8e37c74c22a20a40543 Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Tue, 10 Jan 2017 10:06:41 -0200
Subject: [PATCH] Change parseParams middleware to ReqQueryFields

---
 src/libs/routes/api.js        |   2 +-
 src/libs/routes/city.js       |  58 +++---
 src/libs/routes/enrollment.js | 320 +++++++++++++++++-----------------
 src/libs/routes/region.js     |  30 +++-
 src/libs/routes/school.js     |  90 ++++++----
 src/libs/routes/state.js      |  60 +++++--
 6 files changed, 317 insertions(+), 243 deletions(-)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 2c259bab..422dd97b 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -30,7 +30,7 @@ api.get('/', (req, res) => {
 
 api.use('/user', user);
 api.use('/simulation', simulation);
-api.use('/enrollment', cache('1 day'), enrollment);
+api.use('/enrollment', enrollment);
 api.use('/state', cache('15 day'), state);
 api.use('/region', cache('15 day'), region);
 api.use('/city', cache('15 day'), city);
diff --git a/src/libs/routes/city.js b/src/libs/routes/city.js
index d9632875..41e44254 100644
--- a/src/libs/routes/city.js
+++ b/src/libs/routes/city.js
@@ -10,31 +10,45 @@ const query = require(`${libs}/middlewares/query`);
 
 const response = require(`${libs}/middlewares/response`);
 
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addValue({
+    name: 'id',
+    table: 'municipio',
+    tableField: 'pk_cod_ibge',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_cod_ibge'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'fk_estado_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'pk_estado_id',
+        foreign: 'fk_estado_id',
+        foreignTable: 'municipio'
+    }
+});
+
 // Return all cities
-cityApp.get('/', (req, res, next) => {
+cityApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('municipio');
     next();
 }, query, response('city'));
 
-// Return a specific city by it's id
-cityApp.get('/:id', (req, res, next) => {
-    req.sql.from('municipio')
-        .where('pk_cod_ibge = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('city'));
-
-// Return a specific city by it's IBGE code
-cityApp.get('/ibge/:id', (req, res, next) => {
-    req.sql.from('municipio')
-        .where('pk_cod_ibge = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('city'));
-
-// Return all the cities from a specific state
-cityApp.get('/state/:id', (req, res, next) => {
-    req.sql.from('municipio')
-        .where('fk_estado_id = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('city'));
-
 module.exports = cityApp;
diff --git a/src/libs/routes/enrollment.js b/src/libs/routes/enrollment.js
index 3e878e7f..f74b5fa3 100644
--- a/src/libs/routes/enrollment.js
+++ b/src/libs/routes/enrollment.js
@@ -14,15 +14,16 @@ const response = require(`${libs}/middlewares/response`);
 
 const parseParams = require(`${libs}/middlewares/parseParams`);
 
-// **Temporary** solution to add where clauses that are common to all requests
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
 
+let rqf = new ReqQueryFields();
 
 // Complete range of the enrollments dataset.
 // Returns a tuple of start and ending years of the complete enrollments dataset.
 enrollmentApp.get('/year_range', (req, res, next) => {
     req.sql.from('turma')
-        .field('MIN(turma.ano_censo)', 'start_year')
-        .field('MAX(turma.ano_censo)', 'end_year');
+    .field('MIN(turma.ano_censo)', 'start_year')
+    .field('MAX(turma.ano_censo)', 'end_year');
 
     next();
 }, query, response('range'));
@@ -30,8 +31,8 @@ enrollmentApp.get('/year_range', (req, res, next) => {
 // Returns all educational levels avaible
 enrollmentApp.get('/education_level', (req, res, next) => {
     req.sql.from('etapa_ensino')
-        .field('pk_etapa_ensino_id', 'id')
-        .field('desc_etapa', 'name');
+    .field('pk_etapa_ensino_id', 'id')
+    .field('desc_etapa', 'name');
 
     next();
 }, query, response('education_level'));
@@ -39,167 +40,170 @@ enrollmentApp.get('/education_level', (req, res, next) => {
 // Returns all adm dependencies
 enrollmentApp.get('/adm_dependency', (req, res, next) => {
     req.sql.from('dependencia_adm')
-        .field('pk_dependencia_adm_id', 'id')
-        .field('nome', 'name');
+    .field('pk_dependencia_adm_id', 'id')
+    .field('nome', 'name');
 
     next();
 }, query, response('adm_dependency'));
 
-// Parse the filters and dimensions parameter in the query
-enrollmentApp.use('/', parseParams('filter', [
-    'min_year',
-    'max_year',
-    'adm_dependency',
-    'location',
-    'education_level',
-    'region',
-    'state',
-    'city',
-    'school'
-]), parseParams('dims', [
-    'adm_dependency',
-    'location',
-    'education_level',
-    'region',
-    'state',
-    'city',
-    'school'
-]), (req, res, next) => {
-    log.debug(req.filter);
-    log.debug(req.dims);
-
-    // Do the joins
-    if(typeof req.filter.adm_dependency !== 'undefined'
-        || typeof req.dims.adm_dependency !== 'undefined') {
-        req.sql.join('dependencia_adm', null, 'fk_dependencia_adm_id=dependencia_adm.pk_dependencia_adm_id');
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: 'dependencia_adm',
+    tableField: 'nome',
+    resultField: 'adm_dependency_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_dependencia_adm_id'
+    },
+    join: {
+        primary: 'pk_dependencia_adm_id',
+        foreign: 'fk_dependencia_adm_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'education_level',
+    table: 'etapa_ensino',
+    tableField: 'desc_etapa',
+    resultField: 'education_level',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_etapa_ensino_id'
+    },
+    join: {
+        primary: 'pk_etapa_ensino_id',
+        foreign: 'fk_etapa_ensino_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_regiao_id'
+    },
+    join: {
+        primary: 'pk_regiao_id',
+        foreign: 'fk_regiao_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_estado_id'
+    },
+    join: {
+        primary: 'pk_estado_id',
+        foreign: 'fk_estado_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_cod_ibge'
+    },
+    join: {
+        primary: 'pk_cod_ibge',
+        foreign: 'fk_municipio_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'school',
+    table: 'escola',
+    tableField: 'cod_entidade',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_entidade'
+    },
+    join: {
+        primary: 'cod_entidade',
+        foreign: 'cod_entidade',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'location',
+    table: 'localizacao',
+    tableField: 'descricao',
+    resultField: 'location_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_localizacao_id'
+    },
+    join: {
+        primary: 'pk_localizacao_id',
+        foreign: 'fk_localizacao_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_cod_ibge'
+    },
+    join: {
+        primary: 'pk_cod_ibge',
+        foreign: 'fk_municipio_id',
+        foreignTable: 'turma'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'turma',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo'
+    }
+}).addValue({
+    name: 'max_year',
+    table: 'turma',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo'
     }
-
-    if(typeof req.filter.education_level !== 'undefined'
-        || typeof req.dims.education_level !== 'undefined') {
-        req.sql.join('etapa_ensino', null, 'fk_etapa_ensino_id=etapa_ensino.pk_etapa_ensino_id');
-    }
-
-    if(typeof req.filter.region !== 'undefined'
-        || typeof req.dims.region !== 'undefined') {
-            req.sql.join('regiao', null, 'fk_regiao_id=regiao.pk_regiao_id');
-    }
-
-    if(typeof req.filter.state !== 'undefined'
-        || typeof req.dims.state !== 'undefined') {
-            req.sql.join('estado', null, 'fk_estado_id=estado.pk_estado_id');
-    }
-
-    if(typeof req.filter.city !== 'undefined'
-        || typeof req.dims.city !== 'undefined') {
-        req.sql.join('municipio', null, 'fk_municipio_id=municipio.pk_cod_ibge');
-    }
-
-    if(typeof req.dims.school !== 'undefined') {
-        req.sql.join('escola', null, 'turma.cod_entidade=escola.cod_entidade');
-    }
-
-    if(typeof req.dims.location !== 'undefined') {
-        req.sql.join('localizacao', null, 'turma.id_localizacao=localizacao.pk_localizacao_id')
-    }
-
-    // Dimensions (add fields)
-
-    if(typeof req.dims.education_level !== 'undefined') {
-        req.sql.field('desc_etapa', 'education_level')
-            .group('desc_etapa')
-            .order('desc_etapa');
-    }
-
-    if(typeof req.dims.region !== 'undefined') {
-        req.sql.field('regiao.nome', 'region_name')
-            .group('regiao.nome')
-            .order('regiao.nome');
-    }
-
-    if(typeof req.dims.state !== 'undefined') {
-        req.sql.field('estado.nome', 'state_name')
-            .group('estado.nome')
-            .order('estado.nome');
-    }
-
-    if(typeof req.dims.city !== 'undefined') {
-        req.sql.field('municipio.nome', 'city_name')
-            .group('municipio.nome')
-            .order('municipio.nome');
-    }
-
-    if(typeof req.dims.school !== 'undefined') {
-        req.sql.field('escola.cod_entidade', 'school_name')
-            .group('escola.cod_entidade')
-            .order('escola.cod_entidade');
-    }
-
-    if(typeof req.dims.adm_dependency !== 'undefined') {
-        req.sql.field('dependencia_adm.nome', 'adm_dependency_name')
-            .group('dependencia_adm.nome')
-            .order('dependencia_adm.nome');
-    }
-
-    if(typeof req.dims.location !== 'undefined') {
-        req.sql.field('localizacao.descricao', 'location_name')
-            .group('localizacao.descricao')
-            .order('localizacao.descricao');
-    }
-
-    if(typeof req.dims.region === 'undefined'
-        && typeof req.dims.state === 'undefined'
-        && typeof req.dims.city === 'undefined'
-        && typeof req.dims.school === 'undefined') {
-        req.sql.field("'Brasil'", 'name');
-    }
-
-    // Filter (add where)
-
-    if (typeof req.filter.min_year !== 'undefined') {
-        req.sql.where('turma.ano_censo>=?', parseInt(req.filter.min_year, 10));
-    }
-
-    if (typeof req.filter.max_year !== 'undefined') {
-        req.sql.where('turma.ano_censo<=?', parseInt(req.filter.max_year, 10));
-    }
-
-    if (typeof req.filter.adm_dependency !== 'undefined') {
-        req.sql.where('pk_dependencia_adm_id=?', parseInt(req.filter.adm_dependency, 10));
-    }
-
-    if (typeof req.filter.location !== 'undefined') {
-        req.sql.where('turma.id_localizacao=?', parseInt(req.filter.location, 10));
-    }
-
-    if (typeof req.filter.education_level !== 'undefined') {
-        req.sql.where('pk_etapa_ensino_id=?', parseInt(req.filter.education_level, 10));
-    }
-
-    if (typeof req.filter.region !== 'undefined') {
-        req.sql.where('pk_regiao_id=?', parseInt(req.filter.region, 10));
-    }
-
-    if (typeof req.filter.state !== 'undefined') {
-        req.sql.where('pk_estado_id=?', parseInt(req.filter.state, 10));
-    }
-
-    if (typeof req.filter.city !== 'undefined') {
-        req.sql.where('turma.fk_municipio_id=?', parseInt(req.filter.city, 10));
-    }
-
-    if (typeof req.filter.school !== 'undefined') {
-        req.sql.where('turma.fk_escola_id=?', parseInt(req.filter.school, 10));
-    }
-    log.debug(req.sql.toParam());
-    next();
 });
 
-enrollmentApp.get('/', (req, res, next) => {
+enrollmentApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    log.debug(req.sql.toParam());
     req.sql.field('COALESCE(SUM(num_matriculas), 0)', 'total')
-        .field('turma.ano_censo', 'year')
-        .from('turma')
-        .group('turma.ano_censo')
-        .order('turma.ano_censo');
+    .field("'Brasil'", 'name')
+    .field('turma.ano_censo', 'year')
+    .from('turma')
+    .group('turma.ano_censo')
+    .order('turma.ano_censo');
     next();
 }, query, response('enrollment'));
 
diff --git a/src/libs/routes/region.js b/src/libs/routes/region.js
index 0a8b65f8..be2eb9b0 100644
--- a/src/libs/routes/region.js
+++ b/src/libs/routes/region.js
@@ -10,17 +10,29 @@ const query = require(`${libs}/middlewares/query`);
 
 const response = require(`${libs}/middlewares/response`);
 
-// Get all regions
-regionApp.get('/', (req, res, next) => {
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addValue({
+    name: 'id',
+    table: 'regiao',
+    tableField: 'pk_regiao_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_regiao_id',
+        table: 'regiao'
+    }
+});
+
+regionApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('regiao');
     next();
 }, query, response('region'));
 
-// Get a region by it's id
-regionApp.get('/:id', (req, res, next) => {
-    req.sql.from('regiao')
-        .where('pk_regiao_id = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('region'));
-
 module.exports = regionApp;
diff --git a/src/libs/routes/school.js b/src/libs/routes/school.js
index 4ae980e2..9006137c 100644
--- a/src/libs/routes/school.js
+++ b/src/libs/routes/school.js
@@ -10,47 +10,63 @@ const query = require(`${libs}/middlewares/query`);
 
 const response = require(`${libs}/middlewares/response`);
 
-/**
- * YOU SHALL NOT PASS
- * Esta rota foi desabilitada pois é mais violenta que clube da luta batendo em laranja mecânica
- * A api fica sobrecarregada
- * Pense na cena do elevador de driver mas o elevador é uma bomba de fusão e demora mais que uma luta do DBz
- */
-// schoolApp.get('/', (req, res, next) => {
-//     req.sql = squel.select().from('escola')
-//         .field('cod_entidade')
-//         .field('ano_censo', 'year')
-//         .field('fk_estado_id')
-//         .field('fk_municipio_id');
-//     next();
-// }, query, response('school'));
-
-// Get a school by it's id
-schoolApp.get('/:id', (req, res, next) => {
-    req.sql.from('escola')
-        .where('escola.cod_entidade = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('school'));
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
 
-// Get all schools from a state
-schoolApp.get('/state/:id', (req, res, next) => {
-    req.sql.from('escola')
-        .field('escola.cod_entidade')
-        .field('ano_censo')
-        .field('fk_estado_id')
-        .field('fk_municipio_id')
-        .where('fk_estado_id = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('school'));
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addValue({
+    name: 'id',
+    table: 'escola',
+    tableField: 'cod_entidade',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_entidade'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'fk_municipio_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'pk_cod_ibge',
+        foreign: 'fk_municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'fk_estado_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'pk_estado_id',
+        foreign: 'fk_estado_id',
+        foreignTable: 'escola'
+    }
+});
 
-// Get all schools from a city
-schoolApp.get('/city/:id', (req, res, next) => {
+schoolApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('escola')
         .field('escola.cod_entidade')
-        .field('ano_censo')
-        .field('fk_estado_id')
-        .field('fk_municipio_id')
-        .where('fk_municipio_id = ?', parseInt(req.params.id, 10));
+        .field('escola.ano_censo', 'year')
+        .field('escola.fk_estado_id')
+        .field('escola.fk_municipio_id');
     next();
 }, query, response('school'));
 
diff --git a/src/libs/routes/state.js b/src/libs/routes/state.js
index 8567ec05..399be414 100644
--- a/src/libs/routes/state.js
+++ b/src/libs/routes/state.js
@@ -10,23 +10,51 @@ const query = require(`${libs}/middlewares/query`);
 
 const response = require(`${libs}/middlewares/response`);
 
-// Get all states
-stateApp.get('/', (req, res, next) => {
-    req.sql.from('estado');
-    next();
-}, query, response('state'));
-
-// Get a state
-stateApp.get('/:id', (req, res, next) => {
-    req.sql.from('estado')
-        .where('pk_estado_id = ?', parseInt(req.params.id, 10));
-    next();
-}, query, response('state'));
-
-// Get all states from a region
-stateApp.get('/region/:id', (req, res, next) => {
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addValue({
+    name: 'id',
+    table: 'estado',
+    tableField: 'pk_estado_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'pk_estado_id'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'fk_regiao_id',
+        table: 'estado'
+    },
+    join: {
+        primary: 'pk_regiao_id',
+        foreign: 'fk_regiao_id',
+        foreignTable: 'estado'
+    }
+});
+
+stateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
     req.sql.from('estado')
-        .where('fk_regiao_id = ?', parseInt(req.params.id, 10));
+        .field('pk_estado_id')
+        .group('pk_estado_id')
+        .field('fk_regiao_id')
+        .group('fk_regiao_id')
+        .field('estado.nome')
+        .group('estado.nome')
+        .field('estado.sigla')
+        .group('estado.sigla');
     next();
 }, query, response('state'));
 
-- 
GitLab