diff --git a/libs/routes/api.js b/libs/routes/api.js index 9bea796cbdc5786f43fe42b6ef04b082f1048a05..16105a85d87e3afd2dd9120f28d2636f4503861b 100644 --- a/libs/routes/api.js +++ b/libs/routes/api.js @@ -60,144 +60,218 @@ router.get('/data', function(req, res) { router.get('/enrollments', function(req, res, next) { const params = req.query; + req.paramCnt = 0; - if (params.id) { + if (typeof params.id !== 'undefined') { req.id = parseInt(params.id, 10); + req.paramCnt += 1; } - if (params.location_id) { + if (typeof params.location_id !== 'undefined') { req.location_id = parseInt(params.location_id, 10); + req.paramCnt += 1; } - if (params.adm_dependency_id) { + if (typeof params.adm_dependency_id !== 'undefined') { req.adm_dependency_id = parseInt(params.adm_dependency_id, 10); + req.paramCnt += 1; } - if (params.census_year) { + if (typeof params.census_year !== 'undefined') { req.census_year = parseInt(params.census_year, 10); + req.paramCnt += 1; } - if (params.aggregate) { - log.debug('aggregate parameter detected'); - next('route'); - } else { - log.debug('No aggregate parameter detected'); - next(); - } + next(); +}); - /* - switch(params.aggregate) - { - case "city": - if (id) { - enrollmentSql = "SELECT nome AS name, total FROM mat_municipio(" + id + "," + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } else { - enrollmentSql = "SELECT nome AS name, total FROM mat_municipios(" + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } - break; - case "state": - if (id) { - enrollmentSql = "SELECT nome AS name, total FROM mat_estado(" + id + "," + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } else { - enrollmentSql = "SELECT nome AS name, total FROM mat_estados(" + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } - break; - case "region": - if (id) { - enrollmentSql = "SELECT nome AS name, total FROM mat_regiao(" + id + "," + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } else { - enrollmentSql = "SELECT nome AS name, total FROM mat_regioes(" + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } - break; - default: - enrollmentSql = "SELECT nome AS name, total FROM mat_brasil(" + census_year + "," + adm_dependency_id + "," + location_id + ")"; - } +router.get('/enrollments', function(req, res, next) { + const params = req.query; + if (typeof params.aggregate !== 'undefined' && params.aggregate === 'region') { + log.debug('Using enrollments query for regions'); + req.sqlQuery = 'SELECT r.nome, COALESCE(SUM(t.num_matriculas), 0) AS total ' + + 'FROM regioes AS r ' + + 'INNER JOIN estados AS e ON r.pk_regiao_id = e.fk_regiao_id ' + + 'INNER JOIN municipios AS m ON e.pk_estado_id = m.fk_estado_id ' + + 'LEFT OUTER JOIN turmas AS t ON ( ' + + 'm.pk_municipio_id = t.fk_municipio_id '; + req.sqlQueryParams = []; - log.debug(params); - log.debug("Executing query: " + enrollmentSql); + if (typeof req.census_year !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.ano_censo = ?'; + req.sqlQueryParams.push(req.census_year); + } - conn.query(enrollmentSql, true).then(function(result) { - log.debug(result); - if (req.query.format === 'csv') { - res.csv(result.data); - } else if (req.query.format === 'xml') { - res.send(xml("result", JSON.stringify({enrollments: result.data}))) + if (typeof req.adm_dependency_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.fk_dependencia_adm_id = ?'; + req.sqlQueryParams.push(req.adm_dependency_id); } - else { - res.json({ - result: result.data - }); + + if (typeof req.location_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.id_localizacao = ?'; + req.sqlQueryParams.push(req.location_id); } - log.debug("All resources were released"); - }, function(error) { - }); - */ -}, function(req, res, next) { - /** When no +aggregate+ parameter value is specified on the request, then - * assign the query to compute the result for the whole country. - */ - log.debug('Using SQL query for the whole country'); - req.sql_query = 'SELECT * FROM turmas LIMIT 1'; - next('route'); + req.sqlQuery += ')'; + if (typeof req.id !== 'undefined') { + req.sqlQuery += ' WHERE '; + req.sqlQuery += 'r.pk_regiao_id = ?'; + req.sqlQueryParams.push(req.id); + } + req.sqlQuery += ' GROUP BY r.nome'; + } + next(); }); router.get('/enrollments', function(req, res, next) { const params = req.query; - if (!params.aggregate) { - next('route'); - } else if (params.aggregate == 'region') { - log.debug('Using enrollments query for regions'); - req.sql_query = 'SELECT * FROM turmas LIMIT 1'; + if (typeof params.aggregate !== 'undefined' && params.aggregate === 'state') { + log.debug('Using enrollments query for states'); + req.sqlQuery = 'SELECT e.nome, COALESCE(SUM(t.num_matriculas), 0) as total ' + + 'FROM estados AS e ' + + 'INNER JOIN municipios AS m ON m.fk_estado_id = e.pk_estado_id ' + + 'LEFT OUTER JOIN turmas AS t ON (' + + 'm.pk_municipio_id = t.fk_municipio_id '; + req.sqlQueryParams = []; + + if (typeof req.census_year !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.ano_censo = ?'; + req.sqlQueryParams.push(req.census_year); + } + + if (typeof req.adm_dependency_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.fk_dependencia_adm_id = ?'; + req.sqlQueryParams.push(req.adm_dependency_id); + } + + if (typeof req.location_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.id_localizacao = ?'; + req.sqlQueryParams.push(req.location_id); + } + + req.sqlQuery += ')'; + + if (typeof req.id !== 'undefined') { + req.sqlQuery += " WHERE "; + req.sqlQuery += "e.pk_estado_id = ?"; + req.sqlQueryParams.push(req.id); + } + + req.sqlQuery += ' GROUP BY e.nome'; } - next('route'); + next(); }); router.get('/enrollments', function(req, res, next) { const params = req.query; - if (!params.aggregate) { - next('route'); - } else if (params.aggregate == 'state') { - log.debug('Using enrollments query for states'); - req.sql_query = 'SELECT * FROM turmas LIMIT 1'; + if (typeof params.aggregate !== 'undefined' && params.aggregate === 'city') { + log.debug('Using enrollments query for cities'); + req.sqlQuery = 'SELECT m.nome, COALESCE(SUM(t.num_matriculas), 0) as total ' + + 'FROM municipios AS m ' + + 'LEFT OUTER JOIN turmas AS t ON ( ' + + 'm.pk_municipio_id = t.fk_municipio_id'; + req.sqlQueryParams = []; + + if (typeof req.census_year !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.ano_censo = ?'; + req.sqlQueryParams.push(req.census_year); + } + + if (typeof req.adm_dependency_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.fk_dependencia_adm_id = ?'; + req.sqlQueryParams.push(req.adm_dependency_id); + } + + if (typeof req.location_id !== 'undefined') { + req.sqlQuery += ' AND '; + req.sqlQuery += 't.id_localizacao = ?'; + req.sqlQueryParams.push(req.location_id); + } + + req.sqlQuery += ')'; + + if (typeof req.id !== 'undefined') { + req.sqlQuery += " WHERE "; + req.sqlQuery += "m.pk_municipio_id = ?"; + req.sqlQueryParams.push(req.id); + } + + req.sqlQuery += 'GROUP BY m.nome'; } - next('route'); + next(); }); router.get('/enrollments', function(req, res, next) { const params = req.query; - if (!params.aggregate) { - next('route'); - } else if (params.aggregate == 'city') { - log.debug('Using enrollments query for cities'); - req.sql_query = 'SELECT * FROM turmas LIMIT 1'; + if (typeof params.aggregate === 'undefined') { + log.debug('Using enrollments query for the whole country'); + req.sqlQuery = 'SELECT \'Brasil\', COALESCE(SUM(t.num_matriculas),0) AS total ' + + 'FROM turmas AS t'; + req.sqlQueryParams = []; + + if (req.paramCnt > 0) { + req.sqlQuery += ' WHERE '; + } + + if (typeof req.census_year !== 'undefined') { + req.sqlQuery += 't.ano_censo = ?'; + req.sqlQueryParams.push(req.census_year); + } + + if (typeof req.adm_dependency_id !== 'undefined') { + if (req.sqlQueryParams.length > 0) { + req.sqlQuery += ' AND '; + } + req.sqlQuery += 't.fk_dependencia_adm = ?'; + req.sqlQueryParams.push(req.adm_dependency_id); + } + + if (typeof req.location_id !== 'undefined') { + if (req.sqlQueryParams.length > 0) { + req.sqlQuery += ' AND '; + } + req.sqlQuery += 't.id_localizacao = ?'; + req.sqlQueryParams.push(req.location_id); + } } - next('route'); + next(); }); router.get('/enrollments', function(req, res, next) { - log.debug('Request parameters: ${req}?'); - if (!req.sql_query) { + log.debug('Request parameters: ${ req }?'); + if (!req.sqlQuery) { /* Should only happen if there is a bug in the chaining of the * '/enrollments' route, since when no +aggregate+ parameter is given, * it defaults to use the query for the whole country. */ log.error('BUG -- No SQL query was found to be executed!'); - res.status(501).end(); + res.send('Request could not be satisfied due to an internal error'); } else { - log.debug('SQL query: ${req.sql_query}?'); - conn.query(req.sql_query, true).then(function(result) { - log.debug(result); - if (req.query.format === 'csv') { - res.csv(result.data); - } else if (req.query.format === 'xml') { - res.send(xml('result', JSON.stringify({enrollments: result.data}))); - } else { - res.json({ result: result.data }); - } + log.debug('SQL query: ${ req.sqlQuery }?'); + log.debug(req.sqlQuery); + conn.prepare(req.sqlQuery, true).then(function(dbQuery) { + dbQuery.exec(req.sqlQueryParams).then(function(dbResult) { + log.debug(dbResult); + if (req.query.format === 'csv') { + res.csv(dbResult.data); + } else if (req.query.format === 'xml') { + res.send(xml('result', JSON.stringify({enrollments: dbResult.data}))); + } else { + res.json({ result: dbResult.data }); + } + }); }, function(error) { - log.error('SQL query error: ${error}?'); - res.status(501).end(); + log.error('SQL query error: ${ error.message }?'); + log.debug(error); + res.send('Request could not be satisfied due to an internal error'); }); } });