js-data-rethinkdb
Version:
RethinkDB adapter for js-data.
1,197 lines (1,081 loc) • 39.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var jsData = require('js-data');
var jsDataAdapter = require('js-data-adapter');
var rethinkdbdash = _interopDefault(require('rethinkdbdash'));
var snakeCase = _interopDefault(require('lodash.snakecase'));
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
var __super__ = jsDataAdapter.Adapter.prototype;
var R_OPTS_DEFAULTS = {
db: 'test'
};
var INSERT_OPTS_DEFAULTS = {};
var UPDATE_OPTS_DEFAULTS = {};
var DELETE_OPTS_DEFAULTS = {};
var RUN_OPTS_DEFAULTS = {};
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 module:js-data-rethinkdb.OPERATORS
* @property {function} = Equality operator.
* @property {function} == Equality operator.
* @property {function} != Inequality operator.
* @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,
'===': 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();
}
};
Object.freeze(OPERATORS);
/**
* RethinkDBAdapter class.
*
* @example
* // Use Container instead of DataStore on the server
* import { Container } from 'js-data';
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
*
* // Create a store to hold your Mappers
* const store = new Container();
*
* // Create an instance of RethinkDBAdapter with default settings
* const adapter = new RethinkDBAdapter();
*
* // Mappers in "store" will use the RethinkDB adapter by default
* store.registerAdapter('rethinkdb', adapter, { default: true });
*
* // Create a Mapper that maps to a "user" table
* store.defineMapper('user');
*
* @class RethinkDBAdapter
* @extends Adapter
* @param {object} [opts] Configuration options.
* @param {boolean} [opts.debug=false] See {@link Adapter#debug}.
* @param {object} [opts.deleteOpts={}] See {@link RethinkDBAdapter#deleteOpts}.
* @param {object} [opts.insertOpts={}] See {@link RethinkDBAdapter#insertOpts}.
* @param {object} [opts.operators={@link module:js-data-rethinkdb.OPERATORS}] See {@link RethinkDBAdapter#operators}.
* @param {object} [opts.r] See {@link RethinkDBAdapter#r}.
* @param {boolean} [opts.raw=false] See {@link Adapter#raw}.
* @param {object} [opts.rOpts={}] See {@link RethinkDBAdapter#rOpts}.
* @param {object} [opts.runOpts={}] See {@link RethinkDBAdapter#runOpts}.
* @param {object} [opts.updateOpts={}] See {@link RethinkDBAdapter#updateOpts}.
*/
function RethinkDBAdapter(opts) {
jsData.utils.classCallCheck(this, RethinkDBAdapter);
opts || (opts = {});
// Setup non-enumerable properties
Object.defineProperties(this, {
/**
* The rethinkdbdash instance used by this adapter. Use this directly when
* you need to write custom queries.
*
* @example <caption>Use default instance.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter();
* adapter.r.dbDrop('foo').then(...);
*
* @example <caption>Configure default instance.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter({
* rOpts: {
* user: 'myUser',
* password: 'myPassword'
* }
* });
* adapter.r.dbDrop('foo').then(...);
*
* @example <caption>Provide a custom instance.</caption>
* import rethinkdbdash from 'rethinkdbdash';
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const r = rethinkdbdash();
* const adapter = new RethinkDBAdapter({
* r: r
* });
* adapter.r.dbDrop('foo').then(...);
*
* @name RethinkDBAdapter#r
* @type {object}
*/
r: {
writable: true,
value: undefined
},
databases: {
value: {}
},
indices: {
value: {}
},
tables: {
value: {}
}
});
jsDataAdapter.Adapter.call(this, opts);
/**
* Default options to pass to r#insert.
*
* @name RethinkDBAdapter#insertOpts
* @type {object}
* @default {}
*/
this.insertOpts || (this.insertOpts = {});
jsData.utils.fillIn(this.insertOpts, INSERT_OPTS_DEFAULTS);
/**
* Default options to pass to r#update.
*
* @name RethinkDBAdapter#updateOpts
* @type {object}
* @default {}
*/
this.updateOpts || (this.updateOpts = {});
jsData.utils.fillIn(this.updateOpts, UPDATE_OPTS_DEFAULTS);
/**
* Default options to pass to r#delete.
*
* @name RethinkDBAdapter#deleteOpts
* @type {object}
* @default {}
*/
this.deleteOpts || (this.deleteOpts = {});
jsData.utils.fillIn(this.deleteOpts, DELETE_OPTS_DEFAULTS);
/**
* Default options to pass to r#run.
*
* @name RethinkDBAdapter#runOpts
* @type {object}
* @default {}
*/
this.runOpts || (this.runOpts = {});
jsData.utils.fillIn(this.runOpts, RUN_OPTS_DEFAULTS);
/**
* Override the default predicate functions for the specified operators.
*
* @name RethinkDBAdapter#operators
* @type {object}
* @default {}
*/
this.operators || (this.operators = {});
jsData.utils.fillIn(this.operators, OPERATORS);
/**
* Options to pass to a new `rethinkdbdash` instance, if one was not provided
* at {@link RethinkDBAdapter#r}. See the [rethinkdbdash README][readme] for
* instance options.
*
* [readme]: https://github.com/neumino/rethinkdbdash#importing-the-driver
*
* @example <caption>Connect to localhost:8080, and let the driver find other instances.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter({
* rOpts: {
* discovery: true
* }
* });
*
* @example <caption>Connect to and only to localhost:8080.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter();
*
* @example <caption>Do not create a connection pool.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter({
* rOpts: {
* pool: false
* }
* });
*
* @example <caption>Connect to a cluster seeding from `192.168.0.100`, `192.168.0.101`, `192.168.0.102`.</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter({
* rOpts: {
* servers: [
* { host: '192.168.0.100', port: 28015 },
* { host: '192.168.0.101', port: 28015 },
* { host: '192.168.0.102', port: 28015 }
* ]
* }
* });
*
* @name RethinkDBAdapter#rOpts
* @see https://github.com/neumino/rethinkdbdash#importing-the-driver
* @type {object}
*/
this.rOpts || (this.rOpts = {});
jsData.utils.fillIn(this.rOpts, R_OPTS_DEFAULTS);
this.r || (this.r = rethinkdbdash(this.rOpts));
}
jsDataAdapter.Adapter.extend({
constructor: RethinkDBAdapter,
_handleErrors: function _handleErrors(cursor) {
if (cursor && cursor.errors > 0) {
if (cursor.first_error) {
throw new Error(cursor.first_error);
}
throw new Error('Unknown RethinkDB Error');
}
},
_count: function _count(mapper, query, opts) {
opts || (opts = {});
query || (query = {});
return this.filterSequence(this.selectTable(mapper, opts), query).count().run(this.getOpt('runOpts', opts)).then(function (count) {
return [count, {}];
});
},
_create: function _create(mapper, props, opts) {
var _this = this;
props || (props = {});
opts || (opts = {});
var insertOpts = this.getOpt('insertOpts', opts);
insertOpts.returnChanges = true;
return this.selectTable(mapper, opts).insert(props, insertOpts).run(this.getOpt('runOpts', opts)).then(function (cursor) {
_this._handleErrors(cursor);
var record = void 0;
if (cursor && cursor.changes && cursor.changes.length && cursor.changes[0].new_val) {
record = cursor.changes[0].new_val;
}
return [record, cursor];
});
},
_createMany: function _createMany(mapper, props, opts) {
var _this2 = this;
props || (props = {});
opts || (opts = {});
var insertOpts = this.getOpt('insertOpts', opts);
insertOpts.returnChanges = true;
return this.selectTable(mapper, opts).insert(props, insertOpts).run(this.getOpt('runOpts', opts)).then(function (cursor) {
_this2._handleErrors(cursor);
var records = [];
if (cursor && cursor.changes && cursor.changes.length && cursor.changes) {
records = cursor.changes.map(function (change) {
return change.new_val;
});
}
return [records, cursor];
});
},
_destroy: function _destroy(mapper, id, opts) {
var _this3 = this;
opts || (opts = {});
return this.selectTable(mapper, opts).get(id).delete(this.getOpt('deleteOpts', opts)).run(this.getOpt('runOpts', opts)).then(function (cursor) {
_this3._handleErrors(cursor);
return [undefined, cursor];
});
},
_destroyAll: function _destroyAll(mapper, query, opts) {
var _this4 = this;
query || (query = {});
opts || (opts = {});
return this.filterSequence(this.selectTable(mapper, opts), query).delete(this.getOpt('deleteOpts', opts)).run(this.getOpt('runOpts', opts)).then(function (cursor) {
_this4._handleErrors(cursor);
return [undefined, cursor];
});
},
_find: function _find(mapper, id, opts) {
opts || (opts = {});
return this._pluck(mapper, this.selectTable(mapper, opts).get(id), opts).run(this.getOpt('runOpts', opts)).then(function (record) {
if (!record) {
record = undefined;
}
return [record, {}];
});
},
_findAll: function _findAll(mapper, query, opts) {
opts || (opts = {});
query || (query = {});
return this._pluck(mapper, this.filterSequence(this.selectTable(mapper, opts), query), opts).run(this.getOpt('runOpts', opts)).then(function (records) {
return [records, {}];
});
},
_pluck: function _pluck(mapper, rql, opts) {
if (jsData.utils.isString(opts.fields)) {
opts.fields = [opts.fields];
}
if (jsData.utils.isArray(opts.fields)) {
return rql.pluck.apply(rql, toConsumableArray(opts.fields));
}
return rql;
},
_sum: function _sum(mapper, field, query, opts) {
if (!jsData.utils.isString(field)) {
throw new Error('field must be a string!');
}
opts || (opts = {});
query || (query = {});
return this.filterSequence(this.selectTable(mapper, opts), query).sum(field).run(this.getOpt('runOpts', opts)).then(function (sum) {
return [sum, {}];
});
},
_update: function _update(mapper, id, props, opts) {
var _this5 = this;
props || (props = {});
opts || (opts = {});
var updateOpts = this.getOpt('updateOpts', opts);
updateOpts.returnChanges = true;
return this.selectTable(mapper, opts).get(id).update(props, updateOpts).run(this.getOpt('runOpts', opts)).then(function (cursor) {
_this5._handleErrors(cursor);
if (cursor.skipped) {
throw new Error('Not Found');
} else if (cursor && cursor.changes && cursor.changes.length && cursor.changes[0].new_val) {
return [cursor.changes[0].new_val, cursor];
} else {
return _this5._find(mapper, id, opts);
}
});
},
_updateAll: function _updateAll(mapper, props, query, opts) {
var _this6 = this;
props || (props = {});
query || (query = {});
opts || (opts = {});
var updateOpts = this.getOpt('updateOpts', opts);
updateOpts.returnChanges = true;
return this.filterSequence(this.selectTable(mapper, opts), query).update(props, updateOpts).run(this.getOpt('runOpts', opts)).then(function (cursor) {
var records = [];
_this6._handleErrors(cursor);
if (cursor && cursor.changes && cursor.changes.length) {
records = cursor.changes.map(function (change) {
return change.new_val;
});
}
return [records, cursor];
});
},
_updateMany: function _updateMany(mapper, records, opts) {
var _this7 = this;
records || (records = []);
opts || (opts = {});
var insertOpts = this.getOpt('insertOpts', opts);
insertOpts.returnChanges = true;
insertOpts.conflict = 'update';
return this.selectTable(mapper, opts).insert(records, insertOpts).run(this.getOpt('runOpts', opts)).then(function (cursor) {
records = [];
_this7._handleErrors(cursor);
if (cursor && cursor.changes && cursor.changes.length) {
records = cursor.changes.map(function (change) {
return change.new_val;
});
}
return [records, cursor];
});
},
_applyWhereFromObject: function _applyWhereFromObject(where) {
var fields = [];
var ops = [];
var predicates = [];
jsData.utils.forOwn(where, function (clause, field) {
if (!jsData.utils.isObject(clause)) {
clause = {
'==': clause
};
}
jsData.utils.forOwn(clause, function (expr, op) {
fields.push(field);
ops.push(op);
predicates.push(expr);
});
});
return {
fields: fields,
ops: ops,
predicates: predicates
};
},
_applyWhereFromArray: function _applyWhereFromArray(where) {
var _this8 = this;
var groups = [];
where.forEach(function (_where, i) {
if (jsData.utils.isString(_where)) {
return;
}
var prev = where[i - 1];
var parser = jsData.utils.isArray(_where) ? _this8._applyWhereFromArray : _this8._applyWhereFromObject;
var group = parser.call(_this8, _where);
if (prev === 'or') {
group.isOr = true;
}
groups.push(group);
});
groups.isArray = true;
return groups;
},
_testObjectGroup: function _testObjectGroup(rql, group, row, opts) {
var i = void 0;
var r = this.r;
var fields = group.fields;
var ops = group.ops;
var predicates = group.predicates;
var len = ops.length;
for (i = 0; i < len; i++) {
var op = ops[i];
var isOr = op.charAt(0) === '|';
op = isOr ? op.substr(1) : op;
var predicateFn = this.getOperator(op, opts);
if (predicateFn) {
var predicateResult = predicateFn(r, row, fields[i], predicates[i]);
if (isOr) {
rql = rql ? rql.or(predicateResult) : predicateResult;
} else {
rql = rql ? rql.and(predicateResult) : predicateResult;
}
} else {
throw new Error('Operator ' + op + ' not supported!');
}
}
return rql;
},
_testArrayGroup: function _testArrayGroup(rql, groups, row, opts) {
var i = void 0;
var len = groups.length;
for (i = 0; i < len; i++) {
var group = groups[i];
var subQuery = void 0;
if (group.isArray) {
subQuery = this._testArrayGroup(rql, group, row, opts);
} else {
subQuery = this._testObjectGroup(null, group, row, opts);
}
if (groups[i - 1]) {
if (group.isOr) {
rql = rql.or(subQuery);
} else {
rql = rql.and(subQuery);
}
} else {
rql = rql ? rql.and(subQuery) : subQuery;
}
}
return rql;
},
/**
* 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 _this9 = this;
var r = this.r;
query = jsData.utils.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
jsData.utils.forOwn(query, function (config, keyword) {
if (jsDataAdapter.reserved.indexOf(keyword) === -1) {
if (jsData.utils.isObject(config)) {
query.where[keyword] = config;
} else {
query.where[keyword] = {
'==': config
};
}
delete query[keyword];
}
});
var rql = sequence;
// Filter
var groups = void 0;
if (jsData.utils.isObject(query.where) && Object.keys(query.where).length !== 0) {
groups = this._applyWhereFromArray([query.where]);
} else if (jsData.utils.isArray(query.where)) {
groups = this._applyWhereFromArray(query.where);
}
if (groups) {
rql = rql.filter(function (row) {
return _this9._testArrayGroup(null, groups, row, opts) || true;
});
}
// Sort
if (query.orderBy) {
if (jsData.utils.isString(query.orderBy)) {
query.orderBy = [[query.orderBy, 'asc']];
}
for (var i = 0; i < query.orderBy.length; i++) {
if (jsData.utils.isString(query.orderBy[i])) {
query.orderBy[i] = [query.orderBy[i], 'asc'];
}
rql = (query.orderBy[i][1] || '').toUpperCase() === 'DESC' ? rql.orderBy(r.desc(query.orderBy[i][0])) : rql.orderBy(query.orderBy[i][0]);
}
}
// Offset
if (query.skip) {
rql = rql.skip(+query.skip);
}
// Limit
if (query.limit) {
rql = rql.limit(+query.limit);
}
return rql;
},
selectDb: function selectDb(opts) {
return this.r.db(jsData.utils.isUndefined(opts.db) ? this.rOpts.db : opts.db);
},
selectTable: function selectTable(mapper, opts) {
return this.selectDb(opts).table(mapper.table || snakeCase(mapper.name));
},
waitForDb: function waitForDb(opts) {
opts || (opts = {});
var db = jsData.utils.isUndefined(opts.db) ? this.rOpts.db : opts.db;
if (!this.databases[db]) {
this.databases[db] = this.r.branch(this.r.dbList().contains(db), true, this.r.dbCreate(db)).run();
}
return this.databases[db];
},
waitForTable: function waitForTable(mapper, opts) {
var _this10 = this;
opts || (opts = {});
var table = jsData.utils.isString(mapper) ? mapper : mapper.table || snakeCase(mapper.name);
var db = jsData.utils.isUndefined(opts.db) ? this.rOpts.db : opts.db;
return this.waitForDb(opts).then(function () {
_this10.tables[db] = _this10.tables[db] || {};
if (!_this10.tables[db][table]) {
_this10.tables[db][table] = _this10.r.branch(_this10.r.db(db).tableList().contains(table), true, _this10.r.db(db).tableCreate(table)).run();
}
return _this10.tables[db][table];
});
},
waitForIndex: function waitForIndex(table, index, opts) {
var _this11 = this;
opts || (opts = {});
var db = jsData.utils.isUndefined(opts.db) ? this.rOpts.db : opts.db;
return this.waitForDb(opts).then(function () {
return _this11.waitForTable(table, opts);
}).then(function () {
_this11.indices[db] = _this11.indices[db] || {};
_this11.indices[db][table] = _this11.indices[db][table] || {};
if (!_this11.tables[db][table][index]) {
_this11.tables[db][table][index] = _this11.r.branch(_this11.r.db(db).table(table).indexList().contains(index), true, _this11.r.db(db).table(table).indexCreate(index)).run().then(function () {
return _this11.r.db(db).table(table).indexWait(index).run();
});
}
return _this11.tables[db][table][index];
});
},
/**
* Return the number of records that match the selection query.
*
* @name RethinkDBAdapter#count
* @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.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
count: function count(mapper, query, opts) {
var _this12 = this;
opts || (opts = {});
query || (query = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.count.call(_this12, mapper, query, opts);
});
},
/**
* Create a new record.
*
* @name RethinkDBAdapter#create
* @method
* @param {object} mapper The mapper.
* @param {object} props The record to be created.
* @param {object} [opts] Configuration options.
* @param {object} [opts.insertOpts] Options to pass to r#insert.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
create: function create(mapper, props, opts) {
var _this13 = this;
props || (props = {});
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.create.call(_this13, mapper, props, opts);
});
},
/**
* Create multiple records in a single batch.
*
* @name RethinkDBAdapter#createMany
* @method
* @param {object} mapper The mapper.
* @param {object} props The records to be created.
* @param {object} [opts] Configuration options.
* @param {object} [opts.insertOpts] Options to pass to r#insert.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
createMany: function createMany(mapper, props, opts) {
var _this14 = this;
props || (props = {});
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.createMany.call(_this14, mapper, props, opts);
});
},
/**
* Destroy the record with the given primary key.
*
* @name RethinkDBAdapter#destroy
* @method
* @param {object} mapper The mapper.
* @param {(string|number)} id Primary key of the record to destroy.
* @param {object} [opts] Configuration options.
* @param {object} [opts.deleteOpts] Options to pass to r#delete.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
destroy: function destroy(mapper, id, opts) {
var _this15 = this;
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.destroy.call(_this15, mapper, id, opts);
});
},
/**
* Destroy the records that match the selection query.
*
* @name RethinkDBAdapter#destroyAll
* @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.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
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
destroyAll: function destroyAll(mapper, query, opts) {
var _this16 = this;
opts || (opts = {});
query || (query = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.destroyAll.call(_this16, mapper, query, opts);
});
},
/**
* Retrieve the record with the given primary key.
*
* @name RethinkDBAdapter#find
* @method
* @param {object} mapper The mapper.
* @param {(string|number)} id Primary key of the record to retrieve.
* @param {object} [opts] Configuration options.
* @param {string[]} [opts.fields] Select a subset of fields to be returned.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @param {string[]} [opts.with=[]] Relations to eager load.
* @return {Promise}
*/
find: function find(mapper, id, opts) {
var _this17 = this;
opts || (opts = {});
opts.with || (opts.with = []);
var relationList = mapper.relationList || [];
var tasks = [this.waitForTable(mapper, opts)];
relationList.forEach(function (def) {
var relationName = def.relation;
var relationDef = def.getRelation();
if (!opts.with || opts.with.indexOf(relationName) === -1) {
return;
}
if (def.foreignKey && def.type !== 'belongsTo') {
if (def.type === 'belongsTo') {
tasks.push(_this17.waitForIndex(mapper.table || snakeCase(mapper.name), def.foreignKey, opts));
} else {
tasks.push(_this17.waitForIndex(relationDef.table || snakeCase(relationDef.name), def.foreignKey, opts));
}
}
});
return Promise.all(tasks).then(function () {
return __super__.find.call(_this17, mapper, id, opts);
});
},
/**
* Retrieve the records that match the selection query.
*
* @name RethinkDBAdapter#findAll
* @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 {string[]} [opts.fields] Select a subset of fields to be returned.
* @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 {string[]} [opts.with=[]] Relations to eager load.
* @return {Promise}
*/
findAll: function findAll(mapper, query, opts) {
var _this18 = this;
opts || (opts = {});
opts.with || (opts.with = []);
query || (query = {});
var relationList = mapper.relationList || [];
var tasks = [this.waitForTable(mapper, opts)];
relationList.forEach(function (def) {
var relationName = def.relation;
var relationDef = def.getRelation();
if (!opts.with || opts.with.indexOf(relationName) === -1) {
return;
}
if (def.foreignKey && def.type !== 'belongsTo') {
if (def.type === 'belongsTo') {
tasks.push(_this18.waitForIndex(mapper.table || snakeCase(mapper.name), def.foreignKey, opts));
} else {
tasks.push(_this18.waitForIndex(relationDef.table || snakeCase(relationDef.name), def.foreignKey, opts));
}
}
});
return Promise.all(tasks).then(function () {
return __super__.findAll.call(_this18, mapper, query, opts);
});
},
/**
* 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 jsData.utils.isUndefined(opts.operators[operator]) ? ownOps[operator] : opts.operators[operator];
},
/**
* Return the sum of the specified field of records that match the selection
* query.
*
* @name RethinkDBAdapter#sum
* @method
* @param {object} mapper The mapper.
* @param {string} field The field to sum.
* @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
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
sum: function sum(mapper, field, query, opts) {
var _this19 = this;
opts || (opts = {});
query || (query = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.sum.call(_this19, mapper, field, query, opts);
});
},
/**
* Apply the given update to the record with the specified primary key.
*
* @name RethinkDBAdapter#update
* @method
* @param {object} mapper The mapper.
* @param {(string|number)} id The primary key of the record to be updated.
* @param {object} props The update to apply to the record.
* @param {object} [opts] Configuration options.
* @param {object} [opts.updateOpts] Options to pass to r#update.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
update: function update(mapper, id, props, opts) {
var _this20 = this;
props || (props = {});
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.update.call(_this20, mapper, id, props, opts);
});
},
/**
* Apply the given update to all records that match the selection query.
*
* @name RethinkDBAdapter#updateAll
* @method
* @param {object} mapper The mapper.
* @param {object} props The update to apply to the selected records.
* @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
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @param {object} [opts.updateOpts] Options to pass to r#update.
* @return {Promise}
*/
updateAll: function updateAll(mapper, props, query, opts) {
var _this21 = this;
props || (props = {});
query || (query = {});
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.updateAll.call(_this21, mapper, props, query, opts);
});
},
/**
* Update the given records in a single batch.
*
* @name RethinkDBAdapter#updateMany
* @method
* @param {object} mapper The mapper.
* @param {Object[]} records The records to update.
* @param {object} [opts] Configuration options.
* @param {object} [opts.insertOpts] Options to pass to r#insert.
* @param {boolean} [opts.raw=false] Whether to return a more detailed
* response object.
* @param {object} [opts.runOpts] Options to pass to r#run.
* @return {Promise}
*/
updateMany: function updateMany(mapper, records, opts) {
var _this22 = this;
records || (records = []);
opts || (opts = {});
return this.waitForTable(mapper, opts).then(function () {
return __super__.updateMany.call(_this22, mapper, records, opts);
});
}
});
/**
* Details of the current version of the `js-data-rethinkdb` module.
*
* @example <caption>ES2015 modules import</caption>
* import { version } from 'js-data-rethinkdb';
* console.log(version.full);
*
* @example <caption>CommonJS import</caption>
* const version = require('js-data-rethinkdb').version;
* console.log(version.full);
*
* @name module:js-data-rethinkdb.version
* @type {object}
* @property {string} version.full The full semver value.
* @property {number} version.major The major version number.
* @property {number} version.minor The minor version number.
* @property {number} version.patch The patch version number.
* @property {(string|boolean)} version.alpha The alpha version value,
* otherwise `false` if the current version is not alpha.
* @property {(string|boolean)} version.beta The beta version value,
* otherwise `false` if the current version is not beta.
*/
var version = {
full: '3.0.0',
major: 3,
minor: 0,
patch: 0
};
/**
* {@link RethinkDBAdapter} class.
*
* @example <caption>ES2015 modules import</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter();
*
* @example <caption>CommonJS import</caption>
* const RethinkDBAdapter = require('js-data-rethinkdb').RethinkDBAdapter;
* const adapter = new RethinkDBAdapter();
*
* @name module:js-data-rethinkdb.RethinkDBAdapter
* @see RethinkDBAdapter
* @type {Constructor}
*/
/**
* Registered as `js-data-rethinkdb` in NPM.
*
* @example <caption>Install from NPM</caption>
* npm i --save js-data-rethinkdb js-data
*
* @example <caption>ES2015 modules import</caption>
* import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const adapter = new RethinkDBAdapter();
*
* @example <caption>CommonJS import</caption>
* const RethinkDBAdapter = require('js-data-rethinkdb').RethinkDBAdapter;
* const adapter = new RethinkDBAdapter();
*
* @module js-data-rethinkdb
*/
/**
* Create a subclass of this RethinkDBAdapter:
* @example <caption>RethinkDBAdapter.extend</caption>
* // Normally you would do: import { RethinkDBAdapter } from 'js-data-rethinkdb';
* const JSDataRethinkDB = require('js-data-rethinkdb');
* const { RethinkDBAdapter } = JSDataRethinkDB;
* console.log('Using JSDataRethinkDB v' + JSDataRethinkDB.version.full);
*
* // Extend the class using ES2015 class syntax.
* class CustomRethinkDBAdapterClass extends RethinkDBAdapter {
* foo () { return 'bar'; }
* static beep () { return 'boop'; }
* }
* const customRethinkDBAdapter = new CustomRethinkDBAdapterClass();
* console.log(customRethinkDBAdapter.foo());
* console.log(CustomRethinkDBAdapterClass.beep());
*
* // Extend the class using alternate method.
* const OtherRethinkDBAdapterClass = RethinkDBAdapter.extend({
* foo () { return 'bar'; }
* }, {
* beep () { return 'boop'; }
* });
* const otherRethinkDBAdapter = new OtherRethinkDBAdapterClass();
* console.log(otherRethinkDBAdapter.foo());
* console.log(OtherRethinkDBAdapterClass.beep());
*
* // Extend the class, providing a custom constructor.
* function AnotherRethinkDBAdapterClass () {
* RethinkDBAdapter.call(this);
* this.created_at = new Date().getTime();
* }
* RethinkDBAdapter.extend({
* constructor: AnotherRethinkDBAdapterClass,
* foo () { return 'bar'; }
* }, {
* beep () { return 'boop'; }
* })
* const anotherRethinkDBAdapter = new AnotherRethinkDBAdapterClass();
* console.log(anotherRethinkDBAdapter.created_at);
* console.log(anotherRethinkDBAdapter.foo());
* console.log(AnotherRethinkDBAdapterClass.beep());
*
* @method RethinkDBAdapter.extend
* @param {object} [props={}] Properties to add to the prototype of the
* subclass.
* @param {object} [props.constructor] Provide a custom constructor function
* to be used as the subclass itself.
* @param {object} [classProps={}] Static properties to add to the subclass.
* @returns {Constructor} Subclass of this RethinkDBAdapter class.
* @since 3.0.0
*/
exports.OPERATORS = OPERATORS;
exports.RethinkDBAdapter = RethinkDBAdapter;
exports.version = version;
//# sourceMappingURL=js-data-rethinkdb.js.map