From da23daa7ba10b6e907c720326bbd294cb4577521 Mon Sep 17 00:00:00 2001 From: Vytor Calixto <vytorcalixto@gmail.com> Date: Fri, 27 Jan 2017 09:20:08 -0200 Subject: [PATCH] [ci skip] :memo: Update comments in reqQueryFields --- src/libs/middlewares/reqQueryFields.js | 80 ++++++++++++++++++++------ 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/src/libs/middlewares/reqQueryFields.js b/src/libs/middlewares/reqQueryFields.js index 741ae09a..ab82a69f 100644 --- a/src/libs/middlewares/reqQueryFields.js +++ b/src/libs/middlewares/reqQueryFields.js @@ -6,13 +6,38 @@ const _ = require('lodash'); class ReqQueryFields { constructor(fields = {}, fieldValues = {}) { + // Exemplo de requisição: `/api/v1/enrollments?dims=state,region,location` + // Parâmetros no campo query da requisição. // Exemplo de field: + // ```js // { // name: 'dims', // field: true, // where: false // } + // ``` + // Array de valores aceitos pelo campo. + // Exemplo de valor: + // ``` + // { + // name: 'location', + // table: 'localizacao', + // tableField: 'descricao' + // resultField: 'location_name', + // where: { + // relation: '=', + // type: 'integer', + // field: 'id_localizacao', + // table: 'turma' + // }, + // join: { + // primary: 'pk_localizacao_id', + // foreign: 'id_localizacao', + // foreignTable: 'turma' + // } + // } + // ``` this.fields = fields; this.fieldValues = fieldValues; } @@ -20,12 +45,14 @@ class ReqQueryFields { addField(field) { // Parâmetro no campo query da requisição. // Exemplo de field: + // ``` // { // name: 'dims', // field: true, // where: false, // fieldValues: {} // } + // ``` if(typeof this.fields[field.name] === 'undefined') { log.debug("added field "+field.name); this.fields[field.name] = field; @@ -34,8 +61,9 @@ class ReqQueryFields { } addValue(fieldValue) { - // Array de valores aceitos pelo campo + // Valor aceito por **todos** os campos. // Exemplo de valor: + // ``` // { // name: 'location', // table: 'localizacao', @@ -53,7 +81,7 @@ class ReqQueryFields { // foreignTable: 'turma' // } // } - + // ``` if(typeof this.fieldValues[fieldValue.name] === 'undefined') { this.fieldValues[fieldValue.name] = fieldValue; log.debug("added value "+fieldValue.name); @@ -62,7 +90,9 @@ class ReqQueryFields { } addValueToField(fieldValue, field) { + // Valor aceito **apenas** pelo campo `field`. if(typeof this.fields[field] === 'undefined') { + // Se o campo não existe, lança uma exception throw 'No field with name ' +field+ ' defined'; } if(typeof this.fields[field].values === 'undefined') { @@ -76,47 +106,56 @@ class ReqQueryFields { } parse() { + // Faz o parse dos valores que vem na requisição para objetos. return (req, res, next) => { + // "Foreach" nos campos aceitos Object.keys(this.fields).map((key, index) => { let params = []; + // f é o campo let f = this.fields[key]; log.debug('f'); log.debug(f); - // Unimos os valores aceitos globalmente com os aceitos apenas pelo parâmetro + // Unimos os valores parametros globalmente com os aceitos apenas pelo campo let values = _.merge(this.fieldValues, f.values); + // Fazemos um foreach nos parametros aceitos Object.keys(values).map((k, i) => { let value = values[k]; log.debug('value'); log.debug(value); + // Pushamos o parametro params.push(value.name); }); let queryField = f.name; let arrayOfParams = params; + // Criamos o atributo com o nome do **campo** no objeto `req` (nome do campo é 'filter', 'dims', 'search', etc) req[queryField] = {}; if (req.query[queryField]) { + // Se há mais de um parametro no campo, eles estão separados por vÃrgula. + // Fazemos o split então para separar os valores const params = req.query[queryField].split(','); - // Temporary object to hold the params and it's values + // Objeto temporário para guardar os parametros e seus valores. const obj = {}; for (const param of params) { - // Get the key and the value - state:41 is key 'state' whith value 41. - // kv is then an array [key, value] or [key] if there is no value + // O parametro *pode* ter um valor (por exemplo: `state:41`). + // Fazemos o split e temos um array `['state', 41]` const kv = param.split(':'); - // Check if there is a value. If there isn't, assign true + // Checa se há um valor. Se não tem, definimos como true. obj[kv[0]] = (typeof kv[1] === 'undefined') ? true : kv[1]; - // obj is now an object {kv[0]: kv[1]} ou {kv[0]: true} + // `obj` é agora `{kv[0]: kv[1]}` ou `{kv[0]: true}`. + // No exemplo `{'state': 41}` } - // If the array exists and is not empty we intersect + // Se o array existe e não está vazio fazemos a interseção if (typeof arrayOfParams !== 'undefined' && arrayOfParams.length > 0) { - // Intersect the keys of the obj with the array arrayOfParams - // The intersection array is assigned with the keys + // Fazemos a interseção das chaves de `obj` com o array `arrayOfParams`. + // O array resultante são as chaves aceitas pelo campo. const intersection = _.intersection(arrayOfParams, Object.keys(obj)); - // This is a bit tricky... - // For each key in the intersection array we get it's value in the obj - // and assign it to the custom attribute in the req obj. - // For example: instersection => ["state"] so - // obj[intersection[i]] (with i=0) is obj["state"], that is 41 - // and req[queryField]["state"] = 41 + // Isso é um pouco complicado... + // Para cada chave na interseção pegamos seu valor em `obj` + // e atribuÃmos para o atributo que definimos no objeto `req`. + // Por exemplo: intersection = `['state']` então + // `obj[intersection[i]]` (com i=0) é `obj['state']`, cujo valor é 41. + // Então fazemos `req[queryField]['state'] = 41` for (let i = 0; i < intersection.length; ++i) { req[queryField][intersection[i]] = obj[intersection[i]]; } @@ -132,13 +171,18 @@ class ReqQueryFields { } build() { + // "Constrói" o SQL return (req, res, next) => { + // Foreach no campos Object.keys(this.fields).map((key, index) => { + // Campo let field = this.fields[key]; log.debug(field); + // `param` aqui é o atributo no objeto `req` (dims, filter, search, ...) let param = req[field.name]; log.debug('param'); log.debug(param); + // Fazemos um foreach nos parametros dentro do atributo Object.keys(param).map((k, i) => { let values = _.merge(this.fieldValues, field.values); log.debug('ValueS'); @@ -146,7 +190,7 @@ class ReqQueryFields { log.debug('k'); log.debug(k); if(typeof values[k] !== 'undefined') { - // Clonamos para não alterar + // Clonamos para não alterar o original let value = _.clone(values[k]); log.debug(value); // Checa se não fizemos o join para este valor e se é necessário fazer -- GitLab