js-data-rethinkdb
Advanced tools
Comparing version 3.0.0-alpha.4 to 3.0.0-alpha.5
@@ -0,1 +1,9 @@ | ||
##### 3.0.0-alpha.5 - 27 February 2016 | ||
###### Backwards compatible API changes | ||
- Added ability to override query operators used by RethinkDBAdapter#filterSequence. | ||
###### Other | ||
- Improved JSDoc comments. | ||
##### 3.0.0-alpha.4 - 26 February 2016 | ||
@@ -2,0 +10,0 @@ |
@@ -42,2 +42,3 @@ 'use strict'; | ||
var isUndefined = jsData.utils.isUndefined; | ||
var plainCopy = jsData.utils.plainCopy; | ||
var resolve = jsData.utils.resolve; | ||
@@ -172,3 +173,73 @@ | ||
var equal = function equal(r, row, field, value) { | ||
return row(field).default(null).eq(value); | ||
}; | ||
var notEqual = function notEqual(r, row, field, value) { | ||
return row(field).default(null).ne(value); | ||
}; | ||
/** | ||
* Default predicate functions for the filtering operators. | ||
* | ||
* @name RethinkDBAdapter.OPERATORS | ||
* @property {Function} == Equality operator. | ||
* @property {Function} === Same as `==`. | ||
* @property {Function} != Inequality operator. | ||
* @property {Function} !== Same as `!=`. | ||
* @property {Function} > "Greater than" operator. | ||
* @property {Function} >= "Greater than or equal to" operator. | ||
* @property {Function} < "Less than" operator. | ||
* @property {Function} <= "Less than or equal to" operator. | ||
* @property {Function} isectEmpty Operator to test that the intersection | ||
* between two arrays is empty. | ||
* @property {Function} isectNotEmpty Operator to test that the intersection | ||
* between two arrays is NOT empty. | ||
* @property {Function} in Operator to test whether a value is found in the | ||
* provided array. | ||
* @property {Function} notIn Operator to test whether a value is NOT found in | ||
* the provided array. | ||
* @property {Function} contains Operator to test whether an array contains the | ||
* provided value. | ||
* @property {Function} notContains Operator to test whether an array does NOT | ||
* contain the provided value. | ||
*/ | ||
var OPERATORS = { | ||
'==': equal, | ||
'===': equal, | ||
'!=': notEqual, | ||
'!==': notEqual, | ||
'>': function _(r, row, field, value) { | ||
return row(field).default(null).gt(value); | ||
}, | ||
'>=': function _(r, row, field, value) { | ||
return row(field).default(null).ge(value); | ||
}, | ||
'<': function _(r, row, field, value) { | ||
return row(field).default(null).lt(value); | ||
}, | ||
'<=': function _(r, row, field, value) { | ||
return row(field).default(null).le(value); | ||
}, | ||
'isectEmpty': function isectEmpty(r, row, field, value) { | ||
return row(field).default([]).setIntersection(r.expr(value).default([])).count().eq(0); | ||
}, | ||
'isectNotEmpty': function isectNotEmpty(r, row, field, value) { | ||
return row(field).default([]).setIntersection(r.expr(value).default([])).count().ne(0); | ||
}, | ||
'in': function _in(r, row, field, value) { | ||
return r.expr(value).default(r.expr([])).contains(row(field).default(null)); | ||
}, | ||
'notIn': function notIn(r, row, field, value) { | ||
return r.expr(value).default(r.expr([])).contains(row(field).default(null)).not(); | ||
}, | ||
'contains': function contains(r, row, field, value) { | ||
return row(field).default([]).contains(value); | ||
}, | ||
'notContains': function notContains(r, row, field, value) { | ||
return row(field).default([]).contains(value).not(); | ||
} | ||
}; | ||
/** | ||
* RethinkDBAdapter class. | ||
@@ -202,5 +273,6 @@ * | ||
* @param {number} [opts.min=10] Minimum connections in pool. | ||
* @param {Object} [opts.operators] Override the default predicate functions for | ||
* specified operators. | ||
* @param {number} [opts.port=28015] RethinkDB port. | ||
* @param {boolean} [opts.raw=false] Whether to return detailed result objects | ||
* instead of just record data. | ||
* @param {boolean} [opts.raw=false] Whether to return a more detailed response object. | ||
*/ | ||
@@ -254,2 +326,11 @@ function RethinkDBAdapter(opts) { | ||
/** | ||
* Override the default predicate functions for specified operators. | ||
* | ||
* @name RethinkDBAdapter#operators | ||
* @type {Object} | ||
* @default {} | ||
*/ | ||
self.operators || (self.operators = {}); | ||
/** | ||
* The rethinkdbdash instance used by this adapter. Use this directly when you | ||
@@ -402,82 +483,75 @@ * need to write custom queries. | ||
}, | ||
filterSequence: function filterSequence(sequence, params) { | ||
var r = this.r; | ||
params = params || {}; | ||
params.where = params.where || {}; | ||
params.orderBy = params.orderBy || params.sort; | ||
params.skip = params.skip || params.offset; | ||
Object.keys(params).forEach(function (k) { | ||
var v = params[k]; | ||
if (reserved.indexOf(k) === -1) { | ||
if (isObject(v)) { | ||
params.where[k] = v; | ||
/** | ||
* Apply the specified selection query to the provided RQL sequence. | ||
* | ||
* @name RethinkDBAdapter#filterSequence | ||
* @method | ||
* @param {Object} mapper The mapper. | ||
* @param {Object} [query] Selection query. | ||
* @param {Object} [query.where] Filtering criteria. | ||
* @param {string|Array} [query.orderBy] Sorting criteria. | ||
* @param {string|Array} [query.sort] Same as `query.sort`. | ||
* @param {number} [query.limit] Limit results. | ||
* @param {number} [query.skip] Offset results. | ||
* @param {number} [query.offset] Same as `query.skip`. | ||
* @param {Object} [opts] Configuration options. | ||
* @param {Object} [opts.operators] Override the default predicate functions | ||
* for specified operators. | ||
*/ | ||
filterSequence: function filterSequence(sequence, query, opts) { | ||
var self = this; | ||
var r = self.r; | ||
query = plainCopy(query || {}); | ||
opts || (opts = {}); | ||
opts.operators || (opts.operators = {}); | ||
query.where || (query.where = {}); | ||
query.orderBy || (query.orderBy = query.sort); | ||
query.orderBy || (query.orderBy = []); | ||
query.skip || (query.skip = query.offset); | ||
// Transform non-keyword properties to "where" clause configuration | ||
forOwn(query, function (config, keyword) { | ||
if (reserved.indexOf(keyword) === -1) { | ||
if (isObject(config)) { | ||
query.where[keyword] = config; | ||
} else { | ||
params.where[k] = { | ||
'==': v | ||
query.where[keyword] = { | ||
'==': config | ||
}; | ||
} | ||
delete params[k]; | ||
delete query[keyword]; | ||
} | ||
}); | ||
var query = sequence; | ||
var rql = sequence; | ||
if (Object.keys(params.where).length !== 0) { | ||
query = query.filter(function (row) { | ||
// Filter | ||
if (Object.keys(query.where).length !== 0) { | ||
// Filter sequence using filter function | ||
rql = rql.filter(function (row) { | ||
var subQuery = undefined; | ||
forOwn(params.where, function (criteria, field) { | ||
// Apply filter for each field | ||
forOwn(query.where, function (criteria, field) { | ||
if (!isObject(criteria)) { | ||
criteria = { '==': criteria }; | ||
} | ||
forOwn(criteria, function (v, op) { | ||
if (op === '==' || op === '===') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).eq(v)) : row(field).default(null).eq(v); | ||
} else if (op === '!=' || op === '!==') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).ne(v)) : row(field).default(null).ne(v); | ||
} else if (op === '>') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).gt(v)) : row(field).default(null).gt(v); | ||
} else if (op === '>=') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).ge(v)) : row(field).default(null).ge(v); | ||
} else if (op === '<') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).lt(v)) : row(field).default(null).lt(v); | ||
} else if (op === '<=') { | ||
subQuery = subQuery ? subQuery.and(row(field).default(null).le(v)) : row(field).default(null).le(v); | ||
} else if (op === 'isectEmpty') { | ||
subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0); | ||
} else if (op === 'isectNotEmpty') { | ||
subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0); | ||
} else if (op === 'in') { | ||
subQuery = subQuery ? subQuery.and(r.expr(v).default(r.expr([])).contains(row(field).default(null))) : r.expr(v).default(r.expr([])).contains(row(field).default(null)); | ||
} else if (op === 'notIn') { | ||
subQuery = subQuery ? subQuery.and(r.expr(v).default(r.expr([])).contains(row(field).default(null)).not()) : r.expr(v).default(r.expr([])).contains(row(field).default(null)).not(); | ||
} else if (op === 'contains') { | ||
subQuery = subQuery ? subQuery.and(row(field).default([]).contains(v)) : row(field).default([]).contains(v); | ||
} else if (op === 'notContains') { | ||
subQuery = subQuery ? subQuery.and(row(field).default([]).contains(v).not()) : row(field).default([]).contains(v).not(); | ||
} else if (op === '|==' || op === '|===') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).eq(v)) : row(field).default(null).eq(v); | ||
} else if (op === '|!=' || op === '|!==') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).ne(v)) : row(field).default(null).ne(v); | ||
} else if (op === '|>') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).gt(v)) : row(field).default(null).gt(v); | ||
} else if (op === '|>=') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).ge(v)) : row(field).default(null).ge(v); | ||
} else if (op === '|<') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).lt(v)) : row(field).default(null).lt(v); | ||
} else if (op === '|<=') { | ||
subQuery = subQuery ? subQuery.or(row(field).default(null).le(v)) : row(field).default(null).le(v); | ||
} else if (op === '|isectEmpty') { | ||
subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0); | ||
} else if (op === '|isectNotEmpty') { | ||
subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0); | ||
} else if (op === '|in') { | ||
subQuery = subQuery ? subQuery.or(r.expr(v).default(r.expr([])).contains(row(field).default(null))) : r.expr(v).default(r.expr([])).contains(row(field).default(null)); | ||
} else if (op === '|notIn') { | ||
subQuery = subQuery ? subQuery.or(r.expr(v).default(r.expr([])).contains(row(field).default(null)).not()) : r.expr(v).default(r.expr([])).contains(row(field).default(null)).not(); | ||
} else if (op === '|contains') { | ||
subQuery = subQuery ? subQuery.or(row(field).default([]).contains(v)) : row(field).default([]).contains(v); | ||
} else if (op === '|notContains') { | ||
subQuery = subQuery ? subQuery.or(row(field).default([]).contains(v).not()) : row(field).default([]).contains(v).not(); | ||
// Apply filter for each operator | ||
forOwn(criteria, function (value, operator) { | ||
var isOr = false; | ||
if (operator && operator[0] === '|') { | ||
operator = operator.substr(1); | ||
isOr = true; | ||
} | ||
var predicateFn = self.getOperator(operator, opts); | ||
if (predicateFn) { | ||
var predicateResult = predicateFn(r, row, field, value); | ||
if (isOr) { | ||
subQuery = subQuery ? subQuery.or(predicateResult) : predicateResult; | ||
} else { | ||
subQuery = subQuery ? subQuery.and(predicateResult) : predicateResult; | ||
} | ||
} | ||
}); | ||
@@ -489,23 +563,26 @@ }); | ||
if (params.orderBy) { | ||
if (isString(params.orderBy)) { | ||
params.orderBy = [[params.orderBy, 'asc']]; | ||
// Sort | ||
if (query.orderBy) { | ||
if (isString(query.orderBy)) { | ||
query.orderBy = [[query.orderBy, 'asc']]; | ||
} | ||
for (var i = 0; i < params.orderBy.length; i++) { | ||
if (isString(params.orderBy[i])) { | ||
params.orderBy[i] = [params.orderBy[i], 'asc']; | ||
for (var i = 0; i < query.orderBy.length; i++) { | ||
if (isString(query.orderBy[i])) { | ||
query.orderBy[i] = [query.orderBy[i], 'asc']; | ||
} | ||
query = (params.orderBy[i][1] || '').toUpperCase() === 'DESC' ? query.orderBy(r.desc(params.orderBy[i][0])) : query.orderBy(params.orderBy[i][0]); | ||
rql = (query.orderBy[i][1] || '').toUpperCase() === 'DESC' ? rql.orderBy(r.desc(query.orderBy[i][0])) : rql.orderBy(query.orderBy[i][0]); | ||
} | ||
} | ||
if (params.skip) { | ||
query = query.skip(+params.skip); | ||
// Offset | ||
if (query.skip) { | ||
rql = rql.skip(+query.skip); | ||
} | ||
if (params.limit) { | ||
query = query.limit(+params.limit); | ||
// Limit | ||
if (query.limit) { | ||
rql = rql.limit(+query.limit); | ||
} | ||
return query; | ||
return rql; | ||
}, | ||
@@ -674,4 +751,12 @@ waitForDb: function waitForDb(opts) { | ||
* @param {Object} [query] Selection query. | ||
* @param {Object} [query.where] Filtering criteria. | ||
* @param {string|Array} [query.orderBy] Sorting criteria. | ||
* @param {string|Array} [query.sort] Same as `query.sort`. | ||
* @param {number} [query.limit] Limit results. | ||
* @param {number} [query.skip] Offset results. | ||
* @param {number} [query.offset] Same as `query.skip`. | ||
* @param {Object} [opts] Configuration options. | ||
* @param {Object} [opts.deleteOpts] Options to pass to r#delete. | ||
* @param {Object} [opts.operators] Override the default predicate functions | ||
* for specified operators. | ||
* @param {boolean} [opts.raw=false] Whether to return a more detailed | ||
@@ -965,4 +1050,12 @@ * response object. | ||
* @param {Object} mapper The mapper. | ||
* @param {Object} query Selection query. | ||
* @param {Object} [query] Selection query. | ||
* @param {Object} [query.where] Filtering criteria. | ||
* @param {string|Array} [query.orderBy] Sorting criteria. | ||
* @param {string|Array} [query.sort] Same as `query.sort`. | ||
* @param {number} [query.limit] Limit results. | ||
* @param {number} [query.skip] Offset results. | ||
* @param {number} [query.offset] Same as `query.skip`. | ||
* @param {Object} [opts] Configuration options. | ||
* @param {Object} [opts.operators] Override the default predicate functions | ||
* for specified operators. | ||
* @param {boolean} [opts.raw=false] Whether to return a more detailed | ||
@@ -1093,2 +1186,22 @@ * response object. | ||
/** | ||
* Resolve the predicate function for the specified operator based on the | ||
* given options and this adapter's settings. | ||
* | ||
* @name RethinkDBAdapter#getOperator | ||
* @method | ||
* @param {string} operator The name of the operator. | ||
* @param {Object} [opts] Configuration options. | ||
* @param {Object} [opts.operators] Override the default predicate functions | ||
* for specified operators. | ||
* @return {*} The predicate function for the specified operator. | ||
*/ | ||
getOperator: function getOperator(operator, opts) { | ||
opts || (opts = {}); | ||
opts.operators || (opts.operators = {}); | ||
var ownOps = this.operators || {}; | ||
return isUndefined(opts.operators[operator]) ? ownOps[operator] || OPERATORS[operator] : opts.operators[operator]; | ||
}, | ||
/** | ||
* Resolve the value of the specified option based on the given options and | ||
@@ -1105,3 +1218,3 @@ * this adapter's settings. | ||
opts || (opts = {}); | ||
return isUndefined(opts[opt]) ? this[opt] : opts[opt]; | ||
return isUndefined(opts[opt]) ? plainCopy(this[opt]) : plainCopy(opts[opt]); | ||
}, | ||
@@ -1204,7 +1317,15 @@ | ||
* @param {Object} [query] Selection query. | ||
* @param {Object} [query.where] Filtering criteria. | ||
* @param {string|Array} [query.orderBy] Sorting criteria. | ||
* @param {string|Array} [query.sort] Same as `query.sort`. | ||
* @param {number} [query.limit] Limit results. | ||
* @param {number} [query.skip] Offset results. | ||
* @param {number} [query.offset] Same as `query.skip`. | ||
* @param {Object} [opts] Configuration options. | ||
* @param {Object} [opts.updateOpts] Options to pass to r#update. | ||
* @param {Object} [opts.operators] Override the default predicate functions | ||
* for specified operators. | ||
* @param {boolean} [opts.raw=false] Whether to return a more detailed | ||
* response object. | ||
* @param {Object} [opts.runOpts] Options to pass to r#run. | ||
* @param {Object} [opts.updateOpts] Options to pass to r#update. | ||
* @return {Promise} | ||
@@ -1344,3 +1465,5 @@ */ | ||
RethinkDBAdapter.OPERATORS = OPERATORS; | ||
module.exports = RethinkDBAdapter; | ||
//# sourceMappingURL=js-data-rethinkdb.js.map |
{ | ||
"name": "js-data-rethinkdb", | ||
"description": "RethinkDB adapter for js-data.", | ||
"version": "3.0.0-alpha.4", | ||
"version": "3.0.0-alpha.5", | ||
"homepage": "https://github.com/js-data/js-data-rethinkdb", | ||
@@ -61,3 +61,3 @@ "repository": { | ||
"coveralls": "2.11.8", | ||
"ink-docstrap": "1.1.2", | ||
"ink-docstrap": "1.1.3", | ||
"istanbul": "0.4.2", | ||
@@ -64,0 +64,0 @@ "js-data-adapter-tests": "^2.0.0-alpha.9", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
135519
1412