pg-promise为select查询创build自定义filter

我正在工作的function是获取有7个不同的键值的input对象,他们每个可能是未定义或不。 我想根据input中存在的键值过滤我的数据库。 例如,如果只有input.userID存在我想运行这个查询:

 db.query("...WHERE userID = ${userID}", {userID: input.userID}); 

否则,如果input.userID和input.startTime都存在,我想这样做:

 db.query("...WHERE userID = ${userID} and startTime= ${startTime}", {userID: input.userID, startTime: input.startTime}); 

我所做的是我创build了一个params和keys对象,像这样:

 if(input.userID) { keys.push('userID'); params.push(input.userID); query = addFilterToTheQuery(query, 'userID', input.userID, filteredItemsCount); filteredItemsCount = filteredItemsCount +1; } 

addFilterToTheQuery是一个我自己实现的简单函数。 我基本上做了7个,如果情况。 然后,我必须使用这些键和参数值以可能需要另一个巨大的开关大小写代码的方式传递给查询函数。

这是唯一的方法来做到这一点? 有没有更好的方法来摆脱这个代码中的冗余?

自定义types格式是最适合的。

例如,如果我们想要使用属性转换对象 – 过滤值,我们可以这样做:

 var pgp = require('pg-promise')(/* initialization options */); function FilterSet(filters) { if (!filters || typeof filters !== 'object') { throw new TypeError('Parameter \'filters\' must be an object.'); } this._rawDBType = true; this.formatDBType = function () { var keys = Object.keys(filters); var s = keys.map(function (k) { return pgp.as.name(k) + ' = ${' + k + '}'; }).join(' AND '); return pgp.as.format(s, filters); }; } 

testing

 var filter = new FilterSet({ first: 1, second: 'two' }); var test = pgp.as.format('WHERE $1', filter); console.log(test); 

这输出:

 WHERE "first" = 1 AND "second" = 'two' 

如果您的filter被用作LIKEILIKE %value% ,那么您需要相应地更改自定义types。

见相关问题: 42,49,89,90 ,

UPDATE

下面是为最新的pg-promise (版本6.5.0或更新)重写的例子:

 const pgp = require('pg-promise')(/* initialization options */); class FilterSet { constructor(filters) { if (!filters || typeof filters !== 'object') { throw new TypeError('Parameter \'filters\' must be an object.'); } this.filters = filters; this._rawType = true; // do not escape the result from toPostgres() } toPostgres(/*self*/) { // self = this const keys = Object.keys(this.filters); const s = keys.map(k => pgp.as.name(k) + ' = ${' + k + '}').join(' AND '); return pgp.as.format(s, this.filters); } } 

请参阅自定义types格式 。