Knex Query build - 动态构建链

Knex Query build - build chain dynamically

我已经将 node-DBI 换成了 knex,因为它具有我需要的更多功能。

到目前为止,我会再次做出相同的选择,但只有一件事阻碍了我:编写采用选项变量的抽象方法,其中包含 where、innerjoin 等参数。

使用 node-dbi 我可以很容易地使用这些变量伪造一个字符串,但我似乎无法动态地创建 knex 链,因为在使用开关后,你会得到 knex.method is not a function。

知道如何解决这个问题吗?

我正在寻找

中的内容
`getData(table,options){
 var knex=knex
   if(options.select)
   /** append the select data using knex.select()
   if(options.where)
   /** append the where data using knex.where(data)*/
   if(options.innerJoin)
   /** append innerjoin data*/
}`

这样我就可以避免编写大量的数据库函数并让我的业务逻辑层处理请求

/*This function serves as the core of our DB layer
This will generate a SQL query and execute it whilest returning the response prematurely
@param obj:{Object} this is the options object that contain all of the query options
@return Promise{Object}: returns a promise that will be reject or resolved based on the outcome of the query
The reasoning behind this kind of logic is that we want to abstract our layer as much as possible, if evne the slightest 
sytnax change occurs in the near future, we can easily update all our code by updating this one
We are using knex as a query builder and are thus relying on Knex to communicate with our DB*/
/*Can also be used to build custom query functions from a data.service. This way our database service will remain
unpolluted from many different functions and logic will be contained in a BLL*/
/* All available options
var options = {
    table:'table',
    where:{operand:'=',value:'value',valueToEqual:'val2'},
    andWhere:[{operand:'=',value:'value',valueToEqual:'val2'}],
    orWhere:[{operand:'=',value:'value',valueToEqual:'val2'}],
    select:{value:['*']},
    insert:{data:{}},
    innerJoin:[{table:'tableName',value:'value',valueToEqual:'val2'}],
    update:{data:{}}
}*/
/*Test object*/
/*var testobj = {
    table:'advantage',
    where:{operand:'>',value:'id',valueToEqual:'3'},
    select:{value:['*']},
    innerJoin:{table:'User_Advantage',value:'User_Advantage.Advantageid',valueToEqual:'id'}
}
var testobj = {
    table:'advantage',
    where:{operand:'>',value:'id',valueToEqual:'3'},
    select:{value:['*']},
    innerJoin:{table:'User_Advantage',value:'User_Advantage.Advantageid',valueToEqual:'id'}
}
queryBuilder(testobj)*/
function queryBuilder(options){
 var promise = new Promise(function (resolve, reject) {
    var query;
    for (var prop in options) {
        /*logger.info(prop)*/
        if (options.hasOwnProperty(prop)) {
            switch (prop) {
                case 'table':
                query = knex(options[prop]);
                break;
                case 'where':
                query[prop](options[prop].value, options[prop].operand, options[prop].valueToEqual);
                break;
                /*andWhere and orWhere share the same syntax*/
                case 'andWhere':
                case 'orWhere': 
                for(let i=0, len=options[prop].length;i<len;i++){
                    query[prop](options[prop][i].value, options[prop][i].operand, options[prop][i].valueToEqual);
                }
                break;
                case 'select':
                query[prop](options[prop].value);
                break;
                /*Same syntax for update and insert -- switch fallthrough*/
                case 'insert':
                case 'update':
                query[prop](options[prop].data);
                break;
                case 'innerJoin':
                for(let i=0, len=options[prop].length;i<len;i++){
                    query[prop](options[prop][i].table, options[prop][i].value, options[prop][i].valueToEqual);
                }
                break;
            }
        }
    }
    return query
    .then(function (res) {
        return resolve(res);
    }, function (error) {
        logger.error(error)
        return reject(error);
    })
    return reject('Options wrongly formatted');
});
 return promise
}

多亏了 Molda,我才能够生成上面的代码。这个将一个名为 options in 的对象作为参数,并将基于该值构建 knex 链。 Object的语法见注释 并非每个 knex 查询选项都包含在内,但这将为任何试图实现类似效果的人提供良好的基础。

使用这个的一些例子:

/*Will return all values from a certain table
@param: table{String}: string of the table to query
@param: select{Array[String]}: Array of strings of columns to be select -- defaults to ['*'] */
function getAll(table,select) {
    /*Select * from table as default*/
    var selectVal=select||['*']
    var options={
        table:table,
        select:{value:selectVal}
    }
    return queryBuilder(options)
}

或更具体的用例:

function getUserAdvantages(userid){
    var options = {
        table:'advantage',
        innerJoin:[{table:TABLE,value:'advantage.id',valueToEqual:'user_advantage.Advantageid'}],
        where:{operand:'=',value:'user_advantage.Userid',valueToEqual:userid}
    }
    return sqlService.queryBuilder(options)
}

注意:sqlService 是我导出的包含 queryBUilder 方法的节点模块。

编辑:我想补充一点,我遇到的唯一障碍是使用 Knex 的 .from / .insert。我不再使用这些方法,因为它们在使用时会导致错误。正如评论的那样,我使用了 knex(table) 。