louischatriot / nedb

The JavaScript Database, for Node.js, nw.js, electron and the browser
MIT License
13.49k stars 1.03k forks source link

Error creating index when db does not exist #134

Open duncanbrown opened 10 years ago

duncanbrown commented 10 years ago

Bit of an edge case this, but...

Calling ensureIndex on a Datastore gives an error when all the following are true:

  1. The Datastore is not in-memory
  2. The Datastore has not yet been loaded (loadDatabase may have been called, but the executor has not yet got round to carrying it out)
  3. The file for the database does not exist on the filesystem
  4. The directory of the database file does not exist

The error comes about because calling ensureIndex results in a (synchronous) call to Persistence.prototype.persistNewState, which in turn calls fs.appendFile, all before Persistence.prototype.loadDatabase has been called. This may ordinarily go unnoticed because if 4. above is not true then fs.appendFile will actually create the db file.

I've spent a while thinking of a solution to this, but I can't come up with anything that keeps ensureIndex synchronous (short of synchronously checking that the db file exists every time it is called).

louischatriot commented 10 years ago

Seems like an edge case indeed but still worth solving. Thanks for reporting, I'll see when I have the time to fix it :)

kaizhu256 commented 8 years ago

fyi, this is my workaround by running fs.mkdir once if the flag local.swgg.modeNedbInitialized is not set

        local.swgg.collectionCreate = function (schemaName) {
        /*
         * this function will create a persistent nedb-collection from schemaName
         */
            if (!local.swgg.cacheDict.collection[schemaName]) {
                if (local.modeJs === 'node' && !local.swgg.modeNedbInitialized) {
                    // init nedb dir
                    local.fs.mkdir('tmp', local.utility2.nop);
                    local.fs.mkdir('tmp/nedb.collection', local.utility2.nop);
                }
                local.swgg.modeNedbInitialized = true;
                local.swgg.cacheDict.collection[schemaName] = new local.swgg.Nedb({
                    autoload: true,
                    filename: 'tmp/nedb.collection/' + schemaName,
                    timestampData: true
                });
            }
            return local.swgg.cacheDict.collection[schemaName];
        };