3

私が取り組んでいる関数は、7 つの異なるキー値を持つ入力オブジェクトを取得することであり、それぞれが未定義であるかどうかにかかわらず可能性があります。入力に存在するキー値に基づいてデータベースをフィルタリングしたいと考えています。たとえば、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});

私が行ったことは、次のような params と keys オブジェクトを作成したことです。

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

addFilterToTheQuery私が自分で実装した単純な機能です。私は基本的にifケースを7つ作ります。次に、これらのキーとパラメーター値を使用して、別の巨大なスイッチ ケース コードが必要になる可能性がある方法でクエリ関数に渡す必要があります。

これがこれを行う唯一の方法ですか?このコードの冗長性を取り除くより良い方法はありますか?

4

1 に答える 1

5

ここでは、カスタム タイプの書式設定が最適です。

たとえば、プロパティ (フィルター値) を持つオブジェクトを変換する場合は、次のようにします。

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; // property renamed later - see UPDATE below
    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);
    };
}

テスト

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'

フィルタ%value%LIKEまたはと同様に使用する場合ILIKEは、それに応じてカスタム タイプを変更する必要があります。

関連する質問を参照してください: 42498990

アップデート

以下は、最新のpg-promise (バージョン 8.x 以降)用に書き直された同じ例です。

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);
    }
}

カスタム タイプの書式設定を参照してください。

于 2016-03-03T20:06:45.407 に答える