diff --git a/lib/datastore.js b/lib/datastore.js index a73c0f4..7495892 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -4,6 +4,7 @@ var fs = require('fs') , model = require('./model') , async = require('async') , Executor = require('./executor') + , Index = require('./indexes') ; @@ -18,9 +19,33 @@ function Datastore (filename) { // We keep internally the number of lines in the datafile // This will be used when/if I implement autocompacting when the datafile grows too big this.datafileSize = 0; + + // Indexed by field name, dot notation can be used + this.indexes = {}; } +/** + * Ensure an index is kept for this field. Same parameters as lib/indexes + * For now this function is synchronous, we need to test how much time it takes + * @param {String} options.fieldName + * @param {Boolean} options.unique + * @param {Boolean} options.sparse + * @return {Boolean} true if index was created or already exists, false otherwise + */ +Datastore.prototype.ensureIndex = function (options) { + options = options || {}; + + if (!options.fieldName) { return false; } + if (this.indexes[options.fieldName]) { return true; } + + options.datastore = this; + this.indexes[options.fieldName] = new Index(options); + + return true; +}; + + /** * Load the database * This means pulling data out of the data file or creating it if it doesn't exist diff --git a/lib/indexes.js b/lib/indexes.js index 52a573e..e1788a2 100644 --- a/lib/indexes.js +++ b/lib/indexes.js @@ -1,6 +1,7 @@ var BinarySearchTree = require('binary-search-tree').BinarySearchTree , model = require('./model') , _ = require('underscore') + , util = require('util') ; /** @@ -33,10 +34,15 @@ function Index (options) { /** * Insert a new document in the index + * If an array is passed, we insert all its elements * O(log(n)) */ Index.prototype.insert = function (doc) { - var key = model.getDotValue(doc, this.fieldName); + var key, self = this; + + if (util.isArray(doc)) { doc.forEach(function (d) { self.insert(d); }); } + + key = model.getDotValue(doc, this.fieldName); // We don't index documents that don't contain the field if the index is sparse if (key === undefined && this.sparse) { diff --git a/test/indexes.test.js b/test/indexes.test.js index 28db8df..b5f8195 100644 --- a/test/indexes.test.js +++ b/test/indexes.test.js @@ -91,6 +91,20 @@ describe('Indexing', function () { doc3.a.should.equal(42); }); + it('Can insert an array of documents', function () { + var idx = new Index({ fieldName: 'tf' }) + , doc1 = { a: 5, tf: 'hello' } + , doc2 = { a: 8, tf: 'world' } + , doc3 = { a: 2, tf: 'bloup' } + ; + + idx.insert([doc1, doc2, doc3]); + idx.tree.getNumberOfKeys().should.equal(3); + assert.deepEqual(idx.tree.search('hello'), [doc1]); + assert.deepEqual(idx.tree.search('world'), [doc2]); + assert.deepEqual(idx.tree.search('bloup'), [doc3]); + }); + }); // ==== End of 'Insertion' ==== //