From 6a48bda6c9c30f308f6e7cd7daea66bccb8388df Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Fri, 14 Feb 2020 16:48:51 -0700 Subject: [PATCH 1/4] Updated persistence to work with latest mkdirp. Pulled events back into Datastore to fix multiple bugs due to missing emit and on functions. Fixed db test that was failing due to unhandledRejection exception. --- lib/datastore.js | 2 ++ lib/persistence.js | 8 ++++- test/db.test.js | 85 +++++++++++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/lib/datastore.js b/lib/datastore.js index 46973149..861843cb 100755 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -3,6 +3,7 @@ var customUtils = require('./custom-utils') , async = require('async') , Executor = require('./executor') , Index = require('./indexes') + , util = require('util') , _ = require('underscore') , Persistence = require('./persistence') , Cursor = require('./cursor') @@ -82,6 +83,7 @@ function Datastore (options) { }); } } +util.inherits(Datastore, require('events').EventEmitter); /** * Load the database from the datafile, and trigger the execution of buffered commands if any diff --git a/lib/persistence.js b/lib/persistence.js index 1ca7684e..1fac2f3f 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -73,7 +73,13 @@ Persistence.prototype.ensureDirectoryExists = function (dir, cb) { var callback = cb || function () {} ; - this.storage.mkdirp(dir, function (err) { return callback(err); }); + this.storage.mkdirp(dir) + .then(function (made) { + return callback(); + }) + .catch(function (error) { + return callback(error); + }); }; diff --git a/test/db.test.js b/test/db.test.js index 5e72cab0..099b985d 100755 --- a/test/db.test.js +++ b/test/db.test.js @@ -393,17 +393,38 @@ describe('Database', function () { it('If the callback throws an uncaught exception, do not catch it inside findOne, this is userspace concern', function (done) { var tryCount = 0 , currentUncaughtExceptionHandlers = process.listeners('uncaughtException') + , currentUnhandledRejectionHandlers = process.listeners('unhandledRejection') , i ; process.removeAllListeners('uncaughtException'); + process.removeAllListeners('unhandledRejection'); + + process.on('unhandledRejection', function (ex) { + process.removeAllListeners('uncaughtException'); + process.removeAllListeners('unhandledRejection'); + + for (i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { + process.on('uncaughtException', currentUncaughtExceptionHandlers[i]); + } + for (i = 0; i < currentUnhandledRejectionHandlers.length; i += 1) { + process.on('unhandledRejection', currentUnhandledRejectionHandlers[i]); + } + + ex.message.should.equal('SOME EXCEPTION'); + done(); + }); process.on('uncaughtException', function MINE (ex) { process.removeAllListeners('uncaughtException'); + process.removeAllListeners('unhandledRejection'); for (i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { process.on('uncaughtException', currentUncaughtExceptionHandlers[i]); } + for (i = 0; i < currentUnhandledRejectionHandlers.length; i += 1) { + process.on('unhandledRejection', currentUnhandledRejectionHandlers[i]); + } ex.message.should.equal('SOME EXCEPTION'); done(); @@ -828,7 +849,7 @@ describe('Database', function () { }); }); }); - + it('Can use sort, skip and limit if the callback is not passed to find but to exec', function (done) { d.insert({ a: 2, hello: 'world' }, function () { d.insert({ a: 24, hello: 'earth' }, function () { @@ -843,7 +864,7 @@ describe('Database', function () { }); }); }); - }); + }); }); }); @@ -856,7 +877,7 @@ describe('Database', function () { d.findOne({}).sort({ a: 1 }).exec(function (err, doc) { assert.isNull(err); doc.hello.should.equal('world'); - + // A query d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).exec(function (err, doc) { assert.isNull(err); @@ -1230,13 +1251,13 @@ describe('Database', function () { d.find({}, function (err, docs) { docs.length.should.equal(1); // Default option for upsert is false docs[0].something.should.equal("created ok"); - + // Modifying the returned upserted document doesn't modify the database newDoc.newField = true; d.find({}, function (err, docs) { docs[0].something.should.equal("created ok"); assert.isUndefined(docs[0].newField); - + done(); }); }); @@ -1244,7 +1265,7 @@ describe('Database', function () { }); }); }); - + it('If the update query is a normal object with no modifiers, it is the doc that will be upserted', function (done) { d.update({ $or: [{ a: 4 }, { a: 5 }] }, { hello: 'world', bloup: 'blap' }, { upsert: true }, function (err) { d.find({}, function (err, docs) { @@ -1258,7 +1279,7 @@ describe('Database', function () { }); }); }); - + it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 1', function (done) { d.update({ $or: [{ a: 4 }, { a: 5 }] }, { $set: { hello: 'world' }, $inc: { bloup: 3 } }, { upsert: true }, function (err) { d.find({ hello: 'world' }, function (err, docs) { @@ -1272,7 +1293,7 @@ describe('Database', function () { }); }); }); - + it('If the update query contains modifiers, it is applied to the object resulting from removing all operators from the find query 2', function (done) { d.update({ $or: [{ a: 4 }, { a: 5 }], cac: 'rrr' }, { $set: { hello: 'world' }, $inc: { bloup: 3 } }, { upsert: true }, function (err) { d.find({ hello: 'world' }, function (err, docs) { @@ -1287,7 +1308,7 @@ describe('Database', function () { }); }); }); - + it('Performing upsert with badly formatted fields yields a standard error not an exception', function(done) { d.update({_id: '1234'}, { $set: { $$badfield: 5 }}, { upsert: true }, function(err, doc) { assert.isDefined(err); @@ -1504,7 +1525,7 @@ describe('Database', function () { }); }); }); - + it('Can update without the options arg (will use defaults then)', function (done) { d.insert({ a:1, hello: 'world' }, function (err, doc1) { d.insert({ a:2, hello: 'earth' }, function (err, doc2) { @@ -1517,11 +1538,11 @@ describe('Database', function () { , d2 = _.find(docs, function (doc) { return doc._id === doc2._id }) , d3 = _.find(docs, function (doc) { return doc._id === doc3._id }) ; - + d1.a.should.equal(1); d2.a.should.equal(12); d3.a.should.equal(5); - + done(); }); }); @@ -1875,7 +1896,7 @@ describe('Database', function () { }); }); }); - + it('Can remove without the options arg (will use defaults then)', function (done) { d.insert({ a:1, hello: 'world' }, function (err, doc1) { d.insert({ a:2, hello: 'earth' }, function (err, doc2) { @@ -1888,11 +1909,11 @@ describe('Database', function () { , d2 = _.find(docs, function (doc) { return doc._id === doc2._id }) , d3 = _.find(docs, function (doc) { return doc._id === doc3._id }) ; - + d1.a.should.equal(1); assert.isUndefined(d2); d3.a.should.equal(5); - + done(); }); }); @@ -1936,33 +1957,33 @@ describe('Database', function () { }); }); }); - + it('ensureIndex can be called twice on the same field, the second call will ahve no effect', function (done) { Object.keys(d.indexes).length.should.equal(1); Object.keys(d.indexes)[0].should.equal("_id"); - + d.insert({ planet: "Earth" }, function () { d.insert({ planet: "Mars" }, function () { d.find({}, function (err, docs) { docs.length.should.equal(2); - + d.ensureIndex({ fieldName: "planet" }, function (err) { assert.isNull(err); Object.keys(d.indexes).length.should.equal(2); - Object.keys(d.indexes)[0].should.equal("_id"); - Object.keys(d.indexes)[1].should.equal("planet"); + Object.keys(d.indexes)[0].should.equal("_id"); + Object.keys(d.indexes)[1].should.equal("planet"); d.indexes.planet.getAll().length.should.equal(2); - + // This second call has no effect, documents don't get inserted twice in the index d.ensureIndex({ fieldName: "planet" }, function (err) { assert.isNull(err); Object.keys(d.indexes).length.should.equal(2); - Object.keys(d.indexes)[0].should.equal("_id"); - Object.keys(d.indexes)[1].should.equal("planet"); + Object.keys(d.indexes)[0].should.equal("_id"); + Object.keys(d.indexes)[1].should.equal("planet"); + + d.indexes.planet.getAll().length.should.equal(2); - d.indexes.planet.getAll().length.should.equal(2); - done(); }); }); @@ -2141,19 +2162,19 @@ describe('Database', function () { }); }); }); - + it('Can remove an index', function (done) { d.ensureIndex({ fieldName: 'e' }, function (err) { assert.isNull(err); - + Object.keys(d.indexes).length.should.equal(2); assert.isNotNull(d.indexes.e); - + d.removeIndex("e", function (err) { assert.isNull(err); Object.keys(d.indexes).length.should.equal(1); - assert.isUndefined(d.indexes.e); - + assert.isUndefined(d.indexes.e); + done(); }); }); @@ -2161,7 +2182,7 @@ describe('Database', function () { }); // ==== End of 'ensureIndex and index initialization in database loading' ==== // - + describe('Indexing newly inserted documents', function () { it('Newly inserted documents are indexed', function (done) { @@ -2815,7 +2836,7 @@ describe('Database', function () { assert.isNull(err); Object.keys(db.indexes).length.should.equal(3); Object.keys(db.indexes)[0].should.equal("_id"); - Object.keys(db.indexes)[1].should.equal("planet"); + Object.keys(db.indexes)[1].should.equal("planet"); Object.keys(db.indexes)[2].should.equal("another"); db.indexes._id.getAll().length.should.equal(2); db.indexes.planet.getAll().length.should.equal(2); From 527af06a15c3e85a7e25b600fa87f82c99d44f53 Mon Sep 17 00:00:00 2001 From: bnielsen1965 Date: Mon, 8 Feb 2021 14:23:24 -0700 Subject: [PATCH 2/4] Require minimum of nodejs 10 in travis tests. --- .travis.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0ed593b..62167c88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 6 + - 10 cache: directories: diff --git a/package.json b/package.json index a2d44a1d..da1214f8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nedb-core", - "version": "3.0.6", + "version": "3.0.7", "author": { "name": "Louis Chatriot", "email": "louis.chatriot@gmail.com" From 791bd8f3c7b7d71b1bc6aeb64729c7a39e83e492 Mon Sep 17 00:00:00 2001 From: bnielsen1965 Date: Tue, 9 Feb 2021 12:33:02 -0700 Subject: [PATCH 3/4] Fix Buffer deprecation error in test. --- test_lac/loadAndCrash.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_lac/loadAndCrash.test.js b/test_lac/loadAndCrash.test.js index cbe9bc3b..28dfbb95 100755 --- a/test_lac/loadAndCrash.test.js +++ b/test_lac/loadAndCrash.test.js @@ -104,7 +104,7 @@ fs.writeFile = function(path, data, options, callback_) { }); function writeFd(fd, isUserFd) { - var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, + var buffer = (data instanceof Buffer) ? data : Buffer.from('' + data, options.encoding || 'utf8'); var position = /a/.test(flag) ? null : 0; From 0b03bc384184808b3fe4bbea73b116727c4156ce Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Wed, 12 May 2021 13:32:20 -0700 Subject: [PATCH 4/4] Set dependencies to prevent future breakage. --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index da1214f8..c4804ec8 100755 --- a/package.json +++ b/package.json @@ -21,11 +21,11 @@ "url": "git@github.com:nedb3/nedb3.git" }, "dependencies": { - "async": "latest", - "is": "latest", - "localforage": "latest", - "mkdirp": "latest", - "underscore": "latest" + "async": "^3.2.0", + "is": "^3.3.0", + "localforage": "^1.7.3", + "mkdirp": "^1.0.3", + "underscore": "^1.12.1" }, "devDependencies": { "chai": "latest",