diff --git a/leveldown.js b/leveldown.js index 4452190b..ae378ced 100644 --- a/leveldown.js +++ b/leveldown.js @@ -3,6 +3,7 @@ const AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN const binding = require('./binding') const ChainedBatch = require('./chained-batch') const Iterator = require('./iterator') +const fs = require('fs') function LevelDOWN (location) { if (!(this instanceof LevelDOWN)) { @@ -121,7 +122,28 @@ LevelDOWN.destroy = function (location, callback) { throw new Error('destroy() requires a callback function argument') } - binding.destroy_db(location, callback) + binding.destroy_db(location, function (err) { + if (err) return callback(err) + + // On Windows, RocksDB silently fails to remove the directory because its + // Logger, which is instantiated on destroy(), has an open file handle on a + // LOG file. Destroy() removes this file but Windows won't actually delete + // it until the handle is released. This happens when destroy() goes out of + // scope, which disposes the Logger. So back in JS-land, we can again + // attempt to remove the directory. This is merely a workaround because + // arguably RocksDB should not instantiate a Logger or open a file at all. + fs.rmdir(location, function (err) { + if (err) { + // Ignore this error in case there are non-RocksDB files left. + if (err.code === 'ENOTEMPTY') return callback() + if (err.code === 'ENOENT') return callback() + + return callback(err) + } + + callback() + }) + }) } LevelDOWN.repair = function (location, callback) {