Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom id generator #212

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ need to call `loadDatabase`). Any command
issued before load is finished is buffered and will be executed when
load is done.
* `onload` (optional): if you use autoloading, this is the handler called after the `loadDatabase`. It takes one `error` argument. If you use autoloading without specifying this handler, and an error happens during load, an error will be thrown.
* `idGenerator` (optional): if set, this function will be used for generating IDs. It takes one `length`argument and should return a unique string.
* `nodeWebkitAppName` (optional, **DEPRECATED**): if you are using NeDB from whithin a Node Webkit app, specify its name (the same one you use in the `package.json`) in this field and the `filename` will be relative to the directory Node Webkit uses to store the rest of the application's data (local storage etc.). It works on Linux, OS X and Windows. Now that you can use `require('nw.gui').App.dataPath` in Node Webkit to get the path to the data directory for your application, you should not use this option anymore and it will be removed.

If you use a persistent datastore without the `autoload` option, you need to call `loadDatabase` manually.
Expand Down Expand Up @@ -115,7 +116,7 @@ Keep in mind that compaction takes a bit of time (not too much: 130ms for 50k re

### Inserting documents
The native types are `String`, `Number`, `Boolean`, `Date` and `null`. You can also use
arrays and subdocuments (objects). If a field is `undefined`, it will not be saved (this is different from
arrays and subdocuments (objects). If a field is `undefined`, it will not be saved (this is different from
MongoDB which transforms `undefined` in `null`, something I find counter-intuitive).

If the document does not contain an `_id` field, NeDB will automatically generated one for you (a 16-characters alphanumerical string). The `_id` of a document, once set, cannot be modified.
Expand Down Expand Up @@ -584,7 +585,7 @@ As of v0.8.0, you can use NeDB in the browser! You can find it and its minified
<script src="nedb.min.js"></script>
<script>
var db = new Nedb(); // Create an in-memory only datastore

db.insert({ planet: 'Earth' });
db.insert({ planet: 'Mars' });

Expand Down Expand Up @@ -632,9 +633,9 @@ Connect and Express, backed by nedb
Issues reporting and pull requests are always appreciated. For issues, make sure to always include a code snippet and describe the expected vs actual behavior. If you send a pull request, make sure to stick to NeDB's coding style and always test all the code you submit. You can look at the current tests to see how to do it

### Bitcoins
You don't have time? You can support NeDB by sending bitcoins to this adress:
You don't have time? You can support NeDB by sending bitcoins to this adress:


## License
## License

See [License](LICENSE)
24 changes: 13 additions & 11 deletions lib/datastore.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var customUtils = require('./customUtils')
* Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion)
* @param {Boolean} options.autoload Optional, defaults to false
* @param {Function} options.onload Optional, if autoload is used this will be called after the load database with the error object as parameter. If you don't pass it the error will be thrown
* @param {Function} options.idGenerator Optional, an optional used Function for _id generation
*/
function Datastore (options) {
var filename;
Expand All @@ -31,6 +32,7 @@ function Datastore (options) {
filename = options.filename;
this.inMemoryOnly = options.inMemoryOnly || false;
this.autoload = options.autoload || false;
this.idGenerator = options.idGenerator || customUtils.uid;
}

// Determine whether in memory or persistent
Expand All @@ -54,7 +56,7 @@ function Datastore (options) {
// binary is always well-balanced
this.indexes = {};
this.indexes._id = new Index({ fieldName: '_id', unique: true });

// Queue a load of the database right away and call the onload handler
// By default (no onload handler), if there is an error there, no operation will be possible so warn the user by throwing an exception
if (this.autoload) { this.loadDatabase(options.onload || function (err) {
Expand Down Expand Up @@ -127,17 +129,17 @@ Datastore.prototype.ensureIndex = function (options, cb) {
/**
* Remove an index
* @param {String} fieldName
* @param {Function} cb Optional callback, signature: err
* @param {Function} cb Optional callback, signature: err
*/
Datastore.prototype.removeIndex = function (fieldName, cb) {
var callback = cb || function () {};

delete this.indexes[fieldName];

this.persistence.persistNewState([{ $$indexRemoved: fieldName }], function (err) {
if (err) { return callback(err); }
return callback(null);
});
});
};


Expand Down Expand Up @@ -293,7 +295,7 @@ Datastore.prototype._insert = function (newDoc, cb) {
* Create a new _id that's not already in use
*/
Datastore.prototype.createNewId = function () {
var tentativeId = customUtils.uid(16);
var tentativeId = this.idGenerator(16);
// Try as many times as needed to get an unused _id. As explained in customUtils, the probability of this ever happening is extremely small, so this is O(1)
if (this.indexes._id.getMatching(tentativeId).length > 0) {
tentativeId = this.createNewId();
Expand All @@ -316,7 +318,7 @@ Datastore.prototype.prepareDocumentForInsertion = function (newDoc) {
preparedDoc = model.deepCopy(newDoc);
model.checkObject(preparedDoc);
}

return preparedDoc;
};

Expand All @@ -328,7 +330,7 @@ Datastore.prototype._insertInCache = function (newDoc) {
if (util.isArray(newDoc)) {
this._insertMultipleDocsInCache(newDoc);
} else {
this.addToIndexes(this.prepareDocumentForInsertion(newDoc));
this.addToIndexes(this.prepareDocumentForInsertion(newDoc));
}
};

Expand All @@ -351,12 +353,12 @@ Datastore.prototype._insertMultipleDocsInCache = function (newDocs) {
break;
}
}

if (error) {
for (i = 0; i < failingI; i += 1) {
this.removeFromIndexes(preparedDocs[i]);
}

throw error;
}
};
Expand Down Expand Up @@ -523,7 +525,7 @@ Datastore.prototype._update = function (query, updateQuery, options, cb) {
} catch (err) {
return callback(err);
}

// Change the docs in memory
try {
self.updateIndexes(modifications);
Expand Down
Loading