Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added buildTree method to plugin

  • Loading branch information...
commit c1cab04af70c9333160f2fe6508ac1a1a7fea482 1 parent edf0629
Luc Castera dambalah authored
BIN  docs/test_tree.dia
View
Binary file not shown
BIN  docs/test_tree.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 lib/nested_set.js
View
@@ -1,12 +1,41 @@
'use strict'
var mongoose = require('mongoose'),
- Schema = mongoose.Schema;
+ Schema = mongoose.Schema,
+ async = require('async');
var NestedSetPlugin = function(schema, options) {
+ options = options || {}
+
+ var modelName = options.modelName || 'User';
+
schema.add({ lft: {type: Number, min: 0} });
schema.add({ rgt: {type: Number, min: 0} });
schema.add({ parentId: {type: Schema.ObjectId} });
+
+ schema.static('rebuildTree', function(parent, left, callback) {
+ parent.lft = left;
+ parent.rgt = left + 1;
+ var model = mongoose.model(modelName);
+
+ model.find({parentId: parent._id}, function(err, children) {
+ if (err) return callback(err);
+ if (!children) return callback(new Error(modelName + ' not found'));
+
+ if (children.length > 0) {
+ async.forEachSeries(children, function(item, cb) {
+ model.rebuildTree(item, parent.rgt, function() {
+ parent.rgt = item.rgt + 1;
+ model.update({_id: parent._id}, {lft: parent.lft, rgt: parent.rgt}, cb);
+ });
+ }, function(err) {
+ callback();
+ });
+ } else {
+ model.update({_id: parent._id}, {lft: parent.lft, rgt: parent.rgt}, callback);
+ }
+ });
+ });
}
-module.exports = NestedSetPlugin;
+module.exports = exports = NestedSetPlugin;
2  package.json
View
@@ -24,7 +24,7 @@
},
"dependencies": {
"mongoose": "~2.4.5",
- "step": "~0.0.5"
+ "async": "~0.1.15"
},
"devDependencies": {
"nodeunit": "~0.6.4"
95 tests/nested_set_test.js
View
@@ -4,32 +4,33 @@ var testCase = require('nodeunit').testCase,
mongoose = require('mongoose'),
NestedSetPlugin = require('../lib/nested_set'),
Schema = mongoose.Schema,
- Step = require('step'),
+ async = require('async'),
Helpers = require('./helpers');
var UserSchema,
User
var tests = testCase({
- setUp: function(callback) {
- Step(
- function() {
+ setUp: function(next) {
+ async.series([
+ function(callback) {
mongoose.connect('mongodb://localhost/nested_set_test');
- this();
+ callback();
},
- function() {
+ function(callback) {
UserSchema = new Schema({
username: {type: String}
});
UserSchema.plugin(NestedSetPlugin);
User = mongoose.model('User', UserSchema);
- this();
+ callback();
},
- function() {
+ function(callback) {
// drop users from mongodb
- User.remove({}, this);
+ User.remove({}, callback);
},
- function() {
+ function(callback) {
+ // see diagram in docs/test_tree.png for a representation of this tree
var michael = new User({username: 'michael'});
var meredith = new User({username: 'meredith', parentId: michael._id});
@@ -45,22 +46,25 @@ var tests = testCase({
var oscar = new User({username: 'oscar', parentId: angela._id});
- michael.save(this.parallel());
- meredith.save(this.parallel());
- jim.save(this.parallel());
- angela.save(this.parallel());
- kelly.save(this.parallel());
- creed.save(this.parallel());
- phyllis.save(this.parallel());
- stanley.save(this.parallel());
- dwight.save(this.parallel());
- oscar.save(this.parallel());
+ async.forEach([
+ michael,
+ meredith,
+ jim,
+ angela,
+ kelly,
+ creed,
+ phyllis,
+ stanley,
+ dwight,
+ oscar
+ ], function(item, cb) { item.save(cb) }, function(err) {
+ callback();
+ })
},
- function(err) {
- if (err) { console.log(err); }
- callback();
+ function(callback) {
+ next();
}
- )
+ ])
},
'is sane': function(test) {
test.expect(3);
@@ -91,6 +95,49 @@ var tests = testCase({
});
test.done();
});
+ },
+ 'rebuildTree should set lft and rgt based on parentIds': function(test) {
+ User.findOne({username: 'michael'}, function(err, user) {
+ User.rebuildTree(user, 1, function() {
+ User.find(function(err, users) {
+ // see docs/test_tree.png for the graphical representation of this tree with lft/rgt values
+ users.forEach(function(person) {
+ if (person.username === 'michael') {
+ test.equal(1, person.lft);
+ test.equal(20, person.rgt);
+ } else if (person.username === 'meredith') {
+ test.equal(2, person.lft);
+ test.equal(7, person.rgt);
+ } else if (person.username === 'jim') {
+ test.equal(8, person.lft);
+ test.equal(15, person.rgt);
+ } else if (person.username === 'angela') {
+ test.equal(16, person.lft);
+ test.equal(19, person.rgt);
+ } else if (person.username === 'kelly') {
+ test.equal(3, person.lft);
+ test.equal(4, person.rgt);
+ } else if (person.username === 'creed') {
+ test.equal(5, person.lft);
+ test.equal(6, person.rgt);
+ } else if (person.username === 'phyllis') {
+ test.equal(9, person.lft);
+ test.equal(10, person.rgt);
+ } else if (person.username === 'stanley') {
+ test.equal(11, person.lft);
+ test.equal(12, person.rgt);
+ } else if (person.username === 'dwight') {
+ test.equal(13, person.lft);
+ test.equal(14, person.rgt);
+ } else if (person.username === 'oscar') {
+ test.equal(17, person.lft);
+ test.equal(18, person.rgt);
+ }
+ })
+ test.done();
+ })
+ });
+ });
}
});
Please sign in to comment.
Something went wrong with that request. Please try again.