Can now use with any nedb query

pull/2/head
Louis Chatriot 11 years ago
parent 04dd0d3a9c
commit af426c5141
  1. 8
      README.md
  2. 30
      lib/model.js
  3. 89
      test/model.test.js

@ -350,11 +350,15 @@ db.update({ _id: 'id6' }, { $addToSet: { fruits: 'apple' } }, {}, function () {
// If we had used a fruit not in the array, e.g. 'banana', it would have been added to the array
});
// $pull removes all instances of a value from an existing array
// Equality is deep-checked
// $pull removes all values matching a value or even any NeDB query from the array
db.update({ _id: 'id6' }, { $pull: { fruits: 'apple' } }, {}, function () {
// Now the fruits array is ['orange', 'pear']
});
db.update({ _id: 'id6' }, { $pull: { fruits: $in: ['apple', 'pear'] } }, {}, function () {
// Now the fruits array is ['orange']
});
// $each can be used to $push or $addToSet multiple values at once
// This example works the same way with $addToSet

@ -141,7 +141,7 @@ function isPrimitiveType (obj) {
typeof obj === 'string' ||
obj === null ||
util.isDate(obj) ||
util.isArray(obj));
util.isArray(obj));
}
@ -619,21 +619,27 @@ logicalOperators.$not = function (obj, query) {
* @param {Object} query
*/
function match (obj, query) {
var queryKeys = Object.keys(query)
, queryKey, queryValue
, i
;
var queryKeys, queryKey, queryValue, i;
// Primitive query against a primitive type
// This is a bit of a hack since we construct an object with an arbitrary key only to dereference it later
// But I don't have time for a cleaner implementation now
if (isPrimitiveType(obj) || isPrimitiveType(query)) {
return matchQueryPart({ needAKey: obj }, 'needAKey', query);
}
// Normal query
queryKeys = Object.keys(query);
for (i = 0; i < queryKeys.length; i += 1) {
queryKey = queryKeys[i];
queryValue = query[queryKey];
queryKey = queryKeys[i];
queryValue = query[queryKey];
if (queryKey[0] === '$') {
if (queryKey[0] === '$') {
if (!logicalOperators[queryKey]) { throw "Unknown logical operator " + queryKey; }
if (!logicalOperators[queryKey](obj, queryValue)) { return false; }
} else {
} else {
if (!matchQueryPart(obj, queryKey, queryValue)) { return false; }
}
}
}
return true;
@ -645,8 +651,7 @@ function match (obj, query) {
*/
function matchQueryPart (obj, queryKey, queryValue) {
var objValue = getDotValue(obj, queryKey)
, i, keys, firstChars, dollarFirstChars
;
, i, keys, firstChars, dollarFirstChars;
// Check if the object value is an array treat it as an array of { obj, query }
// Where there needs to be at least one match
@ -695,6 +700,7 @@ module.exports.serialize = serialize;
module.exports.deserialize = deserialize;
module.exports.deepCopy = deepCopy;
module.exports.checkObject = checkObject;
module.exports.isPrimitiveType = isPrimitiveType;
module.exports.modify = modify;
module.exports.getDotValue = getDotValue;
module.exports.match = match;

@ -165,10 +165,21 @@ describe('Model', function () {
model.checkObject(obj);
});
it.only('Can check if an object is a primitive or not', function () {
});
it('Can check if an object is a primitive or not', function () {
model.isPrimitiveType(5).should.equal(true);
model.isPrimitiveType('sdsfdfs').should.equal(true);
model.isPrimitiveType(0).should.equal(true);
model.isPrimitiveType(true).should.equal(true);
model.isPrimitiveType(false).should.equal(true);
model.isPrimitiveType(new Date()).should.equal(true);
model.isPrimitiveType([]).should.equal(true);
model.isPrimitiveType([3, 'try']).should.equal(true);
model.isPrimitiveType(null).should.equal(true);
model.isPrimitiveType({}).should.equal(false);
model.isPrimitiveType({ a: 42 }).should.equal(false);
});
}); // ==== End of 'Object checking' ==== //
@ -300,48 +311,48 @@ describe('Model', function () {
_.isEqual(modified, { yup: { subfield: 'changed', yop: 'yes indeed' }, totally: { doesnt: { exist: 'now it does' } } }).should.equal(true);
});
}); // End of '$set modifier'
describe('$unset modifier', function () {
it('Can delete a field, not throwing an error if the field doesnt exist', function () {
var obj, updateQuery, modified;
describe('$unset modifier', function () {
it('Can delete a field, not throwing an error if the field doesnt exist', function () {
var obj, updateQuery, modified;
obj = { yup: 'yes', other: 'also' }
updateQuery = { $unset: { yup: true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, { other: 'also' });
assert.deepEqual(modified, { other: 'also' });
obj = { yup: 'yes', other: 'also' }
updateQuery = { $unset: { nope: true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, obj);
assert.deepEqual(modified, obj);
obj = { yup: 'yes', other: 'also' }
updateQuery = { $unset: { nope: true, other: true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, { yup: 'yes' });
});
assert.deepEqual(modified, { yup: 'yes' });
});
it('Can unset sub-fields and entire nested documents', function () {
var obj, updateQuery, modified;
var obj, updateQuery, modified;
obj = { yup: 'yes', nested: { a: 'also', b: 'yeah' } }
updateQuery = { $unset: { nested: true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, { yup: 'yes' });
assert.deepEqual(modified, { yup: 'yes' });
obj = { yup: 'yes', nested: { a: 'also', b: 'yeah' } }
updateQuery = { $unset: { 'nested.a': true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, { yup: 'yes', nested: { b: 'yeah' } });
assert.deepEqual(modified, { yup: 'yes', nested: { b: 'yeah' } });
obj = { yup: 'yes', nested: { a: 'also', b: 'yeah' } }
updateQuery = { $unset: { 'nested.a': true, 'nested.b': true } }
modified = model.modify(obj, updateQuery);
assert.deepEqual(modified, { yup: 'yes', nested: {} });
assert.deepEqual(modified, { yup: 'yes', nested: {} });
});
}); // End of '$unset modifier'
}); // End of '$unset modifier'
describe('$inc modifier', function () {
it('Throw an error if you try to use it with a non-number or on a non number field', function () {
@ -545,7 +556,7 @@ describe('Model', function () {
}); // End of '$pop modifier'
describe.skip('$pull modifier', function () {
describe('$pull modifier', function () {
it('Can remove an element from a set', function () {
var obj = { arr: ['hello', 'world'] }
@ -587,19 +598,19 @@ describe('Model', function () {
modified = model.modify(obj, { $pull: { arr: { b: 3 } } });
assert.deepEqual(modified, { arr: [{ b: 2 }] });
});
it('Can use any kind of nedb query with $pull', function () {
var obj = { arr: [4, 7, 12, 2], other: 'yup' }
, modified
;
// modified = model.modify(obj, { $pull: { arr: { $gte: 5 } } });
// assert.deepEqual(modified, { arr: [4, 2], other: 'yup' });
// obj = { arr: [{ b: 4 }, { b: 7 }, { b: 1 }], other: 'yeah' };
// modified = model.modify(obj, { $pull: { arr: { b: { $gte: 5} } } });
// assert.deepEqual(modified, { arr: [{ b: 4 }, { b: 1 }], other: 'yeah' });
});
it('Can use any kind of nedb query with $pull', function () {
var obj = { arr: [4, 7, 12, 2], other: 'yup' }
, modified
;
modified = model.modify(obj, { $pull: { arr: { $gte: 5 } } });
assert.deepEqual(modified, { arr: [4, 2], other: 'yup' });
obj = { arr: [{ b: 4 }, { b: 7 }, { b: 1 }], other: 'yeah' };
modified = model.modify(obj, { $pull: { arr: { b: { $gte: 5} } } });
assert.deepEqual(modified, { arr: [{ b: 4 }, { b: 1 }], other: 'yeah' });
});
}); // End of '$pull modifier'

Loading…
Cancel
Save