mirror of https://github.com/seald/nedb
parent
aa3302e5dc
commit
185ae680b8
@ -1,22 +0,0 @@ |
|||||||
(The MIT License) |
|
||||||
|
|
||||||
Copyright (c) 2013 Louis Chatriot <louis.chatriot@gmail.com> |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining |
|
||||||
a copy of this software and associated documentation files (the |
|
||||||
'Software'), to deal in the Software without restriction, including |
|
||||||
without limitation the rights to use, copy, modify, merge, publish, |
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to |
|
||||||
permit persons to whom the Software is furnished to do so, subject to |
|
||||||
the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be |
|
||||||
included in all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, |
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
@ -0,0 +1,19 @@ |
|||||||
|
Copyright (c) 2013 Louis Chatriot <louis.chatriot@gmail.com> |
||||||
|
Copyright (c) 2021 Seald [contact@seald.io](mailto:contact@seald.io); |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||||
|
this software and associated documentation files (the |
||||||
|
'Software'), to deal in the Software without restriction, including without |
||||||
|
limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
sublicense, and/or sell copies of the Software, and to permit persons to whom |
||||||
|
the Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -1,51 +1,48 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const Datastore = require('../lib/datastore') |
||||||
, benchDb = 'workspace/insert.bench.db' |
const benchDb = 'workspace/insert.bench.db' |
||||||
, async = require('async') |
const async = require('async') |
||||||
, commonUtilities = require('./commonUtilities') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const ExecTime = require('exec-time') |
||||||
, profiler = new execTime('INSERT BENCH') |
const profiler = new ExecTime('INSERT BENCH') |
||||||
, d = new Datastore(benchDb) |
const d = new Datastore(benchDb) |
||||||
, program = require('commander') |
const program = require('commander') |
||||||
, n |
|
||||||
; |
|
||||||
|
|
||||||
program |
program |
||||||
.option('-n --number [number]', 'Size of the collection to test on', parseInt) |
.option('-n --number [number]', 'Size of the collection to test on', parseInt) |
||||||
.option('-i --with-index', 'Test with an index') |
.option('-i --with-index', 'Test with an index') |
||||||
.parse(process.argv); |
.parse(process.argv) |
||||||
|
|
||||||
n = program.number || 10000; |
const n = program.number || 10000 |
||||||
|
|
||||||
console.log("----------------------------"); |
console.log('----------------------------') |
||||||
console.log("Test with " + n + " documents"); |
console.log('Test with ' + n + ' documents') |
||||||
console.log("----------------------------"); |
console.log('----------------------------') |
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, function (cb) { |
function (cb) { |
||||||
var i; |
let i |
||||||
|
|
||||||
profiler.step('Begin calling ensureIndex ' + n + ' times'); |
profiler.step('Begin calling ensureIndex ' + n + ' times') |
||||||
|
|
||||||
for (i = 0; i < n; i += 1) { |
for (i = 0; i < n; i += 1) { |
||||||
d.ensureIndex({ fieldName: 'docNumber' }); |
d.ensureIndex({ fieldName: 'docNumber' }) |
||||||
delete d.indexes.docNumber; |
delete d.indexes.docNumber |
||||||
} |
} |
||||||
|
|
||||||
console.log("Average time for one ensureIndex: " + (profiler.elapsedSinceLastStep() / n) + "ms"); |
console.log('Average time for one ensureIndex: ' + (profiler.elapsedSinceLastStep() / n) + 'ms') |
||||||
profiler.step('Finished calling ensureIndex ' + n + ' times'); |
profiler.step('Finished calling ensureIndex ' + n + ' times') |
||||||
} |
} |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
|
||||||
}); |
|
||||||
|
|
||||||
|
if (err) { return console.log('An error was encountered: ', err) } |
||||||
|
}) |
||||||
|
@ -1,30 +1,26 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/find.bench.db' |
||||||
, benchDb = 'workspace/find.bench.db' |
const async = require('async') |
||||||
, fs = require('fs') |
const ExecTime = require('exec-time') |
||||||
, path = require('path') |
const profiler = new ExecTime('FIND BENCH') |
||||||
, async = require('async') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, profiler = new execTime('FIND BENCH') |
const d = config.d |
||||||
, commonUtilities = require('./commonUtilities') |
const n = config.n |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
|
||||||
, d = config.d |
|
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }); } |
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, async.apply(commonUtilities.findDocs, d, n, profiler) |
async.apply(commonUtilities.findDocs, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,31 +1,27 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/findOne.bench.db' |
||||||
, benchDb = 'workspace/findOne.bench.db' |
const async = require('async') |
||||||
, fs = require('fs') |
const ExecTime = require('exec-time') |
||||||
, path = require('path') |
const profiler = new ExecTime('FINDONE BENCH') |
||||||
, async = require('async') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, profiler = new execTime('FINDONE BENCH') |
const d = config.d |
||||||
, commonUtilities = require('./commonUtilities') |
const n = config.n |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
|
||||||
, d = config.d |
|
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }); } |
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, function (cb) { setTimeout(function () {cb();}, 500); } |
function (cb) { setTimeout(function () { cb() }, 500) }, |
||||||
, async.apply(commonUtilities.findOneDocs, d, n, profiler) |
async.apply(commonUtilities.findOneDocs, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,30 +1,26 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/find.bench.db' |
||||||
, benchDb = 'workspace/find.bench.db' |
const async = require('async') |
||||||
, fs = require('fs') |
const ExecTime = require('exec-time') |
||||||
, path = require('path') |
const profiler = new ExecTime('FIND BENCH') |
||||||
, async = require('async') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, profiler = new execTime('FIND BENCH') |
const d = config.d |
||||||
, commonUtilities = require('./commonUtilities') |
const n = config.n |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
|
||||||
, d = config.d |
|
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }); } |
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, async.apply(commonUtilities.findDocsWithIn, d, n, profiler) |
async.apply(commonUtilities.findDocsWithIn, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,33 +1,31 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/insert.bench.db' |
||||||
, benchDb = 'workspace/insert.bench.db' |
const async = require('async') |
||||||
, async = require('async') |
const ExecTime = require('exec-time') |
||||||
, execTime = require('exec-time') |
const profiler = new ExecTime('INSERT BENCH') |
||||||
, profiler = new execTime('INSERT BENCH') |
const commonUtilities = require('./commonUtilities') |
||||||
, commonUtilities = require('./commonUtilities') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
const d = config.d |
||||||
, d = config.d |
let n = config.n |
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { |
if (config.program.withIndex) { |
||||||
d.ensureIndex({ fieldName: 'docNumber' }); |
d.ensureIndex({ fieldName: 'docNumber' }) |
||||||
n = 2 * n; // We will actually insert twice as many documents
|
n = 2 * n // We will actually insert twice as many documents
|
||||||
// because the index is slower when the collection is already
|
// because the index is slower when the collection is already
|
||||||
// big. So the result given by the algorithm will be a bit worse than
|
// big. So the result given by the algorithm will be a bit worse than
|
||||||
// actual performance
|
// actual performance
|
||||||
} |
} |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,38 +1,34 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const Datastore = require('../lib/datastore') |
||||||
, benchDb = 'workspace/loaddb.bench.db' |
const benchDb = 'workspace/loaddb.bench.db' |
||||||
, fs = require('fs') |
const async = require('async') |
||||||
, path = require('path') |
const commonUtilities = require('./commonUtilities') |
||||||
, async = require('async') |
const ExecTime = require('exec-time') |
||||||
, commonUtilities = require('./commonUtilities') |
const profiler = new ExecTime('LOADDB BENCH') |
||||||
, execTime = require('exec-time') |
const d = new Datastore(benchDb) |
||||||
, profiler = new execTime('LOADDB BENCH') |
const program = require('commander') |
||||||
, d = new Datastore(benchDb) |
|
||||||
, program = require('commander') |
|
||||||
, n |
|
||||||
; |
|
||||||
|
|
||||||
program |
program |
||||||
.option('-n --number [number]', 'Size of the collection to test on', parseInt) |
.option('-n --number [number]', 'Size of the collection to test on', parseInt) |
||||||
.option('-i --with-index', 'Test with an index') |
.option('-i --with-index', 'Test with an index') |
||||||
.parse(process.argv); |
.parse(process.argv) |
||||||
|
|
||||||
n = program.number || 10000; |
const n = program.number || 10000 |
||||||
|
|
||||||
console.log("----------------------------"); |
console.log('----------------------------') |
||||||
console.log("Test with " + n + " documents"); |
console.log('Test with ' + n + ' documents') |
||||||
console.log(program.withIndex ? "Use an index" : "Don't use an index"); |
console.log(program.withIndex ? 'Use an index' : "Don't use an index") |
||||||
console.log("----------------------------"); |
console.log('----------------------------') |
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(cb); |
d.loadDatabase(cb) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, async.apply(commonUtilities.loadDatabase, d, n, profiler) |
async.apply(commonUtilities.loadDatabase, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,38 +1,34 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/remove.bench.db' |
||||||
, benchDb = 'workspace/remove.bench.db' |
const async = require('async') |
||||||
, fs = require('fs') |
const ExecTime = require('exec-time') |
||||||
, path = require('path') |
const profiler = new ExecTime('REMOVE BENCH') |
||||||
, async = require('async') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, profiler = new execTime('REMOVE BENCH') |
const d = config.d |
||||||
, commonUtilities = require('./commonUtilities') |
const n = config.n |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
|
||||||
, d = config.d |
|
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }); } |
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
|
|
||||||
// Test with remove only one document
|
// Test with remove only one document
|
||||||
, function (cb) { profiler.step('MULTI: FALSE'); return cb(); } |
function (cb) { profiler.step('MULTI: FALSE'); return cb() }, |
||||||
, async.apply(commonUtilities.removeDocs, { multi: false }, d, n, profiler) |
async.apply(commonUtilities.removeDocs, { multi: false }, d, n, profiler), |
||||||
// Test with multiple documents
|
// Test with multiple documents
|
||||||
, function (cb) { d.remove({}, { multi: true }, function () { return cb(); }); } |
function (cb) { d.remove({}, { multi: true }, function () { return cb() }) }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, function (cb) { profiler.step('MULTI: TRUE'); return cb(); } |
function (cb) { profiler.step('MULTI: TRUE'); return cb() }, |
||||||
, async.apply(commonUtilities.removeDocs, { multi: true }, d, n, profiler) |
async.apply(commonUtilities.removeDocs, { multi: true }, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,39 +1,36 @@ |
|||||||
var Datastore = require('../lib/datastore') |
const benchDb = 'workspace/update.bench.db' |
||||||
, benchDb = 'workspace/update.bench.db' |
const async = require('async') |
||||||
, fs = require('fs') |
const ExecTime = require('exec-time') |
||||||
, path = require('path') |
const profiler = new ExecTime('UPDATE BENCH') |
||||||
, async = require('async') |
const commonUtilities = require('./commonUtilities') |
||||||
, execTime = require('exec-time') |
const config = commonUtilities.getConfiguration(benchDb) |
||||||
, profiler = new execTime('UPDATE BENCH') |
const d = config.d |
||||||
, commonUtilities = require('./commonUtilities') |
const n = config.n |
||||||
, config = commonUtilities.getConfiguration(benchDb) |
|
||||||
, d = config.d |
|
||||||
, n = config.n |
|
||||||
; |
|
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
async.apply(commonUtilities.prepareDb, benchDb) |
async.apply(commonUtilities.prepareDb, benchDb), |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }); } |
if (config.program.withIndex) { d.ensureIndex({ fieldName: 'docNumber' }) } |
||||||
cb(); |
cb() |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { profiler.beginProfiling(); return cb(); } |
function (cb) { profiler.beginProfiling(); return cb() }, |
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
|
|
||||||
// Test with update only one document
|
// Test with update only one document
|
||||||
, function (cb) { profiler.step('MULTI: FALSE'); return cb(); } |
function (cb) { profiler.step('MULTI: FALSE'); return cb() }, |
||||||
, async.apply(commonUtilities.updateDocs, { multi: false }, d, n, profiler) |
async.apply(commonUtilities.updateDocs, { multi: false }, d, n, profiler), |
||||||
|
|
||||||
// Test with multiple documents
|
// Test with multiple documents
|
||||||
, function (cb) { d.remove({}, { multi: true }, function (err) { return cb(); }); } |
// eslint-disable-next-line node/handle-callback-err
|
||||||
, async.apply(commonUtilities.insertDocs, d, n, profiler) |
function (cb) { d.remove({}, { multi: true }, function (err) { return cb() }) }, |
||||||
, function (cb) { profiler.step('MULTI: TRUE'); return cb(); } |
async.apply(commonUtilities.insertDocs, d, n, profiler), |
||||||
, async.apply(commonUtilities.updateDocs, { multi: true }, d, n, profiler) |
function (cb) { profiler.step('MULTI: TRUE'); return cb() }, |
||||||
|
async.apply(commonUtilities.updateDocs, { multi: true }, d, n, profiler) |
||||||
], function (err) { |
], function (err) { |
||||||
profiler.step("Benchmark finished"); |
profiler.step('Benchmark finished') |
||||||
|
|
||||||
if (err) { return console.log("An error was encountered: ", err); } |
if (err) { return console.log('An error was encountered: ', err) } |
||||||
}); |
}) |
||||||
|
@ -1,3 +1,3 @@ |
|||||||
var Datastore = require('./lib/datastore'); |
const Datastore = require('./lib/datastore') |
||||||
|
|
||||||
module.exports = Datastore; |
module.exports = Datastore |
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,20 @@ |
|||||||
var should = require('chai').should() |
/* eslint-env mocha */ |
||||||
, assert = require('chai').assert |
const chai = require('chai') |
||||||
, customUtils = require('../lib/customUtils') |
const customUtils = require('../lib/customUtils') |
||||||
, fs = require('fs') |
|
||||||
; |
|
||||||
|
|
||||||
|
|
||||||
|
chai.should() |
||||||
describe('customUtils', function () { |
describe('customUtils', function () { |
||||||
|
|
||||||
describe('uid', function () { |
describe('uid', function () { |
||||||
|
|
||||||
it('Generates a string of the expected length', function () { |
it('Generates a string of the expected length', function () { |
||||||
customUtils.uid(3).length.should.equal(3); |
customUtils.uid(3).length.should.equal(3) |
||||||
customUtils.uid(16).length.should.equal(16); |
customUtils.uid(16).length.should.equal(16) |
||||||
customUtils.uid(42).length.should.equal(42); |
customUtils.uid(42).length.should.equal(42) |
||||||
customUtils.uid(1000).length.should.equal(1000); |
customUtils.uid(1000).length.should.equal(1000) |
||||||
}); |
}) |
||||||
|
|
||||||
// Very small probability of conflict
|
// Very small probability of conflict
|
||||||
it('Generated uids should not be the same', function () { |
it('Generated uids should not be the same', function () { |
||||||
customUtils.uid(56).should.not.equal(customUtils.uid(56)); |
customUtils.uid(56).should.not.equal(customUtils.uid(56)) |
||||||
}); |
}) |
||||||
|
}) |
||||||
}); |
}) |
||||||
|
|
||||||
}); |
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,213 +1,215 @@ |
|||||||
var should = require('chai').should() |
/* eslint-env mocha */ |
||||||
, assert = require('chai').assert |
const chai = require('chai') |
||||||
, testDb = 'workspace/test.db' |
const testDb = 'workspace/test.db' |
||||||
, fs = require('fs') |
const fs = require('fs') |
||||||
, path = require('path') |
const path = require('path') |
||||||
, _ = require('underscore') |
const async = require('async') |
||||||
, async = require('async') |
const Datastore = require('../lib/datastore') |
||||||
, model = require('../lib/model') |
const Persistence = require('../lib/persistence') |
||||||
, Datastore = require('../lib/datastore') |
|
||||||
, Persistence = require('../lib/persistence') |
const { assert } = chai |
||||||
; |
chai.should() |
||||||
|
|
||||||
|
|
||||||
// Test that even if a callback throws an exception, the next DB operations will still be executed
|
// Test that even if a callback throws an exception, the next DB operations will still be executed
|
||||||
// We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends
|
// We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends
|
||||||
function testThrowInCallback (d, done) { |
function testThrowInCallback (d, done) { |
||||||
var currentUncaughtExceptionHandlers = process.listeners('uncaughtException'); |
const currentUncaughtExceptionHandlers = process.listeners('uncaughtException') |
||||||
|
|
||||||
process.removeAllListeners('uncaughtException'); |
process.removeAllListeners('uncaughtException') |
||||||
|
|
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
process.on('uncaughtException', function (err) { |
process.on('uncaughtException', function (err) { |
||||||
// Do nothing with the error which is only there to test we stay on track
|
// Do nothing with the error which is only there to test we stay on track
|
||||||
}); |
}) |
||||||
|
|
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.find({}, function (err) { |
d.find({}, function (err) { |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.insert({ bar: 1 }, function (err) { |
d.insert({ bar: 1 }, function (err) { |
||||||
process.removeAllListeners('uncaughtException'); |
process.removeAllListeners('uncaughtException') |
||||||
for (var i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { |
for (let i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { |
||||||
process.on('uncaughtException', currentUncaughtExceptionHandlers[i]); |
process.on('uncaughtException', currentUncaughtExceptionHandlers[i]) |
||||||
} |
} |
||||||
|
|
||||||
done(); |
done() |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
|
|
||||||
throw new Error('Some error'); |
throw new Error('Some error') |
||||||
}); |
}) |
||||||
} |
} |
||||||
|
|
||||||
// Test that if the callback is falsy, the next DB operations will still be executed
|
// Test that if the callback is falsy, the next DB operations will still be executed
|
||||||
function testFalsyCallback (d, done) { |
function testFalsyCallback (d, done) { |
||||||
d.insert({ a: 1 }, null); |
d.insert({ a: 1 }, null) |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.update({ a: 1 }, { a: 2 }, {}, null); |
d.update({ a: 1 }, { a: 2 }, {}, null) |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.update({ a: 2 }, { a: 1 }, null); |
d.update({ a: 2 }, { a: 1 }, null) |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.remove({ a: 2 }, {}, null); |
d.remove({ a: 2 }, {}, null) |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.remove({ a: 2 }, null); |
d.remove({ a: 2 }, null) |
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.find({}, done); |
d.find({}, done) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
} |
} |
||||||
|
|
||||||
// Test that operations are executed in the right order
|
// Test that operations are executed in the right order
|
||||||
// We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends
|
// We prevent Mocha from catching the exception we throw on purpose by remembering all current handlers, remove them and register them back after test ends
|
||||||
function testRightOrder (d, done) { |
function testRightOrder (d, done) { |
||||||
var currentUncaughtExceptionHandlers = process.listeners('uncaughtException'); |
const currentUncaughtExceptionHandlers = process.listeners('uncaughtException') |
||||||
|
|
||||||
process.removeAllListeners('uncaughtException'); |
process.removeAllListeners('uncaughtException') |
||||||
|
|
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
process.on('uncaughtException', function (err) { |
process.on('uncaughtException', function (err) { |
||||||
// Do nothing with the error which is only there to test we stay on track
|
// Do nothing with the error which is only there to test we stay on track
|
||||||
}); |
}) |
||||||
|
|
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.find({}, function (err, docs) { |
d.find({}, function (err, docs) { |
||||||
docs.length.should.equal(0); |
docs.length.should.equal(0) |
||||||
|
|
||||||
d.insert({ a: 1 }, function () { |
d.insert({ a: 1 }, function () { |
||||||
d.update({ a: 1 }, { a: 2 }, {}, function () { |
d.update({ a: 1 }, { a: 2 }, {}, function () { |
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.find({}, function (err, docs) { |
d.find({}, function (err, docs) { |
||||||
docs[0].a.should.equal(2); |
docs[0].a.should.equal(2) |
||||||
|
|
||||||
process.nextTick(function () { |
process.nextTick(function () { |
||||||
d.update({ a: 2 }, { a: 3 }, {}, function () { |
d.update({ a: 2 }, { a: 3 }, {}, function () { |
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.find({}, function (err, docs) { |
d.find({}, function (err, docs) { |
||||||
docs[0].a.should.equal(3); |
docs[0].a.should.equal(3) |
||||||
|
|
||||||
process.removeAllListeners('uncaughtException'); |
process.removeAllListeners('uncaughtException') |
||||||
for (var i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { |
for (let i = 0; i < currentUncaughtExceptionHandlers.length; i += 1) { |
||||||
process.on('uncaughtException', currentUncaughtExceptionHandlers[i]); |
process.on('uncaughtException', currentUncaughtExceptionHandlers[i]) |
||||||
} |
} |
||||||
|
|
||||||
done(); |
done() |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
|
|
||||||
throw new Error('Some error'); |
throw new Error('Some error') |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
} |
} |
||||||
|
|
||||||
// Note: The following test does not have any assertion because it
|
// Note: The following test does not have any assertion because it
|
||||||
// is meant to address the deprecation warning:
|
// is meant to address the deprecation warning:
|
||||||
// (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
|
// (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
|
||||||
// see
|
// see
|
||||||
var testEventLoopStarvation = function(d, done){ |
const testEventLoopStarvation = function (d, done) { |
||||||
var times = 1001; |
const times = 1001 |
||||||
var i = 0; |
let i = 0 |
||||||
while ( i <times) { |
while (i < times) { |
||||||
i++; |
i++ |
||||||
d.find({"bogus": "search"}, function (err, docs) { |
// eslint-disable-next-line node/handle-callback-err
|
||||||
}); |
d.find({ bogus: 'search' }, function (err, docs) { |
||||||
|
}) |
||||||
} |
} |
||||||
done(); |
done() |
||||||
}; |
} |
||||||
|
|
||||||
// Test that operations are executed in the right order even with no callback
|
// Test that operations are executed in the right order even with no callback
|
||||||
function testExecutorWorksWithoutCallback (d, done) { |
function testExecutorWorksWithoutCallback (d, done) { |
||||||
d.insert({ a: 1 }); |
d.insert({ a: 1 }) |
||||||
d.insert({ a: 2 }, false); |
d.insert({ a: 2 }, false) |
||||||
|
// eslint-disable-next-line node/handle-callback-err
|
||||||
d.find({}, function (err, docs) { |
d.find({}, function (err, docs) { |
||||||
docs.length.should.equal(2); |
docs.length.should.equal(2) |
||||||
done(); |
done() |
||||||
}); |
}) |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
describe('Executor', function () { |
describe('Executor', function () { |
||||||
|
|
||||||
describe('With persistent database', function () { |
describe('With persistent database', function () { |
||||||
var d; |
let d |
||||||
|
|
||||||
beforeEach(function (done) { |
beforeEach(function (done) { |
||||||
d = new Datastore({ filename: testDb }); |
d = new Datastore({ filename: testDb }) |
||||||
d.filename.should.equal(testDb); |
d.filename.should.equal(testDb) |
||||||
d.inMemoryOnly.should.equal(false); |
d.inMemoryOnly.should.equal(false) |
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
function (cb) { |
function (cb) { |
||||||
Persistence.ensureDirectoryExists(path.dirname(testDb), function () { |
Persistence.ensureDirectoryExists(path.dirname(testDb), function () { |
||||||
fs.exists(testDb, function (exists) { |
fs.access(testDb, fs.constants.F_OK, function (err) { |
||||||
if (exists) { |
if (!err) { |
||||||
fs.unlink(testDb, cb); |
fs.unlink(testDb, cb) |
||||||
} else { return cb(); } |
} else { return cb() } |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
} |
}, |
||||||
, function (cb) { |
function (cb) { |
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
assert.isNull(err); |
assert.isNull(err) |
||||||
d.getAllData().length.should.equal(0); |
d.getAllData().length.should.equal(0) |
||||||
return cb(); |
return cb() |
||||||
}); |
}) |
||||||
} |
} |
||||||
], done); |
], done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('A throw in a callback doesnt prevent execution of next operations', function(done) { |
|
||||||
testThrowInCallback(d, done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('A falsy callback doesnt prevent execution of next operations', function(done) { |
it('A throw in a callback doesnt prevent execution of next operations', function (done) { |
||||||
testFalsyCallback(d, done); |
testThrowInCallback(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('Operations are executed in the right order', function(done) { |
it('A falsy callback doesnt prevent execution of next operations', function (done) { |
||||||
testRightOrder(d, done); |
testFalsyCallback(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('Does not starve event loop and raise warning when more than 1000 callbacks are in queue', function(done){ |
it('Operations are executed in the right order', function (done) { |
||||||
testEventLoopStarvation(d, done); |
testRightOrder(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('Works in the right order even with no supplied callback', function(done){ |
it('Does not starve event loop and raise warning when more than 1000 callbacks are in queue', function (done) { |
||||||
testExecutorWorksWithoutCallback(d, done); |
testEventLoopStarvation(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
}); // ==== End of 'With persistent database' ====
|
|
||||||
|
|
||||||
|
it('Works in the right order even with no supplied callback', function (done) { |
||||||
|
testExecutorWorksWithoutCallback(d, done) |
||||||
|
}) |
||||||
|
}) // ==== End of 'With persistent database' ====
|
||||||
|
|
||||||
describe('With non persistent database', function () { |
describe('With non persistent database', function () { |
||||||
var d; |
let d |
||||||
|
|
||||||
beforeEach(function (done) { |
beforeEach(function (done) { |
||||||
d = new Datastore({ inMemoryOnly: true }); |
d = new Datastore({ inMemoryOnly: true }) |
||||||
d.inMemoryOnly.should.equal(true); |
d.inMemoryOnly.should.equal(true) |
||||||
|
|
||||||
d.loadDatabase(function (err) { |
d.loadDatabase(function (err) { |
||||||
assert.isNull(err); |
assert.isNull(err) |
||||||
d.getAllData().length.should.equal(0); |
d.getAllData().length.should.equal(0) |
||||||
return done(); |
return done() |
||||||
}); |
}) |
||||||
}); |
}) |
||||||
|
|
||||||
it('A throw in a callback doesnt prevent execution of next operations', function(done) { |
it('A throw in a callback doesnt prevent execution of next operations', function (done) { |
||||||
testThrowInCallback(d, done); |
testThrowInCallback(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('A falsy callback doesnt prevent execution of next operations', function(done) { |
it('A falsy callback doesnt prevent execution of next operations', function (done) { |
||||||
testFalsyCallback(d, done); |
testFalsyCallback(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('Operations are executed in the right order', function(done) { |
it('Operations are executed in the right order', function (done) { |
||||||
testRightOrder(d, done); |
testRightOrder(d, done) |
||||||
}); |
}) |
||||||
|
|
||||||
it('Works in the right order even with no supplied callback', function(done){ |
it('Works in the right order even with no supplied callback', function (done) { |
||||||
testExecutorWorksWithoutCallback(d, done); |
testExecutorWorksWithoutCallback(d, done) |
||||||
}); |
}) |
||||||
|
}) // ==== End of 'With non persistent database' ====
|
||||||
}); // ==== End of 'With non persistent database' ====
|
}) |
||||||
|
|
||||||
}); |
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@ |
|||||||
--reporter spec |
|
||||||
--timeout 30000 |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,123 +1,121 @@ |
|||||||
|
/* eslint-env mocha */ |
||||||
|
/* global DEBUG */ |
||||||
/** |
/** |
||||||
* Load and modify part of fs to ensure writeFile will crash after writing 5000 bytes |
* Load and modify part of fs to ensure writeFile will crash after writing 5000 bytes |
||||||
*/ |
*/ |
||||||
var fs = require('fs'); |
const fs = require('fs') |
||||||
|
|
||||||
function rethrow() { |
function rethrow () { |
||||||
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
|
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
|
||||||
// is fairly slow to generate.
|
// is fairly slow to generate.
|
||||||
if (DEBUG) { |
if (DEBUG) { |
||||||
var backtrace = new Error(); |
const backtrace = new Error() |
||||||
return function(err) { |
return function (err) { |
||||||
if (err) { |
if (err) { |
||||||
backtrace.stack = err.name + ': ' + err.message + |
backtrace.stack = err.name + ': ' + err.message + |
||||||
backtrace.stack.substr(backtrace.name.length); |
backtrace.stack.substr(backtrace.name.length) |
||||||
throw backtrace; |
throw backtrace |
||||||
|
} |
||||||
} |
} |
||||||
}; |
|
||||||
} |
} |
||||||
|
|
||||||
return function(err) { |
return function (err) { |
||||||
if (err) { |
if (err) { |
||||||
throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
|
throw err // Forgot a callback but don't know where? Use NODE_DEBUG=fs
|
||||||
|
} |
||||||
} |
} |
||||||
}; |
|
||||||
} |
} |
||||||
|
|
||||||
function maybeCallback(cb) { |
function maybeCallback (cb) { |
||||||
return typeof cb === 'function' ? cb : rethrow(); |
return typeof cb === 'function' ? cb : rethrow() |
||||||
} |
} |
||||||
|
|
||||||
function isFd(path) { |
function isFd (path) { |
||||||
return (path >>> 0) === path; |
return (path >>> 0) === path |
||||||
} |
} |
||||||
|
|
||||||
function assertEncoding(encoding) { |
function assertEncoding (encoding) { |
||||||
if (encoding && !Buffer.isEncoding(encoding)) { |
if (encoding && !Buffer.isEncoding(encoding)) { |
||||||
throw new Error('Unknown encoding: ' + encoding); |
throw new Error('Unknown encoding: ' + encoding) |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
var onePassDone = false; |
let onePassDone = false |
||||||
function writeAll(fd, isUserFd, buffer, offset, length, position, callback_) { |
|
||||||
var callback = maybeCallback(arguments[arguments.length - 1]); |
|
||||||
|
|
||||||
if (onePassDone) { process.exit(1); } // Crash on purpose before rewrite done
|
function writeAll (fd, isUserFd, buffer, offset, length, position, callback_) { |
||||||
var l = Math.min(5000, length); // Force write by chunks of 5000 bytes to ensure data will be incomplete on crash
|
const callback = maybeCallback(arguments[arguments.length - 1]) |
||||||
|
|
||||||
|
if (onePassDone) { process.exit(1) } // Crash on purpose before rewrite done
|
||||||
|
const l = Math.min(5000, length) // Force write by chunks of 5000 bytes to ensure data will be incomplete on crash
|
||||||
|
|
||||||
// write(fd, buffer, offset, length, position, callback)
|
// write(fd, buffer, offset, length, position, callback)
|
||||||
fs.write(fd, buffer, offset, l, position, function(writeErr, written) { |
fs.write(fd, buffer, offset, l, position, function (writeErr, written) { |
||||||
if (writeErr) { |
if (writeErr) { |
||||||
if (isUserFd) { |
if (isUserFd) { |
||||||
if (callback) callback(writeErr); |
if (callback) callback(writeErr) |
||||||
} else { |
} else { |
||||||
fs.close(fd, function() { |
fs.close(fd, function () { |
||||||
if (callback) callback(writeErr); |
if (callback) callback(writeErr) |
||||||
}); |
}) |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
onePassDone = true; |
onePassDone = true |
||||||
if (written === length) { |
if (written === length) { |
||||||
if (isUserFd) { |
if (isUserFd) { |
||||||
if (callback) callback(null); |
if (callback) callback(null) |
||||||
} else { |
} else { |
||||||
fs.close(fd, callback); |
fs.close(fd, callback) |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
offset += written; |
offset += written |
||||||
length -= written; |
length -= written |
||||||
if (position !== null) { |
if (position !== null) { |
||||||
position += written; |
position += written |
||||||
} |
} |
||||||
writeAll(fd, isUserFd, buffer, offset, length, position, callback); |
writeAll(fd, isUserFd, buffer, offset, length, position, callback) |
||||||
} |
} |
||||||
} |
} |
||||||
}); |
}) |
||||||
} |
} |
||||||
|
|
||||||
fs.writeFile = function(path, data, options, callback_) { |
fs.writeFile = function (path, data, options, callback_) { |
||||||
var callback = maybeCallback(arguments[arguments.length - 1]); |
const callback = maybeCallback(arguments[arguments.length - 1]) |
||||||
|
|
||||||
if (!options || typeof options === 'function') { |
if (!options || typeof options === 'function') { |
||||||
options = { encoding: 'utf8', mode: 438, flag: 'w' }; // Mode 438 == 0o666 (compatibility with older Node releases)
|
options = { encoding: 'utf8', mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases)
|
||||||
} else if (typeof options === 'string') { |
} else if (typeof options === 'string') { |
||||||
options = { encoding: options, mode: 438, flag: 'w' }; // Mode 438 == 0o666 (compatibility with older Node releases)
|
options = { encoding: options, mode: 438, flag: 'w' } // Mode 438 == 0o666 (compatibility with older Node releases)
|
||||||
} else if (typeof options !== 'object') { |
} else if (typeof options !== 'object') { |
||||||
throwOptionsError(options); |
throw new Error(`throwOptionsError${options}`) |
||||||
} |
} |
||||||
|
|
||||||
assertEncoding(options.encoding); |
assertEncoding(options.encoding) |
||||||
|
|
||||||
var flag = options.flag || 'w'; |
const flag = options.flag || 'w' |
||||||
|
|
||||||
if (isFd(path)) { |
if (isFd(path)) { |
||||||
writeFd(path, true); |
writeFd(path, true) |
||||||
return; |
return |
||||||
} |
} |
||||||
|
|
||||||
fs.open(path, flag, options.mode, function(openErr, fd) { |
fs.open(path, flag, options.mode, function (openErr, fd) { |
||||||
if (openErr) { |
if (openErr) { |
||||||
if (callback) callback(openErr); |
if (callback) callback(openErr) |
||||||
} else { |
} else { |
||||||
writeFd(fd, false); |
writeFd(fd, false) |
||||||
} |
} |
||||||
}); |
}) |
||||||
|
|
||||||
function writeFd(fd, isUserFd) { |
function writeFd (fd, isUserFd) { |
||||||
var buffer = (data instanceof Buffer) ? data : new Buffer('' + data, |
const buffer = (data instanceof Buffer) ? data : Buffer.from('' + data, options.encoding || 'utf8') |
||||||
options.encoding || 'utf8'); |
const position = /a/.test(flag) ? null : 0 |
||||||
var position = /a/.test(flag) ? null : 0; |
|
||||||
|
|
||||||
writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback); |
writeAll(fd, isUserFd, buffer, 0, buffer.length, position, callback) |
||||||
} |
} |
||||||
}; |
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// End of fs modification
|
// End of fs modification
|
||||||
var Nedb = require('../lib/datastore.js') |
const Nedb = require('../lib/datastore.js') |
||||||
, db = new Nedb({ filename: 'workspace/lac.db' }) |
const db = new Nedb({ filename: 'workspace/lac.db' }) |
||||||
; |
|
||||||
|
|
||||||
db.loadDatabase(); |
db.loadDatabase() |
||||||
|
@ -1,67 +1,64 @@ |
|||||||
var fs = require('fs') |
const fs = require('fs') |
||||||
, child_process = require('child_process') |
const async = require('async') |
||||||
, async = require('async') |
const Nedb = require('../lib/datastore') |
||||||
, Nedb = require('../lib/datastore') |
const db = new Nedb({ filename: './workspace/openfds.db', autoload: true }) |
||||||
, db = new Nedb({ filename: './workspace/openfds.db', autoload: true }) |
const N = 64 |
||||||
, N = 64 // Half the allowed file descriptors
|
let i |
||||||
, i, fds |
let fds |
||||||
; |
|
||||||
|
|
||||||
function multipleOpen (filename, N, callback) { |
function multipleOpen (filename, N, callback) { |
||||||
async.whilst( function () { return i < N; } |
async.whilst(function () { return i < N } |
||||||
, function (cb) { |
, function (cb) { |
||||||
fs.open(filename, 'r', function (err, fd) { |
fs.open(filename, 'r', function (err, fd) { |
||||||
i += 1; |
i += 1 |
||||||
if (fd) { fds.push(fd); } |
if (fd) { fds.push(fd) } |
||||||
return cb(err); |
return cb(err) |
||||||
}); |
}) |
||||||
} |
} |
||||||
, callback); |
, callback) |
||||||
} |
} |
||||||
|
|
||||||
async.waterfall([ |
async.waterfall([ |
||||||
// Check that ulimit has been set to the correct value
|
// Check that ulimit has been set to the correct value
|
||||||
function (cb) { |
function (cb) { |
||||||
i = 0; |
i = 0 |
||||||
fds = []; |
fds = [] |
||||||
multipleOpen('./test_lac/openFdsTestFile', 2 * N + 1, function (err) { |
multipleOpen('./test_lac/openFdsTestFile', 2 * N + 1, function (err) { |
||||||
if (!err) { console.log("No error occured while opening a file too many times"); } |
if (!err) { console.log('No error occured while opening a file too many times') } |
||||||
fds.forEach(function (fd) { fs.closeSync(fd); }); |
fds.forEach(function (fd) { fs.closeSync(fd) }) |
||||||
return cb(); |
return cb() |
||||||
}) |
}) |
||||||
} |
}, |
||||||
, function (cb) { |
function (cb) { |
||||||
i = 0; |
i = 0 |
||||||
fds = []; |
fds = [] |
||||||
multipleOpen('./test_lac/openFdsTestFile2', N, function (err) { |
multipleOpen('./test_lac/openFdsTestFile2', N, function (err) { |
||||||
if (err) { console.log('An unexpected error occured when opening file not too many times: ' + err); } |
if (err) { console.log('An unexpected error occured when opening file not too many times: ' + err) } |
||||||
fds.forEach(function (fd) { fs.closeSync(fd); }); |
fds.forEach(function (fd) { fs.closeSync(fd) }) |
||||||
return cb(); |
return cb() |
||||||
}) |
}) |
||||||
} |
}, |
||||||
// Then actually test NeDB persistence
|
// Then actually test NeDB persistence
|
||||||
, function () { |
function () { |
||||||
db.remove({}, { multi: true }, function (err) { |
db.remove({}, { multi: true }, function (err) { |
||||||
if (err) { console.log(err); } |
if (err) { console.log(err) } |
||||||
db.insert({ hello: 'world' }, function (err) { |
db.insert({ hello: 'world' }, function (err) { |
||||||
if (err) { console.log(err); } |
if (err) { console.log(err) } |
||||||
|
|
||||||
i = 0; |
i = 0 |
||||||
async.whilst( function () { return i < 2 * N + 1; } |
async.whilst(function () { return i < 2 * N + 1 } |
||||||
, function (cb) { |
, function (cb) { |
||||||
db.persistence.persistCachedDatabase(function (err) { |
db.persistence.persistCachedDatabase(function (err) { |
||||||
if (err) { return cb(err); } |
if (err) { return cb(err) } |
||||||
i += 1; |
i += 1 |
||||||
return cb(); |
return cb() |
||||||
}); |
}) |
||||||
} |
} |
||||||
, function (err) { |
, function (err) { |
||||||
if (err) { console.log("Got unexpected error during one peresistence operation: " + err); } |
if (err) { console.log('Got unexpected error during one peresistence operation: ' + err) } |
||||||
} |
} |
||||||
); |
) |
||||||
|
}) |
||||||
}); |
}) |
||||||
}); |
|
||||||
} |
} |
||||||
]); |
]) |
||||||
|
|
||||||
|
Loading…
Reference in new issue