Comparing version
@@ -45,3 +45,3 @@ /* | ||
} else { | ||
this.store = options.store || store; | ||
this.store = options.store || store; | ||
} | ||
@@ -54,3 +54,3 @@ | ||
this.data = JSON.parse(this.store.get(name) || {}); | ||
this._id = Math.max.apply(Math, this.data.map(function (r) { return r.id; })); | ||
this._id = Math.max.apply(Math, this.data.map(function (r) { return r.id; })) + 1; | ||
} | ||
@@ -155,17 +155,61 @@ } else { | ||
Bourne.prototype.update = function (query, update, callback) { | ||
this.find(query, function (err, records) { | ||
records.forEach(function (record) { | ||
for (var prop in update) { | ||
if (update.hasOwnProperty(prop)) { | ||
record[prop] = update[prop]; | ||
} | ||
var updateOperators = { | ||
$set: function (record, params) { | ||
for (var prop in params) { | ||
if (params.hasOwnProperty(prop)) { | ||
record[prop] = params[prop]; | ||
} | ||
}); | ||
} | ||
}, | ||
$unset: function (record, params) { | ||
for (var prop in params) { | ||
if (record.hasOwnProperty(prop)) { | ||
delete record[prop]; | ||
} | ||
} | ||
} | ||
}; | ||
this.store.set(this.name, JSON.stringify(this.data), function () { | ||
callback && callback(null, records); | ||
}); | ||
Bourne.prototype.update = function (query, update, callback) { | ||
var ids = []; | ||
}.bind(this)); | ||
if (update.$set) { | ||
this.find(query, function (err, records) { | ||
records.forEach(function (record) { | ||
updateOperators.$set(record, update.$set); | ||
}); | ||
this.store.set(this.name, JSON.stringify(this.data), function () { | ||
if (callback) callback(null, records); | ||
}.bind(this)); | ||
}.bind(this)); | ||
} else if (update.$unset) { | ||
this.find(query, function (err, records) { | ||
records.forEach(function (record) { | ||
updateOperators.$unset(record, update.$unset); | ||
}); | ||
this.store.set(this.name, JSON.stringify(this.data), function () { | ||
if (callback) callback(null, records); | ||
}.bind(this)); | ||
}.bind(this)); | ||
} else { | ||
this.find(query, function (err, records) { | ||
records.forEach(function (record) { | ||
ids.push(record.id); | ||
}); | ||
this.delete(query, function () { | ||
var updatedRecords = ids.map(function (id) { | ||
var u = JSON.parse(JSON.stringify(update)); | ||
u.id = id; | ||
return u; | ||
}); | ||
this.data = this.data.concat(updatedRecords); | ||
this.store.set(this.name, JSON.stringify(this.data), function () { | ||
if (callback) this.find({ id: { $in: ids }}, callback); | ||
}.bind(this)); | ||
}.bind(this)); | ||
}.bind(this)); | ||
} | ||
}; | ||
@@ -172,0 +216,0 @@ |
{ | ||
"name": "bourne", | ||
"description": "A simple serverless database stored in a JSON file.", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"homepage": "https://github.com/andreww8088/bourne", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -18,14 +18,96 @@ 'use strict'; | ||
this.bourne_test = { | ||
setUp: function(done) { | ||
var db = this.db = new Bourne(testName, { reset: true }); | ||
db.insert(testRecord1, function () { | ||
db.insert(testRecord2, function () { | ||
db.insert(testRecord3, done); | ||
prepopulated: { | ||
setUp: function(done) { | ||
var db = this.db = new Bourne(testName, { reset: true, temp: true }); | ||
db.insert(testRecord1, function () { | ||
db.insert(testRecord2, function () { | ||
db.insert(testRecord3, done); | ||
}); | ||
}); | ||
}); | ||
}, | ||
tearDown: function (done) { | ||
this.db.destroy(); | ||
done(); | ||
}, | ||
}, | ||
tearDown: function (done) { | ||
this.db.destroy(); | ||
done(); | ||
}, | ||
'can find records by one key': function (test) { | ||
this.db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 1, 'should find one record'); | ||
test.equal(records[0].firstname, testRecord1.firstname, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find records by multiple keys': function (test) { | ||
this.db.find({ firstname: testRecord1.firstname, age: testRecord1.age }, function (err, records) { | ||
test.equal(records.length, 1, 'should find one record'); | ||
test.equal(records[0].age, testRecord1.age, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find multiple records': function (test) { | ||
var r = { firstname: testRecord1.firstname, age: c.age() }; | ||
var db = this.db; | ||
db.insert(r, function () { | ||
db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 2, '2 records should be found'); | ||
test.done(); | ||
}); | ||
}); | ||
}, | ||
'can use query operators': function (test) { | ||
var r = { firstname: c.first(), age: 10 }; | ||
var db = this.db; | ||
db.insert(r, function () { | ||
db.find({ age: { $lt: 11 } }, function (err, records) { | ||
test.notEqual(records.length, 0, 'should have at least 1 record'); | ||
test.done(); | ||
}); | ||
}); | ||
}, | ||
'can find a single record': function (test) { | ||
this.db.findOne({ firstname: testRecord1.firstname }, function (err, record) { | ||
test.equal(record.firstname, testRecord1.firstname, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find all records': function (test) { | ||
this.db.find(function (err, records) { | ||
test.equal(records.length, 3, 'should find 3 records'); | ||
test.done(); | ||
}); | ||
}, | ||
'can updated records by replacement': function (test) { | ||
var updatedQuery = { age: 200 }; | ||
this.db.update({ firstname: testRecord1.firstname }, updatedQuery, function (err, records) { | ||
updatedQuery.id = records[0].id; | ||
test.deepEqual(records[0], updatedQuery, 'objects match'); | ||
test.done(); | ||
}); | ||
}, | ||
'can update records with $set operator': function (test) { | ||
this.db.update({ firstname: testRecord1.firstname }, { $set: { firstname: 'XXX' } }, function (err, records) { | ||
test.equal(records[0].firstname, 'XXX', 'name is updated'); | ||
test.done(); | ||
}); | ||
}, | ||
'can update records with $unset operator': function (test) { | ||
this.db.update({ firstname: testRecord1.firstname }, { $unset: { lastname: '' }}, function (err, records) { | ||
test.equal(records[0].lastname, undefined, 'no last name'); | ||
test.done() | ||
}); | ||
}, | ||
'can delete records': function (test) { | ||
var db = this.db; | ||
db.delete({ firstname: testRecord1.firstname }, function () { | ||
db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 0, 'no records should be found'); | ||
test.done(); | ||
}); | ||
}); | ||
} | ||
}, | ||
'can create Bourne instance': function(test) { | ||
@@ -35,3 +117,3 @@ test.expect(1); | ||
test.doesNotThrow(function () { | ||
var db = new Bourne(testName, { reset: true }); | ||
var db = new Bourne(testName, { reset: true, temp: true }); | ||
}); | ||
@@ -43,3 +125,3 @@ | ||
test.expect(2); | ||
var db = new Bourne(testName, { reset: true }); | ||
var db = new Bourne(testName, { reset: true, temp: true }); | ||
db.insert(testRecord1, function (err, record) { | ||
@@ -51,46 +133,39 @@ test.equal(testRecord1.firstname, record.firstname, 'names should be equal'); | ||
}, | ||
'can store record peristently': function (test) { | ||
var db1 = new Bourne(testName, { reset: true }); | ||
db1.insert(testRecord1, function (err, record) { | ||
var db2 = new Bourne(testName); | ||
test.equal(db2.data[0].firstname, testRecord1.firstname, 'names should be equal'); | ||
'can restart indexing at the right number': function (test) { | ||
var str = '[{ "id": 1, "attr": "value" }]'; | ||
if (typeof require !== 'undefined') { | ||
var fs = require('fs'); | ||
fs.writeFileSync(testName, str); | ||
} else { | ||
localStorage.setItem(testName, str); | ||
} | ||
var db = new Bourne(testName, { log: true }); | ||
db.insert(testRecord1, function (err, record) { | ||
test.equal(record.id, 2, 'id should be 2'); | ||
test.done(); | ||
db.destroy(); | ||
}); | ||
}, | ||
'can find records by one key': function (test) { | ||
this.db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 1, 'should find one record'); | ||
test.equal(records[0].firstname, testRecord1.firstname, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find records by multiple keys': function (test) { | ||
this.db.find({ firstname: testRecord1.firstname, age: testRecord1.age }, function (err, records) { | ||
test.equal(records.length, 1, 'should find one record'); | ||
test.equal(records[0].age, testRecord1.age, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find multiple records': function (test) { | ||
var r = { firstname: testRecord1.firstname, age: c.age() }; | ||
var db = this.db; | ||
db.insert(r, function () { | ||
db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 2, '2 records should be found'); | ||
'can restart alternate': function (test) { | ||
var db = new Bourne(testName, { reset: true }); | ||
db.insert(testRecord1, function (err, record) { | ||
test.equal(record.id, 1, 'first ID is 1'); | ||
var db2 = new Bourne(testName, { log: true }); | ||
db2.insert(testRecord2, function (err, record2) { | ||
test.equal(record2.id, 2, 'second ID is 2'); | ||
test.done(); | ||
db.destroy(); | ||
db2.destroy(); | ||
}); | ||
}); | ||
}, | ||
'can use query operators': function (test) { | ||
var r = { firstname: c.first(), age: 10 }; | ||
var db = this.db; | ||
db.insert(r, function () { | ||
db.find({ age: { $lt: 11 } }, function (err, records) { | ||
test.notEqual(records.length, 0, 'should have at least 1 record'); | ||
test.done(); | ||
}); | ||
'can store record persistently': function (test) { | ||
var db1 = new Bourne(testName, { reset: true }); | ||
db1.insert(testRecord1, function (err, record) { | ||
var db2 = new Bourne(testName); | ||
test.equal(db2.data[0].firstname, testRecord1.firstname, 'names should be equal'); | ||
test.done(); | ||
db1.destroy(); | ||
db2.destroy(); | ||
}); | ||
@@ -124,14 +199,2 @@ }, | ||
}, | ||
'can find a single record': function (test) { | ||
this.db.findOne({ firstname: testRecord1.firstname }, function (err, record) { | ||
test.equal(record.firstname, testRecord1.firstname, 'names should be equal'); | ||
test.done(); | ||
}); | ||
}, | ||
'can find all records': function (test) { | ||
this.db.find(function (err, records) { | ||
test.equal(records.length, 3, 'should find 3 records'); | ||
test.done(); | ||
}); | ||
}, | ||
'can insert multiple records': function (test) { | ||
@@ -142,19 +205,5 @@ var db = new Bourne(testName, { reset: true }); | ||
test.done(); | ||
db.destroy(); | ||
}); | ||
}, | ||
'can updated records': function (test) { | ||
this.db.update({ firstname: testRecord1.firstname }, { age: 200 }, function (err, records) { | ||
test.equal(records[0].age, 200, 'age should be updated'); | ||
test.done(); | ||
}); | ||
}, | ||
'can delete records': function (test) { | ||
var db = this.db; | ||
db.delete({ firstname: testRecord1.firstname }, function () { | ||
db.find({ firstname: testRecord1.firstname }, function (err, records) { | ||
test.equal(records.length, 0, 'no records should be found'); | ||
test.done(); | ||
}); | ||
}); | ||
}, | ||
'can work with no persistence': function (test) { | ||
@@ -166,2 +215,4 @@ var db = new Bourne(testName, { temp: true }); | ||
test.done(); | ||
db.destroy(); | ||
db2.destroy(); | ||
}); | ||
@@ -172,3 +223,3 @@ } | ||
function operatorTest(record, query, cb) { | ||
var db = new Bourne(testName, { reset: true }); | ||
var db = new Bourne(testName, { reset: true, temp: true }); | ||
db.insert(record, function () { | ||
@@ -175,0 +226,0 @@ db.find(query, cb); |
86085
4.67%2337
4.01%2
100%