nsolid-manager
Version:
A manager that sets up and runs N|Solid for you
98 lines (78 loc) • 2.12 kB
JavaScript
var fs = require('fs')
var rimraf = require('rimraf')
var path = require('path')
var level = require('levelup')
var mkdirp = require('mkdirp')
var leveldown = require('leveldown')
module.exports = getStorage
/**
* Caching wrapper around createStorage
*/
function getStorage (storagePath, name, options = {}, done) {
if (!storagePath) return done()
// options is optional
if (typeof options === 'function') {
done = options
options = {}
}
getStorage.dbs = getStorage.dbs || {}
const dbPath = path.join(storagePath, name + '.db')
function handleOpenError (e) {
if (e.type === 'OpenError') {
leveldown.repair(dbPath, function repairComplete (repairError) {
if (repairError) return done(repairError)
getStorage(storagePath, name, options, done)
})
} else {
done(e)
}
}
if (!getStorage.dbs[dbPath] || getStorage.dbs[dbPath].isClosed()) {
const db = createStorage(dbPath, options)
db.once('error', handleOpenError)
db.once('ready', function dbReady () {
db.removeListener('error', handleOpenError)
if (getStorage.dbs[dbPath]) {
delete getStorage.dbs[dbPath]
}
getStorage.dbs[dbPath] = db
done(null, db)
})
} else {
// db is available and open
done(null, getStorage.dbs[dbPath])
}
}
/**
* Initialise a new leveldb instance
*/
function createStorage (dbPath, options) {
if (!dbPath) return
if (dbPath && typeof dbPath !== 'string') throw new TypeError('dbPath string required')
const flush = !!options.flush
try {
if (flush) flushDir(dbPath)
mkdirp.sync(dbPath)
} catch (err) {
// dir already exists is not an error for us
if (err.code !== 'EEXISTS') throw err
}
return level(dbPath, {
valueEncoding: 'json'
})
}
/**
* Wipe a directory.
* Does nothing if dir is not a string or accessible.
*/
function flushDir (dir) {
if (!dir || typeof dir !== 'string') return
try {
fs.accessSync(dir)
} catch (err) {
// ignore err, just return if can't access
return
}
console.info('flushing', dir)
rimraf.sync(dir)
}