Socket
Socket
Sign inDemoInstall

redux-orm

Package Overview
Dependencies
7
Maintainers
1
Versions
70
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.0-rc.0 to 0.9.0-rc.1

373

lib/db/Table.js

@@ -23,6 +23,2 @@ 'use strict';

var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _reject = require('lodash/reject');

@@ -115,157 +111,136 @@

(0, _createClass3.default)(Table, [{
key: 'accessId',
value: function accessId(branch, id) {
return branch[this.mapName][id];
}
}, {
key: 'idExists',
value: function idExists(branch, id) {
return branch[this.mapName].hasOwnProperty(id);
}
}, {
key: 'accessIdList',
value: function accessIdList(branch) {
return branch[this.arrName];
}
}, {
key: 'accessList',
value: function accessList(branch) {
var _this = this;
Table.prototype.accessId = function accessId(branch, id) {
return branch[this.mapName][id];
};
return branch[this.arrName].map(function (id) {
return _this.accessId(branch, id);
});
}
}, {
key: 'getMaxId',
value: function getMaxId(branch) {
return this.getMeta(branch, 'maxId');
}
}, {
key: 'setMaxId',
value: function setMaxId(tx, branch, newMaxId) {
return this.setMeta(tx, branch, 'maxId', newMaxId);
}
}, {
key: 'nextId',
value: function nextId(id) {
return id + 1;
}
}, {
key: 'query',
value: function query(branch, clauses) {
var _this2 = this;
Table.prototype.idExists = function idExists(branch, id) {
return branch[this.mapName].hasOwnProperty(id);
};
return clauses.reduce(function (rows, _ref) {
var type = _ref.type,
payload = _ref.payload;
Table.prototype.accessIdList = function accessIdList(branch) {
return branch[this.arrName];
};
switch (type) {
case _constants.FILTER:
{
if (payload.hasOwnProperty(_this2.idAttribute) && payload[_this2.idAttribute]) {
// Payload specified a primary key; Since that is unique, we can directly
// return that.
var id = payload[_this2.idAttribute];
return _this2.idExists(branch, id) ? [_this2.accessId(branch, payload[_this2.idAttribute])] : [];
}
return (0, _filter2.default)(rows, payload);
}
case _constants.EXCLUDE:
{
return (0, _reject2.default)(rows, payload);
}
case _constants.ORDER_BY:
{
var _payload = (0, _slicedToArray3.default)(payload, 2),
iteratees = _payload[0],
orders = _payload[1];
Table.prototype.accessList = function accessList(branch) {
var _this = this;
return (0, _orderBy2.default)(rows, iteratees, orders);
}
default:
return rows;
}
}, this.accessList(branch));
}
return branch[this.arrName].map(function (id) {
return _this.accessId(branch, id);
});
};
/**
* Returns the default state for the data structure.
* @return {Object} The default state for this {@link Backend} instance's data structure
*/
Table.prototype.getMaxId = function getMaxId(branch) {
return this.getMeta(branch, 'maxId');
};
}, {
key: 'getEmptyState',
value: function getEmptyState() {
var _ref2;
Table.prototype.setMaxId = function setMaxId(tx, branch, newMaxId) {
return this.setMeta(tx, branch, 'maxId', newMaxId);
};
return _ref2 = {}, (0, _defineProperty3.default)(_ref2, this.arrName, []), (0, _defineProperty3.default)(_ref2, this.mapName, {}), (0, _defineProperty3.default)(_ref2, 'meta', {}), _ref2;
}
}, {
key: 'setMeta',
value: function setMeta(tx, branch, key, value) {
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
Table.prototype.nextId = function nextId(id) {
return id + 1;
};
if (withMutations) {
var res = _immutableOps2.default.mutable.setIn(['meta', key], value, branch);
return res;
Table.prototype.query = function query(branch, clauses) {
var _this2 = this;
return clauses.reduce(function (rows, _ref) {
var type = _ref.type,
payload = _ref.payload;
switch (type) {
case _constants.FILTER:
{
if (payload.hasOwnProperty(_this2.idAttribute) && payload[_this2.idAttribute]) {
// Payload specified a primary key; Since that is unique, we can directly
// return that.
var id = payload[_this2.idAttribute];
return _this2.idExists(branch, id) ? [_this2.accessId(branch, payload[_this2.idAttribute])] : [];
}
return (0, _filter2.default)(rows, payload);
}
case _constants.EXCLUDE:
{
return (0, _reject2.default)(rows, payload);
}
case _constants.ORDER_BY:
{
var _payload = (0, _slicedToArray3.default)(payload, 2),
iteratees = _payload[0],
orders = _payload[1];
return (0, _orderBy2.default)(rows, iteratees, orders);
}
default:
return rows;
}
}, this.accessList(branch));
};
return _immutableOps2.default.batch.setIn(batchToken, ['meta', key], value, branch);
/**
* Returns the default state for the data structure.
* @return {Object} The default state for this {@link Backend} instance's data structure
*/
Table.prototype.getEmptyState = function getEmptyState() {
var _ref2;
return _ref2 = {}, (0, _defineProperty3.default)(_ref2, this.arrName, []), (0, _defineProperty3.default)(_ref2, this.mapName, {}), (0, _defineProperty3.default)(_ref2, 'meta', {}), _ref2;
};
Table.prototype.setMeta = function setMeta(tx, branch, key, value) {
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
if (withMutations) {
var res = _immutableOps2.default.mutable.setIn(['meta', key], value, branch);
return res;
}
}, {
key: 'getMeta',
value: function getMeta(branch, key) {
return branch.meta[key];
}
/**
* Returns the data structure including a new object `entry`
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object} entry - the object to insert
* @return {Object} an object with two keys: `state` and `created`.
* `state` is the new table state and `created` is the
* row that was created.
*/
return _immutableOps2.default.batch.setIn(batchToken, ['meta', key], value, branch);
};
}, {
key: 'insert',
value: function insert(tx, branch, entry) {
var _ops$batch$merge2;
Table.prototype.getMeta = function getMeta(branch, key) {
return branch.meta[key];
};
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
/**
* Returns the data structure including a new object `entry`
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object} entry - the object to insert
* @return {Object} an object with two keys: `state` and `created`.
* `state` is the new table state and `created` is the
* row that was created.
*/
var hasId = entry.hasOwnProperty(this.idAttribute);
Table.prototype.insert = function insert(tx, branch, entry) {
var _ops$batch$merge2;
var workingState = branch;
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
// This will not affect string id's.
var _idSequencer = idSequencer(this.getMaxId(branch), entry[this.idAttribute]),
_idSequencer2 = (0, _slicedToArray3.default)(_idSequencer, 2),
newMaxId = _idSequencer2[0],
id = _idSequencer2[1];
var hasId = entry.hasOwnProperty(this.idAttribute);
workingState = this.setMaxId(tx, branch, newMaxId);
var workingState = branch;
var finalEntry = hasId ? entry : _immutableOps2.default.batch.set(batchToken, this.idAttribute, id, entry);
// This will not affect string id's.
if (withMutations) {
_immutableOps2.default.mutable.push(id, workingState[this.arrName]);
_immutableOps2.default.mutable.set(id, finalEntry, workingState[this.mapName]);
return {
state: workingState,
created: finalEntry
};
}
var _idSequencer = idSequencer(this.getMaxId(branch), entry[this.idAttribute]),
_idSequencer2 = (0, _slicedToArray3.default)(_idSequencer, 2),
newMaxId = _idSequencer2[0],
id = _idSequencer2[1];
var nextState = _immutableOps2.default.batch.merge(batchToken, (_ops$batch$merge2 = {}, (0, _defineProperty3.default)(_ops$batch$merge2, this.arrName, _immutableOps2.default.batch.push(batchToken, id, workingState[this.arrName])), (0, _defineProperty3.default)(_ops$batch$merge2, this.mapName, _immutableOps2.default.batch.merge(batchToken, (0, _defineProperty3.default)({}, id, finalEntry), workingState[this.mapName])), _ops$batch$merge2), workingState);
workingState = this.setMaxId(tx, branch, newMaxId);
var finalEntry = hasId ? entry : _immutableOps2.default.batch.set(batchToken, this.idAttribute, id, entry);
if (withMutations) {
_immutableOps2.default.mutable.push(id, workingState[this.arrName]);
_immutableOps2.default.mutable.set(id, finalEntry, workingState[this.mapName]);
return {
state: nextState,
state: workingState,
created: finalEntry

@@ -275,78 +250,84 @@ };

/**
* Returns the data structure with objects where `rows`
* are merged with `mergeObj`.
*
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object[]} rows - rows to update
* @param {Object} mergeObj - The object to merge with each row.
* @return {Object}
*/
var nextState = _immutableOps2.default.batch.merge(batchToken, (_ops$batch$merge2 = {}, (0, _defineProperty3.default)(_ops$batch$merge2, this.arrName, _immutableOps2.default.batch.push(batchToken, id, workingState[this.arrName])), (0, _defineProperty3.default)(_ops$batch$merge2, this.mapName, _immutableOps2.default.batch.merge(batchToken, (0, _defineProperty3.default)({}, id, finalEntry), workingState[this.mapName])), _ops$batch$merge2), workingState);
}, {
key: 'update',
value: function update(tx, branch, rows, mergeObj) {
var _this3 = this;
return {
state: nextState,
created: finalEntry
};
};
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
var mapName = this.mapName;
/**
* Returns the data structure with objects where `rows`
* are merged with `mergeObj`.
*
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object[]} rows - rows to update
* @param {Object} mergeObj - The object to merge with each row.
* @return {Object}
*/
var mapFunction = function mapFunction(row) {
var merge = withMutations ? _immutableOps2.default.mutable.merge : _immutableOps2.default.batch.merge(batchToken);
return merge(mergeObj, row);
};
Table.prototype.update = function update(tx, branch, rows, mergeObj) {
var _this3 = this;
var set = withMutations ? _immutableOps2.default.mutable.set : _immutableOps2.default.batch.set(batchToken);
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
var mapName = this.mapName;
var newMap = rows.reduce(function (map, row) {
var result = mapFunction(row);
return set(result[_this3.idAttribute], result, map);
}, branch[mapName]);
return _immutableOps2.default.batch.set(batchToken, mapName, newMap, branch);
}
/**
* Returns the data structure without rows `rows`.
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object[]} rows - rows to update
* @return {Object} the data structure without ids in `idsToDelete`.
*/
var mapFunction = function mapFunction(row) {
var merge = withMutations ? _immutableOps2.default.mutable.merge : _immutableOps2.default.batch.merge(batchToken);
return merge(mergeObj, row);
};
}, {
key: 'delete',
value: function _delete(tx, branch, rows) {
var _this4 = this,
_ops$batch$merge3;
var set = withMutations ? _immutableOps2.default.mutable.set : _immutableOps2.default.batch.set(batchToken);
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
var arrName = this.arrName,
mapName = this.mapName;
var newMap = rows.reduce(function (map, row) {
var result = mapFunction(row);
return set(result[_this3.idAttribute], result, map);
}, branch[mapName]);
return _immutableOps2.default.batch.set(batchToken, mapName, newMap, branch);
};
var arr = branch[arrName];
/**
* Returns the data structure without rows `rows`.
* @param {Object} tx - transaction info
* @param {Object} branch - the data structure state
* @param {Object[]} rows - rows to update
* @return {Object} the data structure without ids in `idsToDelete`.
*/
var idsToDelete = rows.map(function (row) {
return row[_this4.idAttribute];
Table.prototype.delete = function _delete(tx, branch, rows) {
var _this4 = this,
_ops$batch$merge3;
var batchToken = tx.batchToken,
withMutations = tx.withMutations;
var arrName = this.arrName,
mapName = this.mapName;
var arr = branch[arrName];
var idsToDelete = rows.map(function (row) {
return row[_this4.idAttribute];
});
if (withMutations) {
idsToDelete.forEach(function (id) {
var idx = arr.indexOf(id);
if (idx !== -1) {
_immutableOps2.default.mutable.splice(idx, 1, [], arr);
}
_immutableOps2.default.mutable.omit(id, branch[mapName]);
});
if (withMutations) {
idsToDelete.forEach(function (id) {
var idx = arr.indexOf(id);
if (idx !== -1) {
_immutableOps2.default.mutable.splice(idx, 1, [], arr);
}
return branch;
}
_immutableOps2.default.mutable.omit(id, branch[mapName]);
});
return branch;
}
return _immutableOps2.default.batch.merge(batchToken, (_ops$batch$merge3 = {}, (0, _defineProperty3.default)(_ops$batch$merge3, arrName, _immutableOps2.default.batch.filter(batchToken, function (id) {
return !(0, _utils.includes)(idsToDelete, id);
}, branch[arrName])), (0, _defineProperty3.default)(_ops$batch$merge3, mapName, _immutableOps2.default.batch.omit(batchToken, idsToDelete, branch[mapName])), _ops$batch$merge3), branch);
};
return _immutableOps2.default.batch.merge(batchToken, (_ops$batch$merge3 = {}, (0, _defineProperty3.default)(_ops$batch$merge3, arrName, _immutableOps2.default.batch.filter(batchToken, function (id) {
return !(0, _utils.includes)(idsToDelete, id);
}, branch[arrName])), (0, _defineProperty3.default)(_ops$batch$merge3, mapName, _immutableOps2.default.batch.omit(batchToken, idsToDelete, branch[mapName])), _ops$batch$merge3), branch);
}
}]);
return Table;

@@ -353,0 +334,0 @@ }();

@@ -6,3 +6,3 @@ 'use strict';

});
exports.manyToManyDescriptor = exports.backwardManyToOneDescriptor = exports.backwardOneToOneDescriptor = exports.forwardOneToOneDescriptor = exports.forwardManyToOneDescriptor = undefined;
exports.manyToManyDescriptor = exports.backwardManyToOneDescriptor = exports.backwardOneToOneDescriptor = exports.forwardOneToOneDescriptor = exports.forwardManyToOneDescriptor = exports.attrDescriptor = undefined;

@@ -21,2 +21,17 @@ var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

function attrDescriptor(fieldName) {
return {
get: function get() {
return this._fields[fieldName];
},
set: function set(value) {
return this.set(fieldName, value);
},
enumerable: true,
configurable: true
};
}
// Forwards side a Foreign Key: returns one object.

@@ -191,2 +206,3 @@ // Also works as forwardsOneToOneDescriptor.

exports.attrDescriptor = attrDescriptor;
exports.forwardManyToOneDescriptor = forwardManyToOneDescriptor;

@@ -193,0 +209,0 @@ exports.forwardOneToOneDescriptor = forwardOneToOneDescriptor;

@@ -12,10 +12,6 @@ 'use strict';

var _defineProperty = require('babel-runtime/core-js/object/define-property');
var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor');
var _defineProperty2 = _interopRequireDefault(_defineProperty);
var _getOwnPropertyDescriptor2 = _interopRequireDefault(_getOwnPropertyDescriptor);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

@@ -33,2 +29,6 @@

var _defineProperty = require('babel-runtime/core-js/object/define-property');
var _defineProperty2 = _interopRequireDefault(_defineProperty);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -38,6 +38,2 @@

var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
exports.attr = attr;

@@ -73,6 +69,6 @@ exports.fk = fk;

(0, _createClass3.default)(Attribute, [{
key: 'install',
value: function install() {}
}]);
Attribute.prototype.install = function install(model, fieldName, orm) {
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.attrDescriptor)(fieldName));
};
return Attribute;

@@ -96,8 +92,6 @@ }();

