UNPKG

5.28 kBJavaScriptView Raw
1var _ = require("underscore");
2var DataLayer = require("./DataLayer");
3var helpers = require("../helpers");
4
5module.exports = DataLayer.extend("RedisLayer", {
6
7
8 parseArguments: function(args){
9 switch(args.length){
10 case 0: return false;
11 case 1:
12 if(typeof args[0] !== "function") return false;
13 else return [undefined,{},args[0]];
14 case 2:
15 if(typeof args[1] !== "function") return false;
16 else return [args[0],{}, args[1]];
17 case 3:
18 if(typeof args[2] !== "function") return false;
19 else return [args[0],args[1], args[2]];
20 default: return false;
21 }
22 },
23
24 parseResults: function(pattern, options, cb){
25 var self = this;
26 return function(err, results){
27
28 if(typeof pattern === "number"){
29 if(results[0]) return cb(null, _.extend(JSON.parse(results[0]), _.object([[self.primaryKey, parseInt(pattern)]])));
30 else return cb(null, null);
31 }
32 else if(Array.isArray(pattern)){
33 return cb(null, pattern.map(function(id, index){
34 if(!results[index]) return null;
35 var object = JSON.parse(results[index]);
36 _.extend(object, _.object([[self.primaryKey, parseInt(id)]]));
37 if(options.fields) object = _.pick(object, options.fields);
38 return object;
39 }));
40 }
41 else{
42 var objects = [];
43 for(var key in results){
44 var object = JSON.parse(results[key]);
45 _.extend(object, _.object([[self.primaryKey, parseInt(key)]]))
46 objects.push(options.fields? _.pick(object, options.fields) : object);
47 }
48 cb(null, objects);
49 }
50 };
51 },
52
53 create: function(obj, options, cb){
54 var data = _.omit(_.pick(obj, _.keys(this.fields)), [this.primaryKey]);
55 var primaryKey = primaryKey = ++this.pk;
56 this.redis.hmset(this.hashName, primaryKey, JSON.stringify(data), function(err){
57 if(err) return cb(err);
58 data.primaryKey = primaryKey;
59 cb(null, data)
60 });
61 },
62
63 find: function(pattern, options, cb){
64 if(!pattern) return this.redis.hgetall(this.hashName, this.parseResults(pattern, options, cb));
65 this.redis.hmget(this.hashName, pattern, this.parseResults(pattern, options, cb));
66 },
67
68 findOne: function(pattern, options, cb){
69 // TODO
70 },
71
72 update: function(pattern, options, cb){
73 var self = this;
74 if(Array.isArray(pattern)){
75 pattern = pattern.filter(function(obj){
76 return obj.hasOwnProperty(self.primaryKey);
77 });
78 var objIndex = _.indexBy(pattern, this.primaryKey);
79 this.find(_.pluck(pattern, this.primaryKey), options, function(err, results){
80 if(err) return cb(err);
81 var updates = [];
82 results.forEach(function(result){
83 if(result) {
84 var id = result[self.primaryKey];
85 _.extend(result, objIndex[id])
86 var data = JSON.stringify(_.omit( _.pick(result, self.publicFields || _.keys(self.fields)), [self.primaryKey]));
87 updates.push([id, data]);
88 }
89 });
90 updates.push();
91 self.redis.hmset.call(self.redis, self.hashName, _.object(updates), function(err){
92 if(err) return cb(err);
93 cb(null, results);
94 });
95
96 });
97 }
98 else{
99 if(!_.has(pattern, this.primaryKey)) return cb("Can't find primary key for update");
100 this.find(pattern[this.primaryKey], {}, function(err, object){
101 if(err) return cb(err);
102 if(!object) return cb("Can't find object");
103 _.extend(object, _.pick(pattern, self.publicFields || _.keys(self.fields)));
104 var data = JSON.stringify(_.omit(object, [self.primaryKey] ) );
105
106 self.redis.hmset(self.hashName, _.object([[pattern[this.primaryKey], data]]), function(err){
107 if(err) return cb(err);
108 return cb(null, object);
109 });
110 });
111 }
112 },
113
114 delete: function(pattern, options, cb){
115 if(typeof pattern === "number"){
116 this.redis.hdel(this.hashName, pattern, cb);
117 }
118 else if(Array.isArray(pattern)){
119 var self = this;
120 helpers.amap(pattern, function(id, cb){
121 self.redis.hdel(self.hashName, id, cb);
122 }, cb);
123 }
124 else if(pattern === null){
125 self.redis.hdel(self.hashName, cb);
126 }
127
128 },
129
130
131}, {
132
133 setupDatabase: function(self, env, name){
134 var Prototype = this;
135 self.setupNode = function(cb){ Prototype.setupStore(self, env, function(err){
136 if(err) return cb(err);
137 env.i.do("log.sys", "DataLayer:redis", name);
138 cb();
139 }); }
140 },
141
142 setupStore: function(instance, env, cb){
143 instance.redis = env.engines.redis;
144
145 instance.redis.hgetall(instance.hashName, function(err, obj){
146 if(err) return cb(err);
147 if(!obj) {
148 instance.pk = 0;
149 return cb();
150 }
151
152 var keys = _.keys(obj).sort();
153 var length = keys.length;
154 var last = parseInt(keys.pop());
155 instance.pk = last
156 cb();
157 });
158
159 },
160
161 extend: function(name, props, statics){
162 this.setMethods(this.prototype, props);
163 return DataLayer.extend.apply(this, arguments);
164 }
165});