/
redistree.js
91 lines (78 loc) · 2.41 KB
/
redistree.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
var _ = require('lodash');
var async = require('async');
/**
* RedisTree
* @param {Object} redisClient redis client (node_redis)
*/
function RedisTree(redisClient){this.redis = redisClient;}
/**
* Iteratively & asynchronously retrieve an item from Redis
* @param {String} label label name (set name)
* @param {Function} f(err, arrayOfItems)
*/
RedisTree.prototype._getItem = function(label, f) {
var parent = _.isArray(_.last(arguments)) ? _.last(arguments) : [];
this.members(label, function(err, cards){
var item = {
label: this.label(label),
childrens: []
};
parent.push(item);
if(cards.length === 0){return f(null, parent);}
async.map(cards, _.partialRight(this._getItem.bind(this), item.childrens), function(e){f(e, parent);});
}.bind(this));
};
RedisTree.prototype._saveItem = function(item, f) {
var labels = _.pluck(item.childrens, 'label');
if(labels.length === 0){return f();}
this.addMembers(item.label, labels, function(err){
if(err){return f(err);}
this._saveItems(item.childrens, f);
}.bind(this));
};
/**
*
* @param {Array} arrToSave array of items
* @param {Function} f(err)
*/
RedisTree.prototype._saveItems = function(arrToSave, f) {
async.forEach(arrToSave, this._saveItem.bind(this), f);
};
/**
* Retrieve a name from the label
* Can be overridden to provide namespace support
* e.g. return label.substring(2);
* @return {String} human readable label
*/
RedisTree.prototype.label = function(label){return label;};
/**
* Retrieve every members of the `label` set from redis
* Can be overridden to provide namespace support
* e.g. redis.smembers('ns.'+label, f);
* @param {String} label
*/
RedisTree.prototype.members = function(label, f) {
this.redis.smembers(label, f);
};
/**
* Store members `labels` into the `label` set
* @param {} label [description]
* @param {[type]} labels [description]
* @param {[type]} f [description]
*/
RedisTree.prototype.addMembers = function(label, labels, f) {
this.redis.sadd(label, labels, f);
};
/**
* Load a tree from Redis
* @param {String} startLabel Were to start
* @param {Function} f(err, tree)
*/
RedisTree.prototype.load = function(startLabel, f){this._getItem(startLabel, f);};
/**
* Save a tree from Redis
* @param {Array} treeArray
* @param {Function} f(err, tree)
*/
RedisTree.prototype.save = function(treeArray, f){this._saveItems(treeArray, f);};
module.exports = RedisTree;