(0, _createClass3.default)(RelationalField, [{
key: 'getClass',
value: function getClass() {
return this.constructor;
}
}]);
RelationalField.prototype.getClass = function getClass() {
return this.constructor;
};
return RelationalField;

@@ -111,29 +105,28 @@ }();

(0, _classCallCheck3.default)(this, ForeignKey);
return (0, _possibleConstructorReturn3.default)(this, (ForeignKey.__proto__ || (0, _getPrototypeOf2.default)(ForeignKey)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _RelationalField.apply(this, arguments));
}
(0, _createClass3.default)(ForeignKey, [{
key: 'install',
value: function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
ForeignKey.prototype.install = function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
// Forwards.
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.forwardManyToOneDescriptor)(fieldName, toModel.modelName));
model.definedProperties[fieldName] = true;
// Forwards.
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.forwardManyToOneDescriptor)(fieldName, toModel.modelName));
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : (0, _utils.reverseFieldName)(model.modelName);
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : (0, _utils.reverseFieldName)(model.modelName);
if (toModel.definedProperties[backwardsFieldName]) {
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
var backwardsDescriptor = (0, _getOwnPropertyDescriptor2.default)(toModel.prototype, backwardsFieldName);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.backwardManyToOneDescriptor)(fieldName, model.modelName));
toModel.definedProperties[backwardsFieldName] = true;
var ThisField = this.getClass();
toModel.virtualFields[backwardsFieldName] = new ThisField(model.modelName, fieldName);
if (backwardsDescriptor) {
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
}]);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.backwardManyToOneDescriptor)(fieldName, model.modelName));
var ThisField = this.getClass();
toModel.virtualFields[backwardsFieldName] = new ThisField(model.modelName, fieldName);
};
return ForeignKey;

@@ -147,80 +140,78 @@ }(RelationalField);

(0, _classCallCheck3.default)(this, ManyToMany);
return (0, _possibleConstructorReturn3.default)(this, (ManyToMany.__proto__ || (0, _getPrototypeOf2.default)(ManyToMany)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _RelationalField2.apply(this, arguments));
}
(0, _createClass3.default)(ManyToMany, [{
key: 'install',
value: function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
ManyToMany.prototype.install = function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
// Forwards.
// Forwards.
var throughModelName = this.through || (0, _utils.m2mName)(model.modelName, fieldName);
var throughModelName = this.through || (0, _utils.m2mName)(model.modelName, fieldName);
var throughModel = orm.get(throughModelName);
var throughModel = orm.get(throughModelName);
var throughFields = void 0;
if (!this.throughFields) {
var toFieldName = (0, _findKey2.default)(throughModel.fields, function (field) {
return field instanceof ForeignKey && field.toModelName === toModel.modelName;
});
var fromFieldName = (0, _findKey2.default)(throughModel.fields, function (field) {
return field instanceof ForeignKey && field.toModelName === model.modelName;
});
var throughFields = void 0;
if (!this.throughFields) {
var toFieldName = (0, _findKey2.default)(throughModel.fields, function (field) {
return field instanceof ForeignKey && field.toModelName === toModel.modelName;
});
var fromFieldName = (0, _findKey2.default)(throughModel.fields, function (field) {
return field instanceof ForeignKey && field.toModelName === model.modelName;
});
throughFields = {
to: toFieldName,
from: fromFieldName
};
} else {
var _throughFields = throughFields,
_throughFields2 = (0, _slicedToArray3.default)(_throughFields, 2),
fieldAName = _throughFields2[0],
fieldBName = _throughFields2[1];
var fieldA = throughModel.fields[fieldAName];
if (fieldA.toModelName === toModel.modelName) {
throughFields = {
to: toFieldName,
from: fromFieldName
to: fieldAName,
from: fieldBName
};
} else {
var _throughFields = throughFields,
_throughFields2 = (0, _slicedToArray3.default)(_throughFields, 2),
fieldAName = _throughFields2[0],
fieldBName = _throughFields2[1];
var fieldA = throughModel.fields[fieldAName];
if (fieldA.toModelName === toModel.modelName) {
throughFields = {
to: fieldAName,
from: fieldBName
};
} else {
throughFields = {
to: fieldBName,
from: fieldAName
};
}
throughFields = {
to: fieldBName,
from: fieldAName
};
}
}
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.manyToManyDescriptor)(model.modelName, toModel.modelName, throughModelName, throughFields, false));
model.definedProperties[fieldName] = true;
model.virtualFields[fieldName] = new ManyToMany({
to: toModel.modelName,
relatedName: fieldName,
through: this.through
});
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.manyToManyDescriptor)(model.modelName, toModel.modelName, throughModelName, throughFields, false));
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : (0, _utils.reverseFieldName)(model.modelName);
model.virtualFields[fieldName] = new ManyToMany({
to: toModel.modelName,
relatedName: fieldName,
through: this.through
});
if (toModel.definedProperties[backwardsFieldName]) {
// Backwards field was already defined on toModel.
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : (0, _utils.reverseFieldName)(model.modelName);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.manyToManyDescriptor)(model.modelName, toModel.modelName, throughModelName, throughFields, true));
toModel.definedProperties[backwardsFieldName] = true;
toModel.virtualFields[backwardsFieldName] = new ManyToMany({
to: model.modelName,
relatedName: fieldName,
through: throughModelName
});
var backwardsDescriptor = (0, _getOwnPropertyDescriptor2.default)(toModel.prototype, backwardsFieldName);
if (backwardsDescriptor) {
// Backwards field was already defined on toModel.
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
}, {
key: 'getDefault',
value: function getDefault() {
return [];
}
}]);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.manyToManyDescriptor)(model.modelName, toModel.modelName, throughModelName, throughFields, true));
toModel.virtualFields[backwardsFieldName] = new ManyToMany({
to: model.modelName,
relatedName: fieldName,
through: throughModelName
});
};
ManyToMany.prototype.getDefault = function getDefault() {
return [];
};
return ManyToMany;

@@ -234,28 +225,26 @@ }(RelationalField);

(0, _classCallCheck3.default)(this, OneToOne);
return (0, _possibleConstructorReturn3.default)(this, (OneToOne.__proto__ || (0, _getPrototypeOf2.default)(OneToOne)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _RelationalField3.apply(this, arguments));
}
(0, _createClass3.default)(OneToOne, [{
key: 'install',
value: function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
OneToOne.prototype.install = function install(model, fieldName, orm) {
var toModelName = this.toModelName;
var toModel = toModelName === 'this' ? model : orm.get(toModelName);
// Forwards.
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.forwardOneToOneDescriptor)(fieldName, toModel.modelName));
model.definedProperties[fieldName] = true;
// Forwards.
(0, _defineProperty2.default)(model.prototype, fieldName, (0, _descriptors.forwardOneToOneDescriptor)(fieldName, toModel.modelName));
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : model.modelName.toLowerCase();
// Backwards.
var backwardsFieldName = this.relatedName ? this.relatedName : model.modelName.toLowerCase();
if (toModel.definedProperties[backwardsFieldName]) {
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
var backwardsDescriptor = (0, _getOwnPropertyDescriptor2.default)(toModel.prototype, backwardsFieldName);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.backwardOneToOneDescriptor)(fieldName, model.modelName));
toModel.definedProperties[backwardsFieldName] = true;
toModel.virtualFields[backwardsFieldName] = new OneToOne(model.modelName, fieldName);
if (backwardsDescriptor) {
var errorMsg = (0, _utils.reverseFieldErrorMessage)(model.modelName, fieldName, toModel.modelName, backwardsFieldName);
throw new Error(errorMsg);
}
}]);
(0, _defineProperty2.default)(toModel.prototype, backwardsFieldName, (0, _descriptors.backwardOneToOneDescriptor)(fieldName, model.modelName));
toModel.virtualFields[backwardsFieldName] = new OneToOne(model.modelName, fieldName);
};
return OneToOne;

@@ -266,3 +255,5 @@ }(RelationalField);

* Defines a value attribute on the model.
* You need to define this for each non-foreign key you wish to use.
* Though not required, it is recommended to define this for each non-foreign key you wish to use.
* Getters and setters need to be defined on each Model
* instantiation for undeclared data fields, which is slower.
* You can use the optional `getDefault` parameter to fill in unpassed values

@@ -269,0 +260,0 @@ * to {@link Model#create}, such as for generating ID's with UUID:

@@ -107,480 +107,452 @@ 'use strict';

(0, _createClass3.default)(Model, [{
key: '_initFields',
value: function _initFields(props) {
var _this = this;
Model.prototype._initFields = function _initFields(props) {
var _this = this;
var ModelClass = this.getClass();
this._fields = (0, _assign2.default)({}, props);
var fieldsDef = this.getClass().fields;
this._fields = (0, _assign2.default)({}, props);
var ThisModel = this.getClass();
(0, _forOwn2.default)(props, function (fieldValue, fieldName) {
if (!fieldsDef.hasOwnProperty(fieldName)) {
throw new Error('Unexpected field given to ' + ModelClass.modelName + ' constructor: ' + fieldName + '. ' + ('If ' + ModelClass.modelName + ' should accept this field, ') + 'add an attr() field to it.');
}
(0, _forOwn2.default)(props, function (fieldValue, fieldName) {
// In this case, we got a prop that wasn't defined as a field.
// Assuming it's an arbitrary data field, making an instance-specific
// descriptor for it.
// Using the in operator as the property could be defined anywhere
// on the prototype chain.
if (!(fieldName in _this)) {
(0, _defineProperty3.default)(_this, fieldName, {
get: function get() {
return _this._fields[fieldName];
},
set: function set(value) {
return _this.set(fieldName, value);
},
configurable: true,
enumerable: true
});
}
});
};
_this._fields[fieldName] = fieldValue;
Model.toString = function toString() {
return 'ModelClass: ' + this.modelName;
};
// If the field has not already been defined on the
// prototype for a relation.
if (!ModelClass.definedProperties[fieldName]) {
(0, _defineProperty3.default)(_this, fieldName, {
get: function get() {
return _this._fields[fieldName];
},
set: function set(value) {
return _this.set(fieldName, value);
},
configurable: true
});
}
});
}
}, {
key: 'getClass',
/**
* Returns the options object passed to the database for the table that represents
* this Model class.
*
* Returns an empty object by default, which means the database
* will use default options. You can either override this function to return the options
* you want to use, or assign the options object as a static property of the same name to the
* Model class.
*
* @return {Object} the options object passed to the database for the table
* representing this Model class.
*/
/**
* Gets the {@link Model} class or subclass constructor (the class that
* instantiated this instance).
*
* @return {Model} The {@link Model} class or subclass constructor used to instantiate
* this instance.
*/
value: function getClass() {
return this.constructor;
Model.options = function options() {
return {};
};
Model._getTableOpts = function _getTableOpts() {
if (typeof this.options === 'function') {
return this.options();
}
return this.options;
};
/**
* Gets the id value of the current instance by looking up the id attribute.
* @return {*} The id value of the current instance.
*/
Model.markAccessed = function markAccessed() {
this.session.markAccessed(this);
};
}, {
key: 'getId',
value: function getId() {
return this._fields[this.getClass().idAttribute];
}
/**
* Returns the id attribute of this {@link Model}.
*
* @return {string} The id attribute of this {@link Model}.
*/
/**
* Returns a reference to the plain JS object in the store.
* Make sure to not mutate this.
*
* @return {Object} a reference to the plain JS object in the store
*/
}, {
key: 'toString',
/**
* Connect the model class to a {@link Session}.
*
* @private
* @param {Session} session - The session to connect to.
*/
Model.connect = function connect(session) {
if (!session instanceof _Session2.default) {
throw Error('A model can only connect to a Session instance.');
}
this._session = session;
};
/**
* Get the current {@link Session} instance.
*
* @private
* @return {Session} The current {@link Session} instance.
*/
/**
* Returns a string representation of the {@link Model} instance.
*
* @return {string} A string representation of this {@link Model} instance.
*/
value: function toString() {
var _this2 = this;
var ThisModel = this.getClass();
var className = ThisModel.modelName;
var fieldNames = (0, _keys2.default)(ThisModel.fields);
var fields = fieldNames.map(function (fieldName) {
var field = ThisModel.fields[fieldName];
if (field instanceof _fields.ManyToMany) {
var ids = _this2[fieldName].toModelArray().map(function (model) {
return model.getId();
});
return fieldName + ': [' + ids.join(', ') + ']';
}
var val = _this2._fields[fieldName];
return fieldName + ': ' + val;
}).join(', ');
return className + ': {' + fields + '}';
}
Model.getQuerySet = function getQuerySet() {
var QuerySetClass = this.querySetClass;
return new QuerySetClass(this);
};
/**
* Returns a boolean indicating if `otherModel` equals this {@link Model} instance.
* Equality is determined by shallow comparing their attributes.
*
* @param {Model} otherModel - a {@link Model} instance to compare
* @return {Boolean} a boolean indicating if the {@link Model} instance's are equal.
*/
Model.invalidateClassCache = function invalidateClassCache() {
this.isSetUp = undefined;
this.virtualFields = {};
};
}, {
key: 'equals',
value: function equals(otherModel) {
return (0, _utils.objectShallowEquals)(this._fields, otherModel._fields);
}
/**
* Returns a {@link QuerySet} containing all {@link Model} instances.
* @return {QuerySet} a QuerySet containing all {@link Model} instances
*/
Model.all = function all() {
return this.getQuerySet();
};
/**
* Updates a property name to given value for this {@link Model} instance.
* The values are immediately committed to the database.
*
* @param {string} propertyName - name of the property to set
* @param {*} value - value assigned to the property
* @return {undefined}
*/
/**
* Creates a new record in the database, instantiates a {@link Model} and returns it.
*
* If you pass values for many-to-many fields, instances are created on the through
* model as well.
*
* @param {props} props - the new {@link Model}'s properties.
* @return {Model} a new {@link Model} instance.
*/
}, {
key: 'set',
value: function set(propertyName, value) {
this.update((0, _defineProperty5.default)({}, propertyName, value));
}
/**
* Assigns multiple fields and corresponding values to this {@link Model} instance.
* The updates are immediately committed to the database.
*
* @param {Object} userMergeObj - an object that will be merged with this instance.
* @return {undefined}
*/
Model.create = function create(userProps) {
var _this2 = this;
}, {
key: 'update',
value: function update(userMergeObj) {
var ThisModel = this.getClass();
var relFields = ThisModel.fields;
var mergeObj = (0, _assign2.default)({}, userMergeObj);
var props = (0, _assign2.default)({}, userProps);
// If an array of entities or id's is supplied for a
// many-to-many related field, clear the old relations
// and add the new ones.
for (var mergeKey in mergeObj) {
// eslint-disable-line no-restricted-syntax
if (relFields.hasOwnProperty(mergeKey)) {
var field = relFields[mergeKey];
if (field instanceof _fields.ManyToMany) {
var currentIds = this[mergeKey].toRefArray().map(function (row) {
return row[ThisModel.idAttribute];
});
var m2mVals = {};
var normalizedNewIds = mergeObj[mergeKey].map(_utils.normalizeEntity);
var diffActions = (0, _utils.arrayDiffActions)(currentIds, normalizedNewIds);
if (diffActions) {
var idsToDelete = diffActions.delete;
var idsToAdd = diffActions.add;
if (idsToDelete.length > 0) {
var _mergeKey;
var declaredFieldNames = (0, _keys2.default)(this.fields);
(_mergeKey = this[mergeKey]).remove.apply(_mergeKey, (0, _toConsumableArray3.default)(idsToDelete));
}
if (idsToAdd.length > 0) {
var _mergeKey2;
declaredFieldNames.forEach(function (key) {
var field = _this2.fields[key];
var valuePassed = userProps.hasOwnProperty(key);
if (!valuePassed && !(field instanceof _fields.ManyToMany)) {
if (field.getDefault) {
props[key] = field.getDefault();
}
} else {
var value = userProps[key];
props[key] = (0, _utils.normalizeEntity)(value);
(_mergeKey2 = this[mergeKey]).add.apply(_mergeKey2, (0, _toConsumableArray3.default)(idsToAdd));
}
}
delete mergeObj[mergeKey];
} else if (field instanceof _fields.ForeignKey || field instanceof _fields.OneToOne) {
mergeObj[mergeKey] = (0, _utils.normalizeEntity)(mergeObj[mergeKey]);
// If a value is supplied for a ManyToMany field,
// discard them from props and save for later processing.
if ((0, _isArray2.default)(value)) {
if (_this2.fields.hasOwnProperty(key) && _this2.fields[key] instanceof _fields.ManyToMany) {
m2mVals[key] = value;
delete props[key];
}
}
}
});
this._initFields((0, _assign2.default)({}, this._fields, mergeObj));
var newEntry = this.session.applyUpdate({
action: _constants.CREATE,
table: this.modelName,
payload: props
});
ThisModel.session.applyUpdate({
action: _constants.UPDATE,
query: getByIdQuery(this),
payload: mergeObj
});
}
var ModelClass = this;
var instance = new ModelClass(newEntry);
/**
* Updates {@link Model} instance attributes to reflect the
* database state in the current session.
* @return {undefined}
*/
(0, _forOwn2.default)(m2mVals, function (value, key) {
var _instance$key;
}, {
key: 'refreshFromState',
value: function refreshFromState() {
this._initFields(this.ref);
}
var ids = value.map(_utils.normalizeEntity);
var uniqueIds = (0, _uniq2.default)(ids);
/**
* Deletes the record for this {@link Model} instance.
* You'll still be able to access fields and values on the instance.
*
* @return {undefined}
*/
}, {
key: 'delete',
value: function _delete() {
this._onDelete();
this.getClass().session.applyUpdate({
action: _constants.DELETE,
query: getByIdQuery(this)
});
}
}, {
key: '_onDelete',
value: function _onDelete() {
var virtualFields = this.getClass().virtualFields;
for (var key in virtualFields) {
// eslint-disable-line
var field = virtualFields[key];
if (field instanceof _fields.ManyToMany) {
// Delete any many-to-many rows the entity is included in.
this[key].clear();
} else if (field instanceof _fields.ForeignKey) {
var relatedQs = this[key];
if (relatedQs.exists()) {
relatedQs.update((0, _defineProperty5.default)({}, field.relatedName, null));
}
} else if (field instanceof _fields.OneToOne) {
// Set null to any foreign keys or one to ones pointed to
// this instance.
if (this[key] !== null) {
this[key][field.relatedName] = null;
}
}
if (ids.length !== uniqueIds.length) {
var idsString = ids;
throw new Error('Found duplicate id(s) when passing "' + idsString + '" to ' + _this2.modelName + '.' + key + ' value on create');
}
}
}, {
key: 'ref',
get: function get() {
var ModelClass = this.getClass();
return ModelClass._findDatabaseRows((0, _defineProperty5.default)({}, ModelClass.idAttribute, this.getId()))[0];
}
}], [{
key: 'toString',
value: function toString() {
return 'ModelClass: ' + this.modelName;
}
(_instance$key = instance[key]).add.apply(_instance$key, (0, _toConsumableArray3.default)(ids));
});
/**
* Returns the options object passed to the database for the table that represents
* this Model class.
*
* Returns an empty object by default, which means the database
* will use default options. You can either override this function to return the options
* you want to use, or assign the options object as a static property of the same name to the
* Model class.
*
* @return {Object} the options object passed to the database for the table
* representing this Model class.
*/
return instance;
};
}, {
key: 'options',
value: function options() {
return {};
/**
* Returns a {@link Model} instance for the object with id `id`.
* This throws if the `id` doesn't exist. Use {@link Model#hasId}
* to check for existence first if you're not certain.
*
* @param {*} id - the `id` of the object to get
* @throws If object with id `id` doesn't exist
* @return {Model} {@link Model} instance with id `id`
*/
Model.withId = function withId(id) {
var ModelClass = this;
var rows = this._findDatabaseRows((0, _defineProperty5.default)({}, ModelClass.idAttribute, id));
if (rows.length === 0) {
throw new Error(ModelClass.modelName + ' instance with id ' + id + ' not found');
}
}, {
key: '_getTableOpts',
value: function _getTableOpts() {
if (typeof this.options === 'function') {
return this.options();
}
return this.options;
}
}, {
key: 'markAccessed',
value: function markAccessed() {
this.session.markAccessed(this);
}
/**
* Returns the id attribute of this {@link Model}.
*
* @return {string} The id attribute of this {@link Model}.
*/
return new ModelClass(rows[0]);
};
}, {
key: 'connect',
/**
* Returns a boolean indicating if an entity with the id `id` exists
* in the state.
*
* @param {*} id - a value corresponding to the id attribute of the {@link Model} class.
* @return {Boolean} a boolean indicating if entity with `id` exists in the state
*/
/**
* Connect the model class to a {@link Session}.
*
* @private
* @param {Session} session - The session to connect to.
*/
value: function connect(session) {
if (!session instanceof _Session2.default) {
throw Error('A model can only connect to a Session instance.');
}
this._session = session;
}
Model.hasId = function hasId(id) {
var rows = this._findDatabaseRows((0, _defineProperty5.default)({}, this.idAttribute, id));
return rows.length === 1;
};
/**
* Get the current {@link Session} instance.
*
* @private
* @return {Session} The current {@link Session} instance.
*/
Model._findDatabaseRows = function _findDatabaseRows(lookupObj) {
var ModelClass = this;
return ModelClass.session.query({
table: ModelClass.modelName,
clauses: [{
type: _constants.FILTER,
payload: lookupObj
}]
}).rows;
};
}, {
key: 'getQuerySet',
value: function getQuerySet() {
var QuerySetClass = this.querySetClass;
return new QuerySetClass(this);
}
}, {
key: 'invalidateClassCache',
value: function invalidateClassCache() {
this.isSetUp = undefined;
this.definedProperties = {};
this.virtualFields = {};
}
}, {
key: 'all',
/**
* Gets the {@link Model} instance that matches properties in `lookupObj`.
* Throws an error if {@link Model} is not found, or multiple records match
* the properties.
*
* @param {Object} lookupObj - the properties used to match a single entity.
* @return {Model} a {@link Model} instance that matches `lookupObj` properties.
*/
/**
* Returns a {@link QuerySet} containing all {@link Model} instances.
* @return {QuerySet} a QuerySet containing all {@link Model} instances
*/
value: function all() {
return this.getQuerySet();
Model.get = function get(lookupObj) {
var ModelClass = this;
var rows = this._findDatabaseRows(lookupObj);
if (rows.length === 0) {
throw new Error('Model instance not found when calling get method');
} else if (rows.length > 1) {
throw new Error('Expected to find a single row in Model.get. Found ' + rows.length + '.');
}
/**
* Creates a new record in the database, instantiates a {@link Model} and returns it.
*
* If you pass values for many-to-many fields, instances are created on the through
* model as well.
*
* @param {props} props - the new {@link Model}'s properties.
* @return {Model} a new {@link Model} instance.
*/
return new ModelClass(rows[0]);
};
}, {
key: 'create',
value: function create(userProps) {
var _this3 = this;
/**
* Gets the {@link Model} class or subclass constructor (the class that
* instantiated this instance).
*
* @return {Model} The {@link Model} class or subclass constructor used to instantiate
* this instance.
*/
var props = (0, _assign2.default)({}, userProps);
var m2mVals = {};
Model.prototype.getClass = function getClass() {
return this.constructor;
};
var allowedFieldNames = (0, _keys2.default)(this.fields);
/**
* Gets the id value of the current instance by looking up the id attribute.
* @return {*} The id value of the current instance.
*/
// We don't check for extra field values passed here;
// the constructor will throw in that case. So we
// only go through the defined fields.
allowedFieldNames.forEach(function (key) {
var field = _this3.fields[key];
var valuePassed = userProps.hasOwnProperty(key);
if (!valuePassed && !(field instanceof _fields.ManyToMany)) {
if (field.getDefault) {
props[key] = field.getDefault();
}
} else {
var value = userProps[key];
props[key] = (0, _utils.normalizeEntity)(value);
// If a value is supplied for a ManyToMany field,
// discard them from props and save for later processing.
if ((0, _isArray2.default)(value)) {
if (_this3.fields.hasOwnProperty(key) && _this3.fields[key] instanceof _fields.ManyToMany) {
m2mVals[key] = value;
delete props[key];
}
}
}
});
Model.prototype.getId = function getId() {
return this._fields[this.getClass().idAttribute];
};
var newEntry = this.session.applyUpdate({
action: _constants.CREATE,
table: this.modelName,
payload: props
});
/**
* Returns a reference to the plain JS object in the store.
* Make sure to not mutate this.
*
* @return {Object} a reference to the plain JS object in the store
*/
var ModelClass = this;
var instance = new ModelClass(newEntry);
(0, _forOwn2.default)(m2mVals, function (value, key) {
var _instance$key;
/**
* Returns a string representation of the {@link Model} instance.
*
* @return {string} A string representation of this {@link Model} instance.
*/
Model.prototype.toString = function toString() {
var _this3 = this;
var ids = value.map(_utils.normalizeEntity);
var uniqueIds = (0, _uniq2.default)(ids);
var ThisModel = this.getClass();
var className = ThisModel.modelName;
var fieldNames = (0, _keys2.default)(ThisModel.fields);
var fields = fieldNames.map(function (fieldName) {
var field = ThisModel.fields[fieldName];
if (field instanceof _fields.ManyToMany) {
var ids = _this3[fieldName].toModelArray().map(function (model) {
return model.getId();
});
return fieldName + ': [' + ids.join(', ') + ']';
}
var val = _this3._fields[fieldName];
return fieldName + ': ' + val;
}).join(', ');
return className + ': {' + fields + '}';
};
if (ids.length !== uniqueIds.length) {
var idsString = ids;
throw new Error('Found duplicate id(s) when passing "' + idsString + '" to ' + _this3.modelName + '.' + key + ' value on create');
}
(_instance$key = instance[key]).add.apply(_instance$key, (0, _toConsumableArray3.default)(ids));
});
/**
* Returns a boolean indicating if `otherModel` equals this {@link Model} instance.
* Equality is determined by shallow comparing their attributes.
*
* @param {Model} otherModel - a {@link Model} instance to compare
* @return {Boolean} a boolean indicating if the {@link Model} instance's are equal.
*/
return instance;
}
/**
* Returns a {@link Model} instance for the object with id `id`.
* This throws if the `id` doesn't exist. Use {@link Model#hasId}
* to check for existence first if you're not certain.
*
* @param {*} id - the `id` of the object to get
* @throws If object with id `id` doesn't exist
* @return {Model} {@link Model} instance with id `id`
*/
Model.prototype.equals = function equals(otherModel) {
return (0, _utils.objectShallowEquals)(this._fields, otherModel._fields);
};
}, {
key: 'withId',
value: function withId(id) {
var ModelClass = this;
var rows = this._findDatabaseRows((0, _defineProperty5.default)({}, ModelClass.idAttribute, id));
if (rows.length === 0) {
throw new Error(ModelClass.modelName + ' instance with id ' + id + ' not found');
}
/**
* Updates a property name to given value for this {@link Model} instance.
* The values are immediately committed to the database.
*
* @param {string} propertyName - name of the property to set
* @param {*} value - value assigned to the property
* @return {undefined}
*/
return new ModelClass(rows[0]);
}
/**
* Returns a boolean indicating if an entity with the id `id` exists
* in the state.
*
* @param {*} id - a value corresponding to the id attribute of the {@link Model} class.
* @return {Boolean} a boolean indicating if entity with `id` exists in the state
*/
Model.prototype.set = function set(propertyName, value) {
this.update((0, _defineProperty5.default)({}, propertyName, value));
};
}, {
key: 'hasId',
value: function hasId(id) {
var rows = this._findDatabaseRows((0, _defineProperty5.default)({}, this.idAttribute, id));
return rows.length === 1;
/**
* Assigns multiple fields and corresponding values to this {@link Model} instance.
* The updates are immediately committed to the database.
*
* @param {Object} userMergeObj - an object that will be merged with this instance.
* @return {undefined}
*/
Model.prototype.update = function update(userMergeObj) {
var ThisModel = this.getClass();
var relFields = ThisModel.fields;
var mergeObj = (0, _assign2.default)({}, userMergeObj);
// If an array of entities or id's is supplied for a
// many-to-many related field, clear the old relations
// and add the new ones.
for (var mergeKey in mergeObj) {
// eslint-disable-line no-restricted-syntax
if (relFields.hasOwnProperty(mergeKey)) {
var field = relFields[mergeKey];
if (field) {
if (field instanceof _fields.ManyToMany) {
var currentIds = this[mergeKey].toRefArray().map(function (row) {
return row[ThisModel.idAttribute];
});
var normalizedNewIds = mergeObj[mergeKey].map(_utils.normalizeEntity);
var diffActions = (0, _utils.arrayDiffActions)(currentIds, normalizedNewIds);
if (diffActions) {
var idsToDelete = diffActions.delete;
var idsToAdd = diffActions.add;
if (idsToDelete.length > 0) {
var _mergeKey;
(_mergeKey = this[mergeKey]).remove.apply(_mergeKey, (0, _toConsumableArray3.default)(idsToDelete));
}
if (idsToAdd.length > 0) {
var _mergeKey2;
(_mergeKey2 = this[mergeKey]).add.apply(_mergeKey2, (0, _toConsumableArray3.default)(idsToAdd));
}
}
delete mergeObj[mergeKey];
} else if (field instanceof _fields.ForeignKey || field instanceof _fields.OneToOne) {
mergeObj[mergeKey] = (0, _utils.normalizeEntity)(mergeObj[mergeKey]);
}
}
}
}
}, {
key: '_findDatabaseRows',
value: function _findDatabaseRows(lookupObj) {
var ModelClass = this;
return ModelClass.session.query({
table: ModelClass.modelName,
clauses: [{
type: _constants.FILTER,
payload: lookupObj
}]
}).rows;
}
/**
* Gets the {@link Model} instance that matches properties in `lookupObj`.
* Throws an error if {@link Model} is not found, or multiple records match
* the properties.
*
* @param {Object} lookupObj - the properties used to match a single entity.
* @return {Model} a {@link Model} instance that matches `lookupObj` properties.
*/
this._initFields((0, _assign2.default)({}, this._fields, mergeObj));
}, {
key: 'get',
value: function get(lookupObj) {
var ModelClass = this;
ThisModel.session.applyUpdate({
action: _constants.UPDATE,
query: getByIdQuery(this),
payload: mergeObj
});
};
var rows = this._findDatabaseRows(lookupObj);
/**
* Updates {@link Model} instance attributes to reflect the
* database state in the current session.
* @return {undefined}
*/
if (rows.length === 0) {
throw new Error('Model instance not found when calling get method');
} else if (rows.length > 1) {
throw new Error('Expected to find a single row in Model.get. Found ' + rows.length + '.');
Model.prototype.refreshFromState = function refreshFromState() {
this._initFields(this.ref);
};
/**
* Deletes the record for this {@link Model} instance.
* You'll still be able to access fields and values on the instance.
*
* @return {undefined}
*/
Model.prototype.delete = function _delete() {
this._onDelete();
this.getClass().session.applyUpdate({
action: _constants.DELETE,
query: getByIdQuery(this)
});
};
Model.prototype._onDelete = function _onDelete() {
var virtualFields = this.getClass().virtualFields;
for (var key in virtualFields) {
// eslint-disable-line
var field = virtualFields[key];
if (field instanceof _fields.ManyToMany) {
// Delete any many-to-many rows the entity is included in.
this[key].clear();
} else if (field instanceof _fields.ForeignKey) {
var relatedQs = this[key];
if (relatedQs.exists()) {
relatedQs.update((0, _defineProperty5.default)({}, field.relatedName, null));
}
} else if (field instanceof _fields.OneToOne) {
// Set null to any foreign keys or one to ones pointed to
// this instance.
if (this[key] !== null) {
this[key][field.relatedName] = null;
}
}
}
};
return new ModelClass(rows[0]);
// DEPRECATED AND REMOVED METHODS
Model.prototype.getNextState = function getNextState() {
throw new Error('Model.prototype.getNextState is removed. See the 0.9 ' + 'migration guide on the GitHub repo.');
};
(0, _createClass3.default)(Model, [{
key: 'ref',
get: function get() {
var ModelClass = this.getClass();
return ModelClass._findDatabaseRows((0, _defineProperty5.default)({}, ModelClass.idAttribute, this.getId()))[0];
}
}, {
}], [{
key: '_sessionData',

@@ -613,3 +585,2 @@ get: function get() {

};
Model.definedProperties = {};
Model.virtualFields = {};

@@ -616,0 +587,0 @@ Model.querySetClass = _QuerySet2.default;

@@ -12,6 +12,2 @@ 'use strict';

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

@@ -33,6 +29,2 @@

var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
exports.DeprecatedSchema = DeprecatedSchema;

@@ -111,230 +103,209 @@

(0, _createClass3.default)(ORM, [{
key: 'register',
value: function register() {
var _this = this;
ORM.prototype.register = function register() {
var _this = this;
for (var _len = arguments.length, models = Array(_len), _key = 0; _key < _len; _key++) {
models[_key] = arguments[_key];
}
for (var _len = arguments.length, models = Array(_len), _key = 0; _key < _len; _key++) {
models[_key] = arguments[_key];
}
models.forEach(function (model) {
model.invalidateClassCache();
models.forEach(function (model) {
model.invalidateClassCache();
_this.registerManyToManyModelsFor(model);
_this.registry.push(model);
});
}
}, {
key: 'registerManyToManyModelsFor',
value: function registerManyToManyModelsFor(model) {
var _this3 = this;
_this.registerManyToManyModelsFor(model);
_this.registry.push(model);
});
};
var fields = model.fields;
var thisModelName = model.modelName;
ORM.prototype.registerManyToManyModelsFor = function registerManyToManyModelsFor(model) {
var _this3 = this;
(0, _forOwn2.default)(fields, function (fieldInstance, fieldName) {
if (fieldInstance instanceof _fields.ManyToMany && !fieldInstance.through) {
var _Through$fields;
var fields = model.fields;
var thisModelName = model.modelName;
var toModelName = void 0;
if (fieldInstance.toModelName === 'this') {
toModelName = thisModelName;
} else {
toModelName = fieldInstance.toModelName;
(0, _forOwn2.default)(fields, function (fieldInstance, fieldName) {
if (fieldInstance instanceof _fields.ManyToMany && !fieldInstance.through) {
var _Through$fields;
var toModelName = void 0;
if (fieldInstance.toModelName === 'this') {
toModelName = thisModelName;
} else {
toModelName = fieldInstance.toModelName;
}
var fromFieldName = (0, _utils.m2mFromFieldName)(thisModelName);
var toFieldName = (0, _utils.m2mToFieldName)(toModelName);
var Through = function (_Model) {
(0, _inherits3.default)(ThroughModel, _Model);
function ThroughModel() {
(0, _classCallCheck3.default)(this, ThroughModel);
return (0, _possibleConstructorReturn3.default)(this, _Model.apply(this, arguments));
}
var fromFieldName = (0, _utils.m2mFromFieldName)(thisModelName);
var toFieldName = (0, _utils.m2mToFieldName)(toModelName);
return ThroughModel;
}(_Model3.default);
var Through = function (_Model) {
(0, _inherits3.default)(ThroughModel, _Model);
Through.modelName = (0, _utils.m2mName)(thisModelName, fieldName);
function ThroughModel() {
(0, _classCallCheck3.default)(this, ThroughModel);
return (0, _possibleConstructorReturn3.default)(this, (ThroughModel.__proto__ || (0, _getPrototypeOf2.default)(ThroughModel)).apply(this, arguments));
}
Through.fields = (_Through$fields = {
id: (0, _fields.attr)()
}, (0, _defineProperty3.default)(_Through$fields, fromFieldName, new _fields.ForeignKey(thisModelName)), (0, _defineProperty3.default)(_Through$fields, toFieldName, new _fields.ForeignKey(toModelName)), _Through$fields);
return ThroughModel;
}(_Model3.default);
Through.invalidateClassCache();
_this3.implicitThroughModels.push(Through);
}
});
};
Through.modelName = (0, _utils.m2mName)(thisModelName, fieldName);
/**
* Gets a {@link Model} class by its name from the registry.
* @param {string} modelName - the name of the {@link Model} class to get
* @throws If {@link Model} class is not found.
* @return {Model} the {@link Model} class, if found
*/
Through.fields = (_Through$fields = {
id: (0, _fields.attr)()
}, (0, _defineProperty3.default)(_Through$fields, fromFieldName, new _fields.ForeignKey(thisModelName)), (0, _defineProperty3.default)(_Through$fields, toFieldName, new _fields.ForeignKey(toModelName)), _Through$fields);
Through.invalidateClassCache();
_this3.implicitThroughModels.push(Through);
}
});
ORM.prototype.get = function get(modelName) {
var found = (0, _find2.default)(this.registry.concat(this.implicitThroughModels), function (model) {
return model.modelName === modelName;
});
if (typeof found === 'undefined') {
throw new Error('Did not find model ' + modelName + ' from registry.');
}
return found;
};
/**
* Gets a {@link Model} class by its name from the registry.
* @param {string} modelName - the name of the {@link Model} class to get
* @throws If {@link Model} class is not found.
* @return {Model} the {@link Model} class, if found
*/
ORM.prototype.getModelClasses = function getModelClasses() {
this._setupModelPrototypes(this.registry);
this._setupModelPrototypes(this.implicitThroughModels);
return this.registry.concat(this.implicitThroughModels);
};
}, {
key: 'get',
value: function get(modelName) {
var found = (0, _find2.default)(this.registry.concat(this.implicitThroughModels), function (model) {
return model.modelName === modelName;
});
ORM.prototype._attachQuerySetMethods = function _attachQuerySetMethods(model) {
var querySetClass = model.querySetClass;
if (typeof found === 'undefined') {
throw new Error('Did not find model ' + modelName + ' from registry.');
}
return found;
}
}, {
key: 'getModelClasses',
value: function getModelClasses() {
this._setupModelPrototypes(this.registry);
this._setupModelPrototypes(this.implicitThroughModels);
return this.registry.concat(this.implicitThroughModels);
}
}, {
key: '_attachQuerySetMethods',
value: function _attachQuerySetMethods(model) {
var querySetClass = model.querySetClass;
(0, _utils.attachQuerySetMethods)(model, querySetClass);
};
(0, _utils.attachQuerySetMethods)(model, querySetClass);
ORM.prototype.isFieldInstalled = function isFieldInstalled(modelName, fieldName) {
return this.installedFields.hasOwnProperty(modelName) ? !!this.installedFields[modelName][fieldName] : false;
};
ORM.prototype.setFieldInstalled = function setFieldInstalled(modelName, fieldName) {
if (!this.installedFields.hasOwnProperty(modelName)) {
this.installedFields[modelName] = {};
}
}, {
key: 'isFieldInstalled',
value: function isFieldInstalled(modelName, fieldName) {
return this.installedFields.hasOwnProperty(modelName) ? !!this.installedFields[modelName][fieldName] : false;
}
}, {
key: 'setFieldInstalled',
value: function setFieldInstalled(modelName, fieldName) {
if (!this.installedFields.hasOwnProperty(modelName)) {
this.installedFields[modelName] = {};
}
this.installedFields[modelName][fieldName] = true;
}
}, {
key: '_setupModelPrototypes',
value: function _setupModelPrototypes(models) {
var _this4 = this;
this.installedFields[modelName][fieldName] = true;
};
models.forEach(function (model) {
if (!model.isSetUp) {
var fields = model.fields;
(0, _forOwn2.default)(fields, function (fieldInstance, fieldName) {
if (!_this4.isFieldInstalled(model.modelName, fieldName)) {
fieldInstance.install(model, fieldName, _this4);
_this4.setFieldInstalled(model.modelName, fieldName);
}
});
_this4._attachQuerySetMethods(model);
model.isSetUp = true;
}
});
}
}, {
key: 'generateSchemaSpec',
value: function generateSchemaSpec() {
var models = this.getModelClasses();
var tables = models.reduce(function (spec, modelClass) {
var tableName = modelClass.modelName;
var tableSpec = modelClass._getTableOpts();
spec[tableName] = (0, _assign2.default)({}, { fields: modelClass.fields }, tableSpec);
return spec;
}, {});
return { tables: tables };
}
}, {
key: 'getDatabase',
value: function getDatabase() {
if (!this.db) {
this.db = this.createDatabase(this.generateSchemaSpec());
ORM.prototype._setupModelPrototypes = function _setupModelPrototypes(models) {
var _this4 = this;
models.forEach(function (model) {
if (!model.isSetUp) {
var fields = model.fields;
(0, _forOwn2.default)(fields, function (fieldInstance, fieldName) {
if (!_this4.isFieldInstalled(model.modelName, fieldName)) {
fieldInstance.install(model, fieldName, _this4);
_this4.setFieldInstalled(model.modelName, fieldName);
}
});
_this4._attachQuerySetMethods(model);
model.isSetUp = true;
}
return this.db;
}
});
};
/**
* Returns the empty database state.
* @return {Object} the empty state
*/
ORM.prototype.generateSchemaSpec = function generateSchemaSpec() {
var models = this.getModelClasses();
var tables = models.reduce(function (spec, modelClass) {
var tableName = modelClass.modelName;
var tableSpec = modelClass._getTableOpts();
spec[tableName] = (0, _assign2.default)({}, { fields: modelClass.fields }, tableSpec);
return spec;
}, {});
return { tables: tables };
};
}, {
key: 'getEmptyState',
value: function getEmptyState() {
return this.getDatabase().getEmptyState();
ORM.prototype.getDatabase = function getDatabase() {
if (!this.db) {
this.db = this.createDatabase(this.generateSchemaSpec());
}
return this.db;
};
/**
* Begins an immutable database session.
*
* @param {Object} state - the state the database manages
* @return {Session} a new {@link Session} instance
*/
/**
* Returns the empty database state.
* @return {Object} the empty state
*/
}, {
key: 'session',
value: function session(state) {
return new _Session2.default(this, this.getDatabase(), state);
}
/**
* Begins a mutable database session.
*
* @param {Object} state - the state the database manages
* @return {Session} a new {@link Session} instance
*/
ORM.prototype.getEmptyState = function getEmptyState() {
return this.getDatabase().getEmptyState();
};
}, {
key: 'mutableSession',
value: function mutableSession(state) {
return new _Session2.default(this, this.getDatabase(), state, true);
}
/**
* Begins an immutable database session.
*
* @param {Object} state - the state the database manages
* @return {Session} a new {@link Session} instance
*/
// DEPRECATED AND REMOVED METHODS
}, {
key: 'withMutations',
value: function withMutations(state) {
(0, _utils.warnDeprecated)('ORM.prototype.withMutations is deprecated. ' + 'Use ORM.prototype.mutableSession instead.');
ORM.prototype.session = function session(state) {
return new _Session2.default(this, this.getDatabase(), state);
};
return this.mutableSession(state);
/**
* Begins a mutable database session.
*
* @param {Object} state - the state the database manages
* @return {Session} a new {@link Session} instance
*/
ORM.prototype.mutableSession = function mutableSession(state) {
return new _Session2.default(this, this.getDatabase(), state, true);
};
// DEPRECATED AND REMOVED METHODS
ORM.prototype.withMutations = function withMutations(state) {
(0, _utils.warnDeprecated)('ORM.prototype.withMutations is deprecated. ' + 'Use ORM.prototype.mutableSession instead.');
return this.mutableSession(state);
};
ORM.prototype.from = function from(state) {
(0, _utils.warnDeprecated)('ORM.prototype.from function is deprecated. ' + 'Use ORM.prototype.session instead.');
return this.session(state);
};
ORM.prototype.reducer = function reducer() {
(0, _utils.warnDeprecated)('ORM.prototype.reducer is deprecated. Access ' + 'the Session.prototype.state property instead.');
return (0, _redux.createReducer)(this);
};
ORM.prototype.createSelector = function createSelector() {
(0, _utils.warnDeprecated)('ORM.prototype.createSelector is deprecated. ' + 'Import `createSelector` from Redux-ORM instead.');
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
}, {
key: 'from',
value: function from(state) {
(0, _utils.warnDeprecated)('ORM.prototype.from function is deprecated. ' + 'Use ORM.prototype.session instead.');
return this.session(state);
}
}, {
key: 'reducer',
value: function reducer() {
(0, _utils.warnDeprecated)('ORM.prototype.reducer is deprecated. Access ' + 'the Session.prototype.state property instead.');
return (0, _redux.createReducer)(this);
}
}, {
key: 'createSelector',
value: function createSelector() {
(0, _utils.warnDeprecated)('ORM.prototype.createSelector is deprecated. ' + 'Import `createSelector` from Redux-ORM instead.');
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _redux.createSelector.apply(undefined, [this].concat(args));
};
return _redux.createSelector.apply(undefined, [this].concat(args));
}
}, {
key: 'getDefaultState',
value: function getDefaultState() {
(0, _utils.warnDeprecated)('ORM.prototype.getDefaultState is deprecated. Use ' + 'the ORM.prototype.getEmptyState instead.');
return this.getEmptyState();
}
}, {
key: 'define',
value: function define() {
throw new Error('ORM.prototype.define is removed. Please define a Model class.');
}
}]);
ORM.prototype.getDefaultState = function getDefaultState() {
(0, _utils.warnDeprecated)('ORM.prototype.getDefaultState is deprecated. Use ' + 'the ORM.prototype.getEmptyState instead.');
return this.getEmptyState();
};
ORM.prototype.define = function define() {
throw new Error('ORM.prototype.define is removed. Please define a Model class.');
};
return ORM;

@@ -341,0 +312,0 @@ }();

@@ -74,258 +74,243 @@ 'use strict';

(0, _createClass3.default)(QuerySet, [{
key: '_new',
value: function _new(clauses, userOpts) {
var opts = (0, _assign2.default)({}, this._opts, userOpts);
return new this.constructor(this.modelClass, clauses, opts);
}
}, {
key: 'toString',
value: function toString() {
var _this = this;
QuerySet.addSharedMethod = function addSharedMethod(methodName) {
this.sharedMethods = this.sharedMethods.concat(methodName);
};
this._evaluate();
var contents = this.rows.map(function (id) {
return _this.modelClass.withId(id).toString();
}).join('\n - ');
return 'QuerySet contents: \n - ' + contents;
}
QuerySet.prototype._new = function _new(clauses, userOpts) {
var opts = (0, _assign2.default)({}, this._opts, userOpts);
return new this.constructor(this.modelClass, clauses, opts);
};
/**
* Returns an array of the plain objects represented by the QuerySet.
* The plain objects are direct references to the store.
*
* @return {Object[]} references to the plain JS objects represented by
* the QuerySet
*/
QuerySet.prototype.toString = function toString() {
var _this = this;
}, {
key: 'toRefArray',
value: function toRefArray() {
this._evaluate();
return this.rows;
}
this._evaluate();
var contents = this.rows.map(function (id) {
return _this.modelClass.withId(id).toString();
}).join('\n - ');
return 'QuerySet contents: \n - ' + contents;
};
/**
* Returns an array of {@link Model} instances represented by the QuerySet.
* @return {Model[]} model instances represented by the QuerySet
*/
/**
* Returns an array of the plain objects represented by the QuerySet.
* The plain objects are direct references to the store.
*
* @return {Object[]} references to the plain JS objects represented by
* the QuerySet
*/
}, {
key: 'toModelArray',
value: function toModelArray() {
this._evaluate();
var ModelClass = this.modelClass;
return this.rows.map(function (props) {
return new ModelClass(props);
});
}
/**
* Returns the number of {@link Model} instances represented by the QuerySet.
*
* @return {number} length of the QuerySet
*/
QuerySet.prototype.toRefArray = function toRefArray() {
this._evaluate();
return this.rows;
};
}, {
key: 'count',
value: function count() {
this._evaluate();
return this.rows.length;
}
/**
* Returns an array of {@link Model} instances represented by the QuerySet.
* @return {Model[]} model instances represented by the QuerySet
*/
/**
* Checks if the {@link QuerySet} instance has any records matching the query
* in the database.
*
* @return {Boolean} `true` if the {@link QuerySet} instance contains entities, else `false`.
*/
}, {
key: 'exists',
value: function exists() {
return Boolean(this.count());
}
QuerySet.prototype.toModelArray = function toModelArray() {
this._evaluate();
var ModelClass = this.modelClass;
return this.rows.map(function (props) {
return new ModelClass(props);
});
};
/**
* Returns the {@link Model} instance at index `index` in the {@link QuerySet} instance if
* `withRefs` flag is set to `false`, or a reference to the plain JavaScript
* object in the model state if `true`.
*
* @param {number} index - index of the model instance to get
* @return {Model|Object} a {@link Model} instance or a plain JavaScript
* object at index `index` in the {@link QuerySet} instance
*/
/**
* Returns the number of {@link Model} instances represented by the QuerySet.
*
* @return {number} length of the QuerySet
*/
}, {
key: 'at',
value: function at(index) {
this._evaluate();
var ModelClass = this.modelClass;
return new ModelClass(this.rows[index]);
}
/**
* Returns the {@link Model} instance at index 0 in the {@link QuerySet} instance.
* @return {Model}
*/
QuerySet.prototype.count = function count() {
this._evaluate();
return this.rows.length;
};
}, {
key: 'first',
value: function first() {
return this.at(0);
}
/**
* Checks if the {@link QuerySet} instance has any records matching the query
* in the database.
*
* @return {Boolean} `true` if the {@link QuerySet} instance contains entities, else `false`.
*/
/**
* Returns the {@link Model} instance at index `QuerySet.count() - 1`
* @return {Model}
*/
}, {
key: 'last',
value: function last() {
this._evaluate();
return this.at(this.rows.length - 1);
}
QuerySet.prototype.exists = function exists() {
return Boolean(this.count());
};
/**
* Returns a new {@link QuerySet} instance with the same entities.
* @return {QuerySet} a new QuerySet with the same entities.
*/
/**
* Returns the {@link Model} instance at index `index` in the {@link QuerySet} instance if
* `withRefs` flag is set to `false`, or a reference to the plain JavaScript
* object in the model state if `true`.
*
* @param {number} index - index of the model instance to get
* @return {Model|Object} a {@link Model} instance or a plain JavaScript
* object at index `index` in the {@link QuerySet} instance
*/
}, {
key: 'all',
value: function all() {
return this._new(this.clauses);
}
/**
* Returns a new {@link QuerySet} instance with entities that match properties in `lookupObj`.
*
* @param {Object} lookupObj - the properties to match objects with.
* @return {QuerySet} a new {@link QuerySet} instance with objects that passed the filter.
*/
QuerySet.prototype.at = function at(index) {
this._evaluate();
var ModelClass = this.modelClass;
return new ModelClass(this.rows[index]);
};
}, {
key: 'filter',
value: function filter(lookupObj) {
var normalizedLookupObj = (typeof lookupObj === 'undefined' ? 'undefined' : (0, _typeof3.default)(lookupObj)) === 'object' ? (0, _mapValues2.default)(lookupObj, _utils.normalizeEntity) : lookupObj;
var filterDescriptor = { type: _constants.FILTER, payload: normalizedLookupObj };
return this._new(this.clauses.concat(filterDescriptor));
}
/**
* Returns the {@link Model} instance at index 0 in the {@link QuerySet} instance.
* @return {Model}
*/
/**
* Returns a new {@link QuerySet} instance with entities that do not match
* properties in `lookupObj`.
*
* @param {Object} lookupObj - the properties to unmatch objects with.
* @return {QuerySet} a new {@link QuerySet} instance with objects that passed the filter.
*/
}, {
key: 'exclude',
value: function exclude(lookupObj) {
var normalizedLookupObj = (typeof lookupObj === 'undefined' ? 'undefined' : (0, _typeof3.default)(lookupObj)) === 'object' ? (0, _mapValues2.default)(lookupObj, _utils.normalizeEntity) : lookupObj;
var excludeDescriptor = { type: _constants.EXCLUDE, payload: normalizedLookupObj };
return this._new(this.clauses.concat(excludeDescriptor));
}
}, {
key: '_evaluate',
value: function _evaluate() {
if (!this._evaluated) {
var session = this.modelClass.session;
var querySpec = {
table: this.modelClass.modelName,
clauses: this.clauses
};
QuerySet.prototype.first = function first() {
return this.at(0);
};
var _session$query = session.query(querySpec),
rows = _session$query.rows;
/**
* Returns the {@link Model} instance at index `QuerySet.count() - 1`
* @return {Model}
*/
this.rows = rows;
this._evaluated = true;
}
}
/**
* Returns a new {@link QuerySet} instance with entities ordered by `iteratees` in ascending
* order, unless otherwise specified. Delegates to `lodash.orderBy`.
*
* @param {string[]|Function[]} iteratees - an array where each item can be a string or a
* function. If a string is supplied, it should
* correspond to property on the entity that will
* determine the order. If a function is supplied,
* it should return the value to order by.
* @param {Boolean[]} [orders] - the sort orders of `iteratees`. If unspecified, all iteratees
* will be sorted in ascending order. `true` and `'asc'`
* correspond to ascending order, and `false` and `'desc`
* to descending order.
* @return {QuerySet} a new {@link QuerySet} with objects ordered by `iteratees`.
*/
QuerySet.prototype.last = function last() {
this._evaluate();
return this.at(this.rows.length - 1);
};
}, {
key: 'orderBy',
value: function orderBy(iteratees, orders) {
var orderByDescriptor = { type: _constants.ORDER_BY, payload: [iteratees, orders] };
return this._new(this.clauses.concat(orderByDescriptor));
}
/**
* Returns a new {@link QuerySet} instance with the same entities.
* @return {QuerySet} a new QuerySet with the same entities.
*/
/**
* Records an update specified with `mergeObj` to all the objects
* in the {@link QuerySet} instance.
*
* @param {Object} mergeObj - an object to merge with all the objects in this
* queryset.
* @return {undefined}
*/
}, {
key: 'update',
value: function update(mergeObj) {
this.modelClass.session.applyUpdate({
action: _constants.UPDATE,
query: {
table: this.modelClass.modelName,
clauses: this.clauses
},
payload: mergeObj
});
this._evaluated = false;
}
QuerySet.prototype.all = function all() {
return this._new(this.clauses);
};
/**
* Records a deletion of all the objects in this {@link QuerySet} instance.
* @return {undefined}
*/
/**
* Returns a new {@link QuerySet} instance with entities that match properties in `lookupObj`.
*
* @param {Object} lookupObj - the properties to match objects with.
* @return {QuerySet} a new {@link QuerySet} instance with objects that passed the filter.
*/
}, {
key: 'delete',
value: function _delete() {
this.toModelArray().forEach(function (model) {
return model._onDelete();
});
this.modelClass.session.applyUpdate({
action: _constants.DELETE,
query: {
table: this.modelClass.modelName,
clauses: this.clauses
}
});
QuerySet.prototype.filter = function filter(lookupObj) {
var normalizedLookupObj = (typeof lookupObj === 'undefined' ? 'undefined' : (0, _typeof3.default)(lookupObj)) === 'object' ? (0, _mapValues2.default)(lookupObj, _utils.normalizeEntity) : lookupObj;
var filterDescriptor = { type: _constants.FILTER, payload: normalizedLookupObj };
return this._new(this.clauses.concat(filterDescriptor));
};
this._evaluated = false;
/**
* Returns a new {@link QuerySet} instance with entities that do not match
* properties in `lookupObj`.
*
* @param {Object} lookupObj - the properties to unmatch objects with.
* @return {QuerySet} a new {@link QuerySet} instance with objects that passed the filter.
*/
QuerySet.prototype.exclude = function exclude(lookupObj) {
var normalizedLookupObj = (typeof lookupObj === 'undefined' ? 'undefined' : (0, _typeof3.default)(lookupObj)) === 'object' ? (0, _mapValues2.default)(lookupObj, _utils.normalizeEntity) : lookupObj;
var excludeDescriptor = { type: _constants.EXCLUDE, payload: normalizedLookupObj };
return this._new(this.clauses.concat(excludeDescriptor));
};
QuerySet.prototype._evaluate = function _evaluate() {
if (!this._evaluated) {
var session = this.modelClass.session;
var querySpec = {
table: this.modelClass.modelName,
clauses: this.clauses
};
var _session$query = session.query(querySpec),
rows = _session$query.rows;
this.rows = rows;
this._evaluated = true;
}
};
// DEPRECATED AND REMOVED METHODS
/**
* Returns a new {@link QuerySet} instance with entities ordered by `iteratees` in ascending
* order, unless otherwise specified. Delegates to `lodash.orderBy`.
*
* @param {string[]|Function[]} iteratees - an array where each item can be a string or a
* function. If a string is supplied, it should
* correspond to property on the entity that will
* determine the order. If a function is supplied,
* it should return the value to order by.
* @param {Boolean[]} [orders] - the sort orders of `iteratees`. If unspecified, all iteratees
* will be sorted in ascending order. `true` and `'asc'`
* correspond to ascending order, and `false` and `'desc`
* to descending order.
* @return {QuerySet} a new {@link QuerySet} with objects ordered by `iteratees`.
*/
}, {
key: 'map',
value: function map() {
throw new Error('QuerySet.prototype.map is removed. ' + 'Call .toModelArray() or .toRefArray() first to map.');
}
}, {
key: 'forEach',
value: function forEach() {
throw new Error('QuerySet.prototype.forEach is removed. ' + 'Call .toModelArray() or .toRefArray() first to iterate.');
}
}, {
QuerySet.prototype.orderBy = function orderBy(iteratees, orders) {
var orderByDescriptor = { type: _constants.ORDER_BY, payload: [iteratees, orders] };
return this._new(this.clauses.concat(orderByDescriptor));
};
/**
* Records an update specified with `mergeObj` to all the objects
* in the {@link QuerySet} instance.
*
* @param {Object} mergeObj - an object to merge with all the objects in this
* queryset.
* @return {undefined}
*/
QuerySet.prototype.update = function update(mergeObj) {
this.modelClass.session.applyUpdate({
action: _constants.UPDATE,
query: {
table: this.modelClass.modelName,
clauses: this.clauses
},
payload: mergeObj
});
this._evaluated = false;
};
/**
* Records a deletion of all the objects in this {@link QuerySet} instance.
* @return {undefined}
*/
QuerySet.prototype.delete = function _delete() {
this.toModelArray().forEach(function (model) {
return model._onDelete();
});
this.modelClass.session.applyUpdate({
action: _constants.DELETE,
query: {
table: this.modelClass.modelName,
clauses: this.clauses
}
});
this._evaluated = false;
};
// DEPRECATED AND REMOVED METHODS
QuerySet.prototype.map = function map() {
throw new Error('QuerySet.prototype.map is removed. ' + 'Call .toModelArray() or .toRefArray() first to map.');
};
QuerySet.prototype.forEach = function forEach() {
throw new Error('QuerySet.prototype.forEach is removed. ' + 'Call .toModelArray() or .toRefArray() first to iterate.');
};
(0, _createClass3.default)(QuerySet, [{
key: 'withModels',

@@ -340,7 +325,2 @@ get: function get() {

}
}], [{
key: 'addSharedMethod',
value: function addSharedMethod(methodName) {
this.sharedMethods = this.sharedMethods.concat(methodName);
}
}]);

@@ -347,0 +327,0 @@ return QuerySet;

@@ -11,6 +11,2 @@ 'use strict';

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

@@ -74,3 +70,3 @@

(0, _classCallCheck3.default)(this, SessionBoundModel);
return (0, _possibleConstructorReturn3.default)(this, (SessionBoundModel.__proto__ || (0, _getPrototypeOf2.default)(SessionBoundModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _modelClass.apply(this, arguments));
}

@@ -91,67 +87,60 @@

(0, _createClass3.default)(Session, [{
key: 'markAccessed',
value: function markAccessed(modelName) {
this.getDataForModel(modelName).accessed = true;
Session.prototype.markAccessed = function markAccessed(modelName) {
this.getDataForModel(modelName).accessed = true;
};
Session.prototype.getDataForModel = function getDataForModel(modelName) {
if (!this.modelData[modelName]) {
this.modelData[modelName] = {};
}
}, {
key: 'getDataForModel',
value: function getDataForModel(modelName) {
if (!this.modelData[modelName]) {
this.modelData[modelName] = {};
}
return this.modelData[modelName];
}
return this.modelData[modelName];
};
/**
* Applies update to a model state.
*
* @private
* @param {Object} update - the update object. Must have keys
* `type`, `payload`.
*/
/**
* Applies update to a model state.
*
* @private
* @param {Object} update - the update object. Must have keys
* `type`, `payload`.
*/
}, {
key: 'applyUpdate',
value: function applyUpdate(updateSpec) {
var batchToken = this.batchToken,
withMutations = this.withMutations;
var tx = { batchToken: batchToken, withMutations: withMutations };
var result = this.db.update(updateSpec, tx, this.state);
var status = result.status,
state = result.state;
Session.prototype.applyUpdate = function applyUpdate(updateSpec) {
var batchToken = this.batchToken,
withMutations = this.withMutations;
var tx = { batchToken: batchToken, withMutations: withMutations };
var result = this.db.update(updateSpec, tx, this.state);
var status = result.status,
state = result.state;
if (status === _constants.SUCCESS) {
this.state = state;
} else {
throw new Error('Applying update failed: ' + result.toString());
}
return result.payload;
if (status === _constants.SUCCESS) {
this.state = state;
} else {
throw new Error('Applying update failed: ' + result.toString());
}
}, {
key: 'query',
value: function query(querySpec) {
var table = querySpec.table;
this.markAccessed(table);
return this.db.query(querySpec, this.state);
}
return result.payload;
};
// DEPRECATED AND REMOVED METHODS
Session.prototype.query = function query(querySpec) {
var table = querySpec.table;
}, {
key: 'getNextState',
value: function getNextState() {
(0, _utils.warnDeprecated)('Session.prototype.getNextState function is deprecated. Access ' + 'the Session.prototype.state property instead.');
return this.state;
}
}, {
key: 'reduce',
value: function reduce() {
throw new Error('Session.prototype.reduce is removed. The Redux integration API ' + 'is now decoupled from ORM and Session - see the 0.9 migration guide ' + 'in the GitHub repo.');
}
}, {
this.markAccessed(table);
return this.db.query(querySpec, this.state);
};
// DEPRECATED AND REMOVED METHODS
Session.prototype.getNextState = function getNextState() {
(0, _utils.warnDeprecated)('Session.prototype.getNextState function is deprecated. Access ' + 'the Session.prototype.state property instead.');
return this.state;
};
Session.prototype.reduce = function reduce() {
throw new Error('Session.prototype.reduce is removed. The Redux integration API ' + 'is now decoupled from ORM and Session - see the 0.9 migration guide ' + 'in the GitHub repo.');
};
(0, _createClass3.default)(Session, [{
key: 'accessedModels',

@@ -158,0 +147,0 @@ get: function get() {

'use strict';
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -341,3 +337,3 @@

(0, _classCallCheck3.default)(this, DefaultFieldModel);
return (0, _possibleConstructorReturn3.default)(this, (DefaultFieldModel.__proto__ || (0, _getPrototypeOf2.default)(DefaultFieldModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model.apply(this, arguments));
}

@@ -446,3 +442,3 @@

(0, _classCallCheck3.default)(this, Item);
return (0, _possibleConstructorReturn3.default)(this, (Item.__proto__ || (0, _getPrototypeOf2.default)(Item)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model2.apply(this, arguments));
}

@@ -449,0 +445,0 @@

'use strict';
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -59,3 +55,3 @@

(0, _classCallCheck3.default)(this, TestModel);
return (0, _possibleConstructorReturn3.default)(this, (TestModel.__proto__ || (0, _getPrototypeOf2.default)(TestModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _BaseModel.apply(this, arguments));
}

@@ -68,2 +64,14 @@

it('make sure intsance methods are enumerable', function () {
// See #29.
var enumerableProps = {};
for (var propName in Model) {
// eslint-disable-line
enumerableProps[propName] = true;
}
expect(enumerableProps.create).to.be.true;
});
it('session getter works correctly', function () {

@@ -93,3 +101,3 @@ expect(Model.session).to.be.undefined;

(0, _classCallCheck3.default)(this, TestModel);
return (0, _possibleConstructorReturn3.default)(this, (TestModel.__proto__ || (0, _getPrototypeOf2.default)(TestModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _BaseModel2.apply(this, arguments));
}

@@ -96,0 +104,0 @@

@@ -7,6 +7,2 @@ 'use strict';

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -58,3 +54,3 @@

(0, _classCallCheck3.default)(this, A);
return (0, _possibleConstructorReturn3.default)(this, (A.__proto__ || (0, _getPrototypeOf2.default)(A)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model.apply(this, arguments));
}

@@ -72,3 +68,3 @@

(0, _classCallCheck3.default)(this, B);
return (0, _possibleConstructorReturn3.default)(this, (B.__proto__ || (0, _getPrototypeOf2.default)(B)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model2.apply(this, arguments));
}

@@ -97,3 +93,3 @@

(0, _classCallCheck3.default)(this, A);
return (0, _possibleConstructorReturn3.default)(this, (A.__proto__ || (0, _getPrototypeOf2.default)(A)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model3.apply(this, arguments));
}

@@ -111,3 +107,3 @@

(0, _classCallCheck3.default)(this, B);
return (0, _possibleConstructorReturn3.default)(this, (B.__proto__ || (0, _getPrototypeOf2.default)(B)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model4.apply(this, arguments));
}

@@ -136,3 +132,3 @@

(0, _classCallCheck3.default)(this, A);
return (0, _possibleConstructorReturn3.default)(this, (A.__proto__ || (0, _getPrototypeOf2.default)(A)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model5.apply(this, arguments));
}

@@ -150,3 +146,3 @@

(0, _classCallCheck3.default)(this, B);
return (0, _possibleConstructorReturn3.default)(this, (B.__proto__ || (0, _getPrototypeOf2.default)(B)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model6.apply(this, arguments));
}

@@ -206,3 +202,3 @@

var initialState = {};
var session = orm.from(initialState);
var session = orm.session(initialState);
expect(session).to.be.instanceOf(_.Session);

@@ -209,0 +205,0 @@ });

'use strict';
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -11,6 +7,2 @@

var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

@@ -174,13 +166,11 @@

(0, _classCallCheck3.default)(this, CustomQuerySet);
return (0, _possibleConstructorReturn3.default)(this, (CustomQuerySet.__proto__ || (0, _getPrototypeOf2.default)(CustomQuerySet)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _QuerySet.apply(this, arguments));
}
(0, _createClass3.default)(CustomQuerySet, [{
key: 'unreleased',
value: function unreleased() {
return this.filter(function (book) {
return book.releaseYear > currentYear;
});
}
}]);
CustomQuerySet.prototype.unreleased = function unreleased() {
return this.filter(function (book) {
return book.releaseYear > currentYear;
});
};
return CustomQuerySet;

@@ -187,0 +177,0 @@ }(_.QuerySet);

@@ -56,3 +56,3 @@ 'use strict';

var session = orm.from(emptyState);
var session = orm.session(emptyState);

@@ -76,3 +76,3 @@ expect(session.Book.session).to.equal(session);

it('marks accessed models', function () {
var session = orm.from(emptyState);
var session = orm.session(emptyState);
expect(session.accessedModels).to.have.length(0);

@@ -79,0 +79,0 @@

@@ -8,6 +8,2 @@ 'use strict';

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

@@ -114,3 +110,3 @@

(0, _classCallCheck3.default)(this, BookModel);
return (0, _possibleConstructorReturn3.default)(this, (BookModel.__proto__ || (0, _getPrototypeOf2.default)(BookModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model.apply(this, arguments));
}

@@ -142,3 +138,3 @@

(0, _classCallCheck3.default)(this, AuthorModel);
return (0, _possibleConstructorReturn3.default)(this, (AuthorModel.__proto__ || (0, _getPrototypeOf2.default)(AuthorModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model2.apply(this, arguments));
}

@@ -169,3 +165,3 @@

(0, _classCallCheck3.default)(this, CoverModel);
return (0, _possibleConstructorReturn3.default)(this, (CoverModel.__proto__ || (0, _getPrototypeOf2.default)(CoverModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model3.apply(this, arguments));
}

@@ -186,3 +182,3 @@

(0, _classCallCheck3.default)(this, GenreModel);
return (0, _possibleConstructorReturn3.default)(this, (GenreModel.__proto__ || (0, _getPrototypeOf2.default)(GenreModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model4.apply(this, arguments));
}

@@ -203,3 +199,3 @@

(0, _classCallCheck3.default)(this, PublisherModel);
return (0, _possibleConstructorReturn3.default)(this, (PublisherModel.__proto__ || (0, _getPrototypeOf2.default)(PublisherModel)).apply(this, arguments));
return (0, _possibleConstructorReturn3.default)(this, _Model5.apply(this, arguments));
}

@@ -206,0 +202,0 @@

{
"name": "redux-orm",
"version": "0.9.0-rc.0",
"version": "0.9.0-rc.1",
"description": "Simple ORM to manage and query your state trees",

@@ -25,2 +25,3 @@ "main": "lib/index.js",

"babel-plugin-transform-runtime": "^6.8.0",
"babel-plugin-transform-es2015-classes": "6.18.0",
"babel-preset-es2015": "^6.6.0",

@@ -27,0 +28,0 @@ "babel-preset-stage-2": "^6.5.0",

@@ -31,3 +31,3 @@ redux-orm

You can declare your models with the ES6 class syntax, extending from `Model`. You should declare all fields you want to persist for a model, including non-relational fields. `redux-orm` supports one-to-one and many-to-many relations in addition to foreign keys (`oneToOne`, `many` and `fk` imports respectively). Non-related properties can be accessed like in normal JavaScript objects.
You can declare your models with the ES6 class syntax, extending from `Model`. You need to declare all your non-relational fields on the Model, and declaring all data fields is recommended as the library doesn't have to redefine getters and setters when instantiating Models. `redux-orm` supports one-to-one and many-to-many relations in addition to foreign keys (`oneToOne`, `many` and `fk` imports respectively). Non-related properties can be accessed like in normal JavaScript objects.

@@ -48,3 +48,3 @@ ```javascript

Book.fields = {
id: attr(), // non-relational field for any value
id: attr(), // non-relational field for any value; optional but highly recommended
name: attr(),

@@ -51,0 +51,0 @@ authors: many('Author', 'books'),

@@ -7,2 +7,18 @@ import difference from 'lodash/difference';

function attrDescriptor(fieldName) {
return {
get() {
return this._fields[fieldName];
},
set(value) {
return this.set(fieldName, value);
},
enumerable: true,
configurable: true,
};
}
// Forwards side a Foreign Key: returns one object.

@@ -181,2 +197,3 @@ // Also works as forwardsOneToOneDescriptor.

export {
attrDescriptor,
forwardManyToOneDescriptor,

@@ -183,0 +200,0 @@ forwardOneToOneDescriptor,

import findKey from 'lodash/findKey';
import {
attrDescriptor,
forwardManyToOneDescriptor,

@@ -31,3 +32,9 @@ backwardManyToOneDescriptor,

install() {}
install(model, fieldName, orm) {
Object.defineProperty(
model.prototype,
fieldName,
attrDescriptor(fieldName)
);
}
};

@@ -64,3 +71,2 @@

);
model.definedProperties[fieldName] = true;

@@ -72,3 +78,8 @@ // Backwards.

if (toModel.definedProperties[backwardsFieldName]) {
const backwardsDescriptor = Object.getOwnPropertyDescriptor(
toModel.prototype,
backwardsFieldName
);
if (backwardsDescriptor) {
const errorMsg = reverseFieldErrorMessage(

@@ -88,3 +99,3 @@ model.modelName,

);
toModel.definedProperties[backwardsFieldName] = true;
const ThisField = this.getClass();

@@ -154,3 +165,3 @@ toModel.virtualFields[backwardsFieldName] = new ThisField(model.modelName, fieldName);

);
model.definedProperties[fieldName] = true;
model.virtualFields[fieldName] = new ManyToMany({

@@ -167,3 +178,8 @@ to: toModel.modelName,

if (toModel.definedProperties[backwardsFieldName]) {
const backwardsDescriptor = Object.getOwnPropertyDescriptor(
toModel.prototype,
backwardsFieldName
);
if (backwardsDescriptor) {
// Backwards field was already defined on toModel.

@@ -190,3 +206,2 @@ const errorMsg = reverseFieldErrorMessage(

);
toModel.definedProperties[backwardsFieldName] = true;
toModel.virtualFields[backwardsFieldName] = new ManyToMany({

@@ -216,3 +231,2 @@ to: model.modelName,

);
model.definedProperties[fieldName] = true;

@@ -224,3 +238,8 @@ // Backwards.

if (toModel.definedProperties[backwardsFieldName]) {
const backwardsDescriptor = Object.getOwnPropertyDescriptor(
toModel.prototype,
backwardsFieldName
);
if (backwardsDescriptor) {
const errorMsg = reverseFieldErrorMessage(

@@ -240,3 +259,2 @@ model.modelName,

);
toModel.definedProperties[backwardsFieldName] = true;
toModel.virtualFields[backwardsFieldName] = new OneToOne(model.modelName, fieldName);

@@ -248,3 +266,5 @@ }

* Defines a value attribute on the model.
* You need to define this for each non-foreign key you wish to use.
* Though not required, it is recommended to define this for each non-foreign key you wish to use.
* Getters and setters need to be defined on each Model
* instantiation for undeclared data fields, which is slower.
* You can use the optional `getDefault` parameter to fill in unpassed values

@@ -251,0 +271,0 @@ * to {@link Model#create}, such as for generating ID's with UUID:

@@ -69,25 +69,18 @@ import forOwn from 'lodash/forOwn';

_initFields(props) {
const ModelClass = this.getClass();
const fieldsDef = this.getClass().fields;
this._fields = Object.assign({}, props);
const ThisModel = this.getClass();
forOwn(props, (fieldValue, fieldName) => {
if (!fieldsDef.hasOwnProperty(fieldName)) {
throw new Error(
`Unexpected field given to ${ModelClass.modelName} constructor: ${fieldName}. ` +
`If ${ModelClass.modelName} should accept this field, ` +
'add an attr() field to it.'
);
}
this._fields[fieldName] = fieldValue;
// If the field has not already been defined on the
// prototype for a relation.
if (!ModelClass.definedProperties[fieldName]) {
// In this case, we got a prop that wasn't defined as a field.
// Assuming it's an arbitrary data field, making an instance-specific
// descriptor for it.
// Using the in operator as the property could be defined anywhere
// on the prototype chain.
if (!(fieldName in this)) {
Object.defineProperty(this, fieldName, {
get: () => this._fields[fieldName],
set: (value) => this.set(fieldName, value),
set: value => this.set(fieldName, value),
configurable: true,
enumerable: true,
});

@@ -173,3 +166,2 @@ }

this.isSetUp = undefined;
this.definedProperties = {};
this.virtualFields = {};

@@ -204,8 +196,5 @@ }

const allowedFieldNames = Object.keys(this.fields);
const declaredFieldNames = Object.keys(this.fields);
// We don't check for extra field values passed here;
// the constructor will throw in that case. So we
// only go through the defined fields.
allowedFieldNames.forEach(key => {
declaredFieldNames.forEach(key => {
const field = this.fields[key];

@@ -419,21 +408,23 @@ const valuePassed = userProps.hasOwnProperty(key);

const field = relFields[mergeKey];
if (field instanceof ManyToMany) {
const currentIds = this[mergeKey].toRefArray()
.map(row => row[ThisModel.idAttribute]);
if (field) {
if (field instanceof ManyToMany) {
const currentIds = this[mergeKey].toRefArray()
.map(row => row[ThisModel.idAttribute]);
const normalizedNewIds = mergeObj[mergeKey].map(normalizeEntity);
const diffActions = arrayDiffActions(currentIds, normalizedNewIds);
if (diffActions) {
const idsToDelete = diffActions.delete;
const idsToAdd = diffActions.add;
if (idsToDelete.length > 0) {
this[mergeKey].remove(...idsToDelete);
const normalizedNewIds = mergeObj[mergeKey].map(normalizeEntity);
const diffActions = arrayDiffActions(currentIds, normalizedNewIds);
if (diffActions) {
const idsToDelete = diffActions.delete;
const idsToAdd = diffActions.add;
if (idsToDelete.length > 0) {
this[mergeKey].remove(...idsToDelete);
}
if (idsToAdd.length > 0) {
this[mergeKey].add(...idsToAdd);
}
}
if (idsToAdd.length > 0) {
this[mergeKey].add(...idsToAdd);
}
delete mergeObj[mergeKey];
} else if (field instanceof ForeignKey || field instanceof OneToOne) {
mergeObj[mergeKey] = normalizeEntity(mergeObj[mergeKey]);
}
delete mergeObj[mergeKey];
} else if (field instanceof ForeignKey || field instanceof OneToOne) {
mergeObj[mergeKey] = normalizeEntity(mergeObj[mergeKey]);
}

@@ -497,2 +488,11 @@ }

}
// DEPRECATED AND REMOVED METHODS
getNextState() {
throw new Error(
'Model.prototype.getNextState is removed. See the 0.9 ' +
'migration guide on the GitHub repo.'
);
}
};

@@ -503,3 +503,2 @@

};
Model.definedProperties = {};
Model.virtualFields = {};

@@ -506,0 +505,0 @@ Model.querySetClass = QuerySet;

@@ -27,2 +27,13 @@ import chai from 'chai';

it('make sure intsance methods are enumerable', () => {
// See #29.
const enumerableProps = {};
for (const propName in Model) { // eslint-disable-line
enumerableProps[propName] = true;
}
expect(enumerableProps.create).to.be.true;
});
it('session getter works correctly', () => {

@@ -29,0 +40,0 @@ expect(Model.session).to.be.undefined;

@@ -106,3 +106,3 @@ import chai from 'chai';

const initialState = {};
const session = orm.from(initialState);
const session = orm.session(initialState);
expect(session).to.be.instanceOf(Session);

@@ -109,0 +109,0 @@ });

@@ -45,3 +45,3 @@ import chai from 'chai';

const session = orm.from(emptyState);
const session = orm.session(emptyState);

@@ -65,3 +65,3 @@ expect(session.Book.session).to.equal(session);

it('marks accessed models', () => {
const session = orm.from(emptyState);
const session = orm.session(emptyState);
expect(session.accessedModels).to.have.length(0);

@@ -68,0 +68,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc