Skip to content
Snippets Groups Projects
Commit cd64fcb6 authored by Vytor Calixto's avatar Vytor Calixto :space_invader:
Browse files

Change jsdoc to Docco

parent 9c48e5c5
No related branches found
No related tags found
1 merge request!15Change jsdoc to Docco
Pipeline #
...@@ -10,7 +10,7 @@ const nodemon = require('gulp-nodemon'); ...@@ -10,7 +10,7 @@ const nodemon = require('gulp-nodemon');
const Cache = require('gulp-file-cache'); const Cache = require('gulp-file-cache');
const jsdoc = require('gulp-jsdoc3'); const docco = require('gulp-docco');
const cache = new Cache(); const cache = new Cache();
...@@ -38,12 +38,14 @@ function compile() { ...@@ -38,12 +38,14 @@ function compile() {
gulp.task('build', compile); gulp.task('build', compile);
gulp.task('doc', (cb) => { gulp.task('docco', () => {
let config = require('./jsdoc.json'); gulp.src('./src/**/*.js')
gulp.src(['README.md', './src/**/*.js'], {read: false}) .pipe(docco())
.pipe(jsdoc(config, cb)); .pipe(gulp.dest('./docs'));
}); });
gulp.task('doc', ['docco']);
gulp.task('test', () => { gulp.task('test', () => {
gulp.src('test/test.js', {read: false}) gulp.src('test/test.js', {read: false})
.pipe(mocha()) .pipe(mocha())
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-babel": "^6.1.2", "gulp-babel": "^6.1.2",
"gulp-cli": "^1.2.2", "gulp-cli": "^1.2.2",
"gulp-docco": "0.0.4",
"gulp-eslint": "^3.0.1", "gulp-eslint": "^3.0.1",
"gulp-file-cache": "0.0.1", "gulp-file-cache": "0.0.1",
"gulp-jsdoc3": "^0.3.0", "gulp-jsdoc3": "^0.3.0",
......
...@@ -18,25 +18,30 @@ const mongoose = require('./db/mongoose'); ...@@ -18,25 +18,30 @@ const mongoose = require('./db/mongoose');
const db = mongoose(); const db = mongoose();
// Set default node environment
process.env.NODE_ENV = process.env.NODE_ENV || 'development'; process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// Parse json received in requests
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser()); app.use(cookieParser());
// Enable Cross-Origin Resource Sharing (CORS)
app.use(cors()); app.use(cors());
app.use(methodOverride()); app.use(methodOverride());
// Enable cache for 1 day
app.use(cache('1 day')); app.use(cache('1 day'));
// Enable maximum compression
app.use(compression(9)); app.use(compression(9));
app.use(api); app.use(api);
// catch 404 and forward to error handler // Catch 404 and forward to error handler
app.use((req, res, next) => { app.use((req, res, next) => {
res.status(404); res.status(404);
log.debug('%s %d %s', req.method, res.statusCode, req.url); log.debug('%s %d %s', req.method, res.statusCode, req.url);
res.json({ error: 'Not found' }).end(); res.json({ error: 'Not found' }).end();
}); });
// error handlers // Error handlers
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
res.status(err.status || 500); res.status(err.status || 500);
log.error('%s %d %s', req.method, res.statusCode, err.message); log.error('%s %d %s', req.method, res.statusCode, err.message);
......
const nconf = require('nconf'); const nconf = require('nconf');
// Exports the config.json as an object with get functions
nconf.argv() nconf.argv()
.env() .env()
.file({ file: `${process.cwd()}/config.json` }); .file({ file: `${process.cwd()}/config.json` });
......
...@@ -4,10 +4,12 @@ const libs = `${process.cwd()}/libs`; ...@@ -4,10 +4,12 @@ const libs = `${process.cwd()}/libs`;
const config = require(`${libs}/config`); const config = require(`${libs}/config`);
// Connection options
const poolOptions = { const poolOptions = {
nrConnections: config.get('monetdb:nrConnections'), nrConnections: config.get('monetdb:nrConnections'),
}; };
// Configuration options
const options = { const options = {
host: config.get('monetdb:host'), host: config.get('monetdb:host'),
port: config.get('monetdb:port'), port: config.get('monetdb:port'),
...@@ -16,6 +18,7 @@ const options = { ...@@ -16,6 +18,7 @@ const options = {
password: config.get('monetdb:password'), password: config.get('monetdb:password'),
}; };
// Connection singleton
const conn = new MonetDBPool(poolOptions, options); const conn = new MonetDBPool(poolOptions, options);
conn.connect(); conn.connect();
......
...@@ -7,8 +7,10 @@ const log = require(`${libs}/log`)(module); ...@@ -7,8 +7,10 @@ const log = require(`${libs}/log`)(module);
const mongoose = require('mongoose'); const mongoose = require('mongoose');
module.exports = () => { module.exports = () => {
// Get mongodb URI (ip and port) in config file
const mongoUri = config.get('mongodb:uri'); const mongoUri = config.get('mongodb:uri');
log.debug(`Connecting to MongDB on URI ${mongoUri}`); log.debug(`Connecting to MongDB on URI ${mongoUri}`);
// Connection singleton
const db = mongoose.connect(mongoUri); const db = mongoose.connect(mongoUri);
mongoose.connection.once('open', () => { log.info("MongoDB connected"); }); mongoose.connection.once('open', () => { log.info("MongoDB connected"); });
......
const libs = `${process.cwd()}/libs`; const libs = `${process.cwd()}/libs`;
const log = require(`${libs}/log`)(module); const log = require(`${libs}/log`)(module);
const conn = require(`${libs}/db/monet`); const conn = require(`${libs}/db/monet`);
/** // Promise that executes an SQL query with optional parameters
* Promise that executes an SQL query with optional parameters // ```
* // Examples:
* Examples: // Query with no parameters:
* Query with no parameters: // execSqlQuery('SELECT * FROM people');
* execSqlQuery('SELECT * FROM people'); // Query with one parameter:
* Query with one parameter: // execSqlQuery('SELECT name, age FROM people WHERE id = ?', [1]);
* execSqlQuery('SELECT name, age FROM people WHERE id = ?', [1]); // Query with more than one parameter:
* Query with more than one parameter: // execSqlQuery('SELECT name, age FROM people WHERE city = ? AND age > ?', ['São Paulo', 35]);
* execSqlQuery('SELECT name, age FROM people WHERE city = ? AND age > ?', ['São Paulo', 35]); // ```
*
* @param {string} sqlQuery - SQL query to be executed by the Promise
* @param {array} sqlQueryParams - SQL query parameters
*/
function execSqlQuery(sqlQuery, sqlQueryParams = []) { function execSqlQuery(sqlQuery, sqlQueryParams = []) {
log.debug(`Executing SQL query '${sqlQuery}' with params '${sqlQueryParams}'`); log.debug(`Executing SQL query '${sqlQuery}' with params '${sqlQueryParams}'`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Prepare statement
conn.prepare(sqlQuery, true).then( conn.prepare(sqlQuery, true).then(
(dbQuery) => { (dbQuery) => {
// Execute query
dbQuery.exec(sqlQueryParams).then( dbQuery.exec(sqlQueryParams).then(
// Success
(dbResult) => { (dbResult) => {
log.debug(`Query result: ${dbResult.data}`); log.debug(`Query result: ${dbResult.data}`);
log.debug(dbResult.data); log.debug(dbResult.data);
resolve(dbResult.data); resolve(dbResult.data);
}, },
// Error
(dbError) => { (dbError) => {
log.error(`SQL query execution error: ${dbError.message}`); log.error(`SQL query execution error: ${dbError.message}`);
reject(new Error(dbError.message)); reject(new Error(dbError.message));
} }
); );
// release resources allocated for prepared statement // Release resources allocated for prepared statement
conn.release(); conn.release();
} }
); );
......
/**
* Dimensions middleware
*
* EXAMPLE:
* Use it with no parameters to get all the dimensions specified
* app.get('/', dimensions(), function(req, res, next){})
*
* Use it with an array of accepted values
* app.get('/', dimensions(['year', 'location']), function(req, res, next){})
*
* Use it globally
* app.use(dimensions())
*/
/** // This function returns the intersection of two arrays
* This function returns the intersection of two arrays
* @param {array} a [description]
* @param {array} b [description]
* @return {array} [description]
*/
function intersect(a, b) { function intersect(a, b) {
let t; let t;
if (b.length > a.length) { if (b.length > a.length) {
...@@ -26,23 +8,35 @@ function intersect(a, b) { ...@@ -26,23 +8,35 @@ function intersect(a, b) {
return a.filter((e) => b.indexOf(e) !== -1); return a.filter((e) => b.indexOf(e) !== -1);
} }
// Dimensions middleware
// ```
// EXAMPLE:
// Use it with no parameters to get all the dimensions specified
// app.get('/', dimensions(), function(req, res, next){})
//
// Use it with an array of accepted values
// app.get('/', dimensions(['year', 'location']), function(req, res, next){})
//
// Use it globally
// app.use(dimensions())
// ```
function dimensions(dims) { function dimensions(dims) {
return (req, res, next) => { return (req, res, next) => {
req.dims = {}; req.dims = {};
if (req.query.dims) { if (req.query.dims) {
// Split the string and get all dimensions.
// Example string: 'state:41,year:2013,urban'
const params = req.query.dims.split(','); const params = req.query.dims.split(',');
const dimObj = {}; const dimObj = {};
// For each dimension in the array see if there is a value associated
for (const param of params) { for (const param of params) {
const kv = param.split(':'); const kv = param.split(':');
dimObj[kv[0]] = (typeof kv[1] === 'undefined') ? null : kv[1]; dimObj[kv[0]] = (typeof kv[1] === 'undefined') ? null : kv[1];
} }
// for(let i=0; i<params.length; ++i) {
// let kv = params[i].split(':');
// dimObj[kv[0]] = (typeof kv[1] === 'undefined') ? null : kv[1];
// }
// If the dims array exists and is not empty // If the dims array exists and is not empty
if (typeof dims !== 'undefined' && dims.length > 0) { if (typeof dims !== 'undefined' && dims.length > 0) {
// Intersect the two arrays
const intersection = intersect(dims, Object.keys(dimObj)); const intersection = intersect(dims, Object.keys(dimObj));
for (let i = 0; i < intersection.length; ++i) { for (let i = 0; i < intersection.length; ++i) {
req.dims[intersection[i]] = dimObj[intersection[i]]; req.dims[intersection[i]] = dimObj[intersection[i]];
......
...@@ -2,12 +2,7 @@ const libs = `${process.cwd()}/libs`; ...@@ -2,12 +2,7 @@ const libs = `${process.cwd()}/libs`;
const log = require(`${libs}/log`)(module); const log = require(`${libs}/log`)(module);
const execQuery = require(`${libs}/db/query_exec`); const execQuery = require(`${libs}/db/query_exec`);
/** // Middleware that executes a query defined by a squel object in req.sql
* Middleware that executes a query defined by a squel object in req.sql
* @param {Object} req [description]
* @param {Object} res [description]
* @param {Function} next [description]
*/
function query(req, res, next) { function query(req, res, next) {
log.debug(req.sql); log.debug(req.sql);
execQuery(req.sql.text, req.sql.values).then((result) => { execQuery(req.sql.text, req.sql.values).then((result) => {
......
...@@ -3,10 +3,8 @@ const log = require(`${libs}/log`)(module); ...@@ -3,10 +3,8 @@ const log = require(`${libs}/log`)(module);
const xml = require('js2xmlparser'); const xml = require('js2xmlparser');
const csv = require('csv-express'); const csv = require('csv-express');
/** // Custom generic middleware used respond requests.
* Custom generic middleware used to send api responses // The function reads the req.query.format param and respond in json, xml or csv
* @param {string} value text to be used in the xml response
*/
function response(value) { function response(value) {
return (req, res, next) => { return (req, res, next) => {
log.debug(req.query.format); log.debug(req.query.format);
......
...@@ -12,11 +12,11 @@ const city = require('./city'); ...@@ -12,11 +12,11 @@ const city = require('./city');
const school = require('./school'); const school = require('./school');
// API status route
api.get('/api/v1', (req, res) => { api.get('/api/v1', (req, res) => {
res.json({ msg: 'SimCAQ API is running' }); res.json({ msg: 'SimCAQ API is running' });
}); });
// mount API routes
api.use('/api/v1/enrollment', enrollment); api.use('/api/v1/enrollment', enrollment);
api.use('/api/v1/state', state); api.use('/api/v1/state', state);
api.use('/api/v1/region', region); api.use('/api/v1/region', region);
......
...@@ -10,23 +10,27 @@ const query = require(`${libs}/middlewares/query`); ...@@ -10,23 +10,27 @@ const query = require(`${libs}/middlewares/query`);
const response = require(`${libs}/middlewares/response`); const response = require(`${libs}/middlewares/response`);
// Return all cities
cityApp.get('/', (req, res, next) => { cityApp.get('/', (req, res, next) => {
req.sql = squel.select().from('municipios').toParam(); req.sql = squel.select().from('municipios').toParam();
next(); next();
}, query, response('city')); }, query, response('city'));
// Return a specific city by it's id
cityApp.get('/:id', (req, res, next) => { cityApp.get('/:id', (req, res, next) => {
req.sql = squel.select().from('municipios').where('pk_municipio_id = ?', req.sql = squel.select().from('municipios').where('pk_municipio_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
next(); next();
}, query, response('city')); }, query, response('city'));
// Return a specific city by it's IBGE code
cityApp.get('/ibge/:id', (req, res, next) => { cityApp.get('/ibge/:id', (req, res, next) => {
req.sql = squel.select().from('municipios').where('codigo_ibge = ?', req.sql = squel.select().from('municipios').where('codigo_ibge = ?',
req.params.id).toParam(); req.params.id).toParam();
next(); next();
}, query, response('city')); }, query, response('city'));
// Return all the cities from a specific state
cityApp.get('/state/:id', (req, res, next) => { cityApp.get('/state/:id', (req, res, next) => {
req.sql = squel.select().from('municipios').where('fk_estado_id = ?', req.sql = squel.select().from('municipios').where('fk_estado_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
......
...@@ -35,11 +35,8 @@ function filter(req, q) { ...@@ -35,11 +35,8 @@ function filter(req, q) {
} }
} }
/** // Complete range of the enrollments dataset.
* Complete range of the enrollments dataset // Returns a tuple of start and ending years of the complete enrollments dataset.
*
* Returns a tuple of start and ending years of the complete enrollments dataset.
*/
enrollmentApp.get('/year_range', (req, res, next) => { enrollmentApp.get('/year_range', (req, res, next) => {
req.sql = squel.select() req.sql = squel.select()
.from('turmas') .from('turmas')
...@@ -50,10 +47,7 @@ enrollmentApp.get('/year_range', (req, res, next) => { ...@@ -50,10 +47,7 @@ enrollmentApp.get('/year_range', (req, res, next) => {
next(); next();
}, query, response('range')); }, query, response('range'));
/** // Returns all educational levels avaible
* Returns all educational levels avaible
*
*/
enrollmentApp.get('/education_level', (req, res, next) => { enrollmentApp.get('/education_level', (req, res, next) => {
req.sql = squel.select() req.sql = squel.select()
.from('etapa_ensino') .from('etapa_ensino')
...@@ -64,10 +58,7 @@ enrollmentApp.get('/education_level', (req, res, next) => { ...@@ -64,10 +58,7 @@ enrollmentApp.get('/education_level', (req, res, next) => {
next(); next();
}, query, response('education_level')); }, query, response('education_level'));
/** // Returns all adm dependencies
* Returns all adm dependency
*
*/
enrollmentApp.get('/adm_dependency', (req, res, next) => { enrollmentApp.get('/adm_dependency', (req, res, next) => {
req.sql = squel.select() req.sql = squel.select()
.from('dependencia_adms') .from('dependencia_adms')
...@@ -216,27 +207,4 @@ enrollmentApp.get('/', (req, res, next) => { ...@@ -216,27 +207,4 @@ enrollmentApp.get('/', (req, res, next) => {
next(); next();
}, query, response('enrollments')); }, query, response('enrollments'));
// enrollmentApp.get('/', (req, res, next) => {
// log.debug(`Request parameters: ${req}`);
// if (typeof req.sqlQuery === 'undefined') {
// // 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!');
// next('Internal error, request could not be satisfied at this moment. Please, '
// + 'try again later');
// } else {
// log.debug('SQL query: ${ req.sqlQuery }?');
// log.debug(req.sqlQuery);
// dbQuery(req.sqlQuery).then((result) => {
// req.result = result;
// return response(req, res);
// }, (error) => {
// log.error(`[${req.originalUrl}] SQL query error: ${error}`);
// next('Internal error, request could not be satisfied at this moment. Please, '
// + 'try again later');
// });
// }
// });
module.exports = enrollmentApp; module.exports = enrollmentApp;
...@@ -10,11 +10,13 @@ const query = require(`${libs}/middlewares/query`); ...@@ -10,11 +10,13 @@ const query = require(`${libs}/middlewares/query`);
const response = require(`${libs}/middlewares/response`); const response = require(`${libs}/middlewares/response`);
// Get all regions
regionApp.get('/', (req, res, next) => { regionApp.get('/', (req, res, next) => {
req.sql = squel.select().from('regioes').toParam(); req.sql = squel.select().from('regioes').toParam();
next(); next();
}, query, response('region')); }, query, response('region'));
// Get a region by it's id
regionApp.get('/:id', (req, res, next) => { regionApp.get('/:id', (req, res, next) => {
req.sql = squel.select().from('regioes').where('pk_regiao_id = ?', req.sql = squel.select().from('regioes').where('pk_regiao_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
......
...@@ -16,23 +16,26 @@ const response = require(`${libs}/middlewares/response`); ...@@ -16,23 +16,26 @@ const response = require(`${libs}/middlewares/response`);
* A api fica sobrecarregada * 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 * 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) => { /* schoolApp.get('/', (req, res, next) => {
// req.sql = squel.select().from('escolas') * req.sql = squel.select().from('escolas')
// .field('pk_escola_id') * .field('pk_escola_id')
// .field('nome_entidade', 'name') * .field('nome_entidade', 'name')
// .field('ano_censo', 'year') * .field('ano_censo', 'year')
// .field('fk_cod_estado') * .field('fk_cod_estado')
// .field('fk_cod_municipio') * .field('fk_cod_municipio')
// .toParam(); * .toParam();
// next(); * next();
// }, query, response('school')); * }, query, response('school'));
*/
// Get a school by it's id
schoolApp.get('/:id', (req, res, next) => { schoolApp.get('/:id', (req, res, next) => {
req.sql = squel.select().from('escolas').where('pk_escola_id = ?', req.sql = squel.select().from('escolas').where('pk_escola_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
next(); next();
}, query, response('school')); }, query, response('school'));
// Get all schools from a state
schoolApp.get('/state/:id', (req, res, next) => { schoolApp.get('/state/:id', (req, res, next) => {
req.sql = squel.select().from('escolas') req.sql = squel.select().from('escolas')
.field('pk_escola_id') .field('pk_escola_id')
...@@ -46,6 +49,7 @@ schoolApp.get('/state/:id', (req, res, next) => { ...@@ -46,6 +49,7 @@ schoolApp.get('/state/:id', (req, res, next) => {
next(); next();
}, query, response('school')); }, query, response('school'));
// Get all schools from a city
schoolApp.get('/city/:id', (req, res, next) => { schoolApp.get('/city/:id', (req, res, next) => {
req.sql = squel.select().from('escolas') req.sql = squel.select().from('escolas')
.field('pk_escola_id') .field('pk_escola_id')
......
...@@ -10,17 +10,20 @@ const query = require(`${libs}/middlewares/query`); ...@@ -10,17 +10,20 @@ const query = require(`${libs}/middlewares/query`);
const response = require(`${libs}/middlewares/response`); const response = require(`${libs}/middlewares/response`);
// Get all states
stateApp.get('/', (req, res, next) => { stateApp.get('/', (req, res, next) => {
req.sql = squel.select().from('estados').toParam(); req.sql = squel.select().from('estados').toParam();
next(); next();
}, query, response('state')); }, query, response('state'));
// Get a state
stateApp.get('/:id', (req, res, next) => { stateApp.get('/:id', (req, res, next) => {
req.sql = squel.select().from('estados').where('pk_estado_id = ?', req.sql = squel.select().from('estados').where('pk_estado_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
next(); next();
}, query, response('state')); }, query, response('state'));
// Get all states from a region
stateApp.get('/region/:id', (req, res, next) => { stateApp.get('/region/:id', (req, res, next) => {
req.sql = squel.select().from('estados').where('fk_regiao_id = ?', req.sql = squel.select().from('estados').where('fk_regiao_id = ?',
parseInt(req.params.id, 10)).toParam(); parseInt(req.params.id, 10)).toParam();
......
...@@ -8,8 +8,10 @@ const log = require(`${libs}/log`)(module); ...@@ -8,8 +8,10 @@ const log = require(`${libs}/log`)(module);
const app = require(`${libs}/app`); const app = require(`${libs}/app`);
// Set default port: first environment variable PORT, then configuration and last 3000
app.set('port', process.env.PORT || config.get('port') || 3000); app.set('port', process.env.PORT || config.get('port') || 3000);
// Set default ip: first environment variable IOP, then configuration and last '127.0.0.1'
app.set('ip', process.env.IP || config.get('ip') || '127.0.0.1'); app.set('ip', process.env.IP || config.get('ip') || '127.0.0.1');
const server = app.listen(app.get('port'), () => { const server = app.listen(app.get('port'), () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment