2016-05-13 124 views
0

我已經爲knex交易了節點DBI,因爲它具有我需要的更多功能。 到目前爲止,我會再次做出同樣的選擇,但只有一件事情讓我失望:編寫抽象方法,其中包含像params這樣的參數,innerjoin等參數。 使用node-dbi我可以很容易地僞造字符串使用這些變量,但我似乎無法動態地創建knex鏈,因爲使用開關後,你會得到knex.method不是一個函數。Knex查詢構建 - 動態構建鏈

任何想法如何解決這個問題?

我在尋找的東西,如

`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*/ 
}` 

這樣我可不必寫很多的DB功能,讓我的業務邏輯層次韓德爾的要求

+0

我不知道我的理解是否正確,但我相信你可以做類似'var query = knex('users_table');如果(options.select)query.select(...)' – Molda

+0

我會測試併發布結果。謝謝你的回覆。 –

回答

-1
/*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的對象作爲參數,並將根據此值構建knex鏈。查看對象 的語法註釋並非每個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(表)作爲評論。

+0

另請注意,訂單非常重要。就像在SQL中一樣,你的表和連接應該是第一位的! –