PageRenderTime 61ms CodeModel.GetById 15ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/lodis.js

http://github.com/elcuervo/lodis
JavaScript | 672 lines | 672 code | 0 blank | 0 comment | 108 complexity | 0c8c3cf84ca3a1431ffe1826b0cb1adf MD5 | raw file
  1(function() {
  2  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __slice = Array.prototype.slice, __indexOf = Array.prototype.indexOf || function(item) {
  3    for (var i = 0, l = this.length; i < l; i++) {
  4      if (this[i] === item) return i;
  5    }
  6    return -1;
  7  };
  8  this.Lodis = (function() {
  9    function Lodis() {
 10      this._expire_key = __bind(this._expire_key, this);      this.storage = window.localStorage;
 11    }
 12    Lodis.prototype._pack = function(value) {
 13      return JSON.stringify(value);
 14    };
 15    Lodis.prototype._unpack = function(value) {
 16      return JSON.parse(value);
 17    };
 18    Lodis.prototype._expire_key = function(key) {
 19      this.del(key);
 20      return delete this._expiration_hash[key];
 21    };
 22    Lodis.prototype._get_set_or_default = function(key, default_value) {
 23      return this._unpack(this.get(key)) || default_value;
 24    };
 25    Lodis.prototype._get_set = function(key) {
 26      return this._get_set_or_default(key, []);
 27    };
 28    Lodis.prototype._extract_from_set = function() {
 29      var item, member, members, result, source, _i, _j, _len, _len2, _ref;
 30      source = arguments[0], members = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
 31      result = [];
 32      for (_i = 0, _len = members.length; _i < _len; _i++) {
 33        member = members[_i];
 34        if (__indexOf.call(this.smembers(source), member) >= 0) {
 35          _ref = this._get_set(source);
 36          for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
 37            item = _ref[_j];
 38            if (item !== member) {
 39              result.push(item);
 40            }
 41          }
 42        }
 43      }
 44      return result;
 45    };
 46    Lodis.prototype._get_unpacked = function(key) {
 47      try {
 48        return this._unpack(this.get(key));
 49      } catch (error) {
 50        return this.get(key);
 51      }
 52    };
 53    Lodis.prototype._get_hash = function(key) {
 54      return this._get_set_or_default(key, {});
 55    };
 56    Lodis.prototype._set_packed = function(key, value) {
 57      value = this._pack(value);
 58      return this.set(key, value);
 59    };
 60    Lodis.prototype._get_difference_or_intersection_for_sets = function() {
 61      var action, condition, head, key, keys, other_set, result, set, tail, value, _i, _j, _len, _len2;
 62      action = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
 63      if (action == null) {
 64        action = 'DIFF';
 65      }
 66      head = keys[0], tail = 2 <= keys.length ? __slice.call(keys, 1) : [];
 67      set = this._get_set(head);
 68      other_set = result = [];
 69      for (_i = 0, _len = tail.length; _i < _len; _i++) {
 70        key = tail[_i];
 71        other_set = other_set.concat(this._get_set(key));
 72      }
 73      for (_j = 0, _len2 = set.length; _j < _len2; _j++) {
 74        value = set[_j];
 75        condition = (function() {
 76          switch (action.toUpperCase()) {
 77            case 'DIFF':
 78              return __indexOf.call(other_set, value) < 0;
 79            case 'INTER':
 80              return __indexOf.call(other_set, value) >= 0;
 81          }
 82        })();
 83        if (condition) {
 84          result.push(value);
 85        }
 86      }
 87      return result.reverse();
 88    };
 89    Lodis.prototype._get_from_hash = function(key, options) {
 90      var hash, result, value;
 91      if (options == null) {
 92        options = {
 93          with_keys: true,
 94          with_values: true,
 95          only: []
 96        };
 97      }
 98      hash = this._get_hash(key);
 99      result = [];
100      for (key in hash) {
101        value = hash[key];
102        if (options["with_keys"]) {
103          result.push(key);
104        }
105        if (options["with_values"] || (options["only"] && __indexOf.call(options["only"], key) >= 0)) {
106          result.push(value);
107        }
108      }
109      return result;
110    };
111    Lodis.prototype._alter_int_value = function(key, quantity) {
112      var value;
113      if (this.exists(key)) {
114        value = parseInt(this.get(key));
115        if (typeof value === "number") {
116          value = value + quantity;
117          this.set(key, value);
118          return value;
119        } else {
120          throw new Error;
121        }
122      }
123    };
124    Lodis.prototype._expiration_hash = {};
125    Lodis.prototype.del = function() {
126      var key, keys, _i, _len;
127      keys = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
128      for (_i = 0, _len = keys.length; _i < _len; _i++) {
129        key = keys[_i];
130        this.storage.removeItem(key);
131      }
132      return true;
133    };
134    Lodis.prototype.set = function(key, value) {
135      this.storage.setItem(key, value);
136      return true;
137    };
138    Lodis.prototype.get = function(key) {
139      return this.storage.getItem(key);
140    };
141    Lodis.prototype.exists = function(key) {
142      return this.get(key) != null;
143    };
144    Lodis.prototype.dbsize = function() {
145      return this.storage.length;
146    };
147    Lodis.prototype.keys = function(regexp) {
148      var found_keys, i, key, _ref;
149      found_keys = [];
150      for (i = 0, _ref = this.dbsize() - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
151        key = this.storage.key(i);
152        if (key.match(regexp)) {
153          found_keys.push(key);
154        }
155      }
156      return found_keys;
157    };
158    Lodis.prototype.expire = function(key, seconds) {
159      var miliseconds, timeout_id;
160      miliseconds = seconds * 1000;
161      timeout_id = setTimeout(this._expire_key, miliseconds, key);
162      this._expiration_hash[key] = {
163        id: timeout_id,
164        timeout: new Date().getTime() + miliseconds
165      };
166      return true;
167    };
168    Lodis.prototype.expireat = function(key, miliseconds) {
169      var seconds;
170      if ((miliseconds < new Date().getTime()) || !this.exists(key)) {
171        return false;
172      }
173      seconds = (miliseconds - new Date().getTime()) / 1000;
174      this.expire(key, seconds);
175      return true;
176    };
177    Lodis.prototype.ttl = function(key) {
178      if (this.exists(key)) {
179        if (this._expiration_hash[key]) {
180          return Math.floor((this._expiration_hash[key].timeout - new Date().getTime()) / 1000);
181        } else {
182          return -1;
183        }
184      }
185    };
186    Lodis.prototype.append = function(key, value) {
187      if (this.exists(key)) {
188        return this.set(key, "" + (this.get(key)) + value);
189      }
190    };
191    Lodis.prototype.auth = function(password) {
192      return true;
193    };
194    Lodis.prototype.bgrewriteaof = function() {
195      return true;
196    };
197    Lodis.prototype.bgsave = function() {
198      return true;
199    };
200    Lodis.prototype.blpop = function() {};
201    Lodis.prototype.lrange = function(key, start, end) {
202      var result, set;
203      end += 1;
204      set = this._get_set(key);
205      if (end < 1) {
206        end = set.length + end;
207      }
208      result = set.slice(start, end);
209      if (result.constructor === String) {
210        result = [result];
211      }
212      return result;
213    };
214    Lodis.prototype.lpush = function(key, item) {
215      var set;
216      set = this._get_set(key);
217      set.unshift(item);
218      return this._set_packed(key, set);
219    };
220    Lodis.prototype.rpush = function(key, item) {
221      var set;
222      set = this._get_set(key);
223      set.push(item);
224      return this._set_packed(key, set);
225    };
226    Lodis.prototype.rpushx = function(key, item) {
227      if (this.exists(key)) {
228        return this.rpush(key, item);
229      }
230    };
231    Lodis.prototype.decr = function(key) {
232      return this.decrby(key, 1);
233    };
234    Lodis.prototype.incr = function(key) {
235      return this.incrby(key, 1);
236    };
237    Lodis.prototype.decrby = function(key, quantity) {
238      if (quantity == null) {
239        quantity = 1;
240      }
241      return this._alter_int_value(key, -quantity);
242    };
243    Lodis.prototype.incrby = function(key, quantity) {
244      if (quantity == null) {
245        quantity = 1;
246      }
247      return this._alter_int_value(key, quantity);
248    };
249    Lodis.prototype.echo = function(message) {
250      return message;
251    };
252    Lodis.prototype.flushall = function() {
253      return this.storage.clear();
254    };
255    Lodis.prototype.flushdb = function() {
256      return this.flushall();
257    };
258    Lodis.prototype.getrange = function(key, start, end) {
259      var string;
260      if (this.exists(key)) {
261        string = this.get(key);
262        if (start < 0) {
263          start = string.length + start;
264        }
265        if (end < 0) {
266          end = string.length + end;
267        }
268        return string.substr(start, end + 1);
269      }
270    };
271    Lodis.prototype.getset = function(key, value) {
272      var old_value;
273      if (this.exists(key)) {
274        old_value = this.get(key);
275        this.set(key, value);
276        return old_value;
277      }
278    };
279    Lodis.prototype.hset = function(hash_key, key, value) {
280      var hash;
281      hash = this._get_hash(hash_key);
282      hash[key] = value;
283      this._set_packed(hash_key, hash);
284      return true;
285    };
286    Lodis.prototype.hget = function(hash_key, key) {
287      var hash;
288      if (this.exists(hash_key)) {
289        hash = this._get_hash(hash_key);
290        return hash[key];
291      }
292    };
293    Lodis.prototype.hgetall = function(hash_key) {
294      if (this.exists(hash_key)) {
295        return this._get_from_hash(hash_key);
296      }
297    };
298    Lodis.prototype.hexists = function(hash_key, key) {
299      return this.hget(hash_key, key) != null;
300    };
301    Lodis.prototype.hkeys = function(hash_key) {
302      if (this.exists(hash_key)) {
303        return this._get_from_hash(hash_key, {
304          with_keys: true,
305          with_values: false
306        });
307      }
308    };
309    Lodis.prototype.hlen = function(hash_key) {
310      if (this.exists(hash_key)) {
311        return this.hkeys(hash_key).length;
312      }
313    };
314    Lodis.prototype.hincrby = function(hash_key, key, quantity) {
315      var new_value, old_value;
316      if (this.hexists(hash_key, key)) {
317        old_value = parseInt(this.hget(hash_key, key));
318        if (typeof old_value === "number") {
319          new_value = old_value + quantity;
320          this.hset(hash_key, key, new_value);
321          return new_value;
322        } else {
323          throw new Error("Invalid type");
324        }
325      }
326    };
327    Lodis.prototype.hmget = function() {
328      var hash_key, keys;
329      hash_key = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
330      if (this.exists(hash_key)) {
331        return this._get_from_hash(hash_key, {
332          with_values: true,
333          with_keys: false,
334          only: keys
335        });
336      }
337    };
338    Lodis.prototype.hmset = function() {
339      var hash_key, i, keys_and_values, result, value;
340      hash_key = arguments[0], keys_and_values = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
341      result = {};
342      for (i in keys_and_values) {
343        value = keys_and_values[i];
344        if (i % 2) {
345          result[keys_and_values[i - 1]] = value;
346        }
347      }
348      return this._set_packed(hash_key, result);
349    };
350    Lodis.prototype.hsetnx = function(hash_key, key, value) {
351      if (!this.exists(hash_key)) {
352        this.hset(hash_key, key, value);
353        return true;
354      } else {
355        return false;
356      }
357    };
358    Lodis.prototype.hvals = function(hash_key) {
359      if (this.exists(hash_key)) {
360        return this._get_from_hash(hash_key, {
361          with_keys: false,
362          with_values: true
363        });
364      }
365    };
366    Lodis.prototype.lindex = function(key, index) {
367      var hash;
368      if (this.exists(key)) {
369        hash = this._get_set(key);
370        if (index < 0) {
371          index = hash.length + index;
372        }
373        return hash[index] || false;
374      }
375    };
376    Lodis.prototype.linsert = function(key, direction, reference_value, value) {
377      var left_side, result, right_side, set, _ref;
378      if (this.exists(key)) {
379        direction = (function() {
380          switch (direction.toUpperCase()) {
381            case "BEFORE":
382              return -1;
383            case "AFTER":
384              return 1;
385          }
386        })();
387        set = this._get_set(key);
388        reference_value = set.indexOf(reference_value) + direction;
389        _ref = [set.slice(0, reference_value), set.slice(reference_value)], left_side = _ref[0], right_side = _ref[1];
390        result = left_side.concat([value]);
391        result = result.concat(right_side);
392        return this._set_packed(key, result);
393      }
394    };
395    Lodis.prototype.llen = function(key) {
396      var set;
397      if (this.exists(key)) {
398        set = this._get_set(key);
399        return set.length;
400      }
401    };
402    Lodis.prototype.lpop = function(key) {
403      var set, value;
404      if (this.exists(key)) {
405        set = this._get_set(key);
406        value = set.slice(1);
407        this._set_packed(key, value);
408        return value;
409      }
410    };
411    Lodis.prototype.lpushx = function(key, value) {
412      if (this.exists(key)) {
413        return this.lpush(key, value);
414      } else {
415        return false;
416      }
417    };
418    Lodis.prototype.lrem = function(key, count, item) {
419      var quantity, result, set, value, _i, _len;
420      if (this.exists(key)) {
421        quantity = Math.abs(count);
422        set = this._get_set(key);
423        if (count < 0) {
424          set = set.reverse();
425        }
426        result = [];
427        for (_i = 0, _len = set.length; _i < _len; _i++) {
428          value = set[_i];
429          if (value === item && quantity > 0) {
430            quantity -= 1;
431          } else {
432            result.push(value);
433          }
434        }
435        if (count < 0) {
436          result = result.reverse();
437        }
438        return this._set_packed(key, result);
439      }
440    };
441    Lodis.prototype.lset = function(key, index, value) {
442      var set;
443      if (this.exists(key)) {
444        set = this._get_set(key);
445        if (index < 0) {
446          index = set.length + index;
447        }
448        set[index] = value;
449        return this._set_packed(key, set);
450      }
451    };
452    Lodis.prototype.ltrim = function(key, start, end) {
453      var result, set;
454      if (this.exists(key)) {
455        set = this._get_set(key);
456        if (end < 0) {
457          end = set.length + end;
458        }
459        result = set.slice(start, (end + 1) || 9e9);
460        return this._set_packed(key, result);
461      }
462    };
463    Lodis.prototype.mget = function() {
464      var key, keys, result, _i, _len;
465      keys = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
466      result = [];
467      for (_i = 0, _len = keys.length; _i < _len; _i++) {
468        key = keys[_i];
469        result.push(this.get(key));
470      }
471      return result;
472    };
473    Lodis.prototype.mset = function() {
474      var i, keys_and_values, value, _results;
475      keys_and_values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
476      _results = [];
477      for (i in keys_and_values) {
478        value = keys_and_values[i];
479        if (i % 2) {
480          _results.push(this.set(keys_and_values[i - 1], value));
481        }
482      }
483      return _results;
484    };
485    Lodis.prototype.msetnx = function() {
486      var i, key_or_value, keys_and_values;
487      keys_and_values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
488      for (i in keys_and_values) {
489        key_or_value = keys_and_values[i];
490        if (!(i % 2) && this.exists(key_or_value)) {
491          return;
492        }
493      }
494      return this.mset.apply(this, keys_and_values);
495    };
496    Lodis.prototype.persist = function(key) {
497      if (this.exists(key)) {
498        if (this._expiration_hash[key]) {
499          clearTimeout(this._expiration_hash[key].id);
500          return delete this._expiration_hash[key];
501        }
502      }
503    };
504    Lodis.prototype.ping = function() {
505      return "PONG";
506    };
507    Lodis.prototype.randomkey = function() {
508      var keys;
509      keys = this.keys();
510      return keys[Math.floor(Math.random() * keys.length)];
511    };
512    Lodis.prototype.rename = function(key, new_key) {
513      var value;
514      value = this.get(key);
515      this.del(key);
516      return this.set(new_key, value);
517    };
518    Lodis.prototype.renamenx = function(key, new_key) {
519      if (!this.exists(new_key)) {
520        return this.rename(key, new_key);
521      }
522    };
523    Lodis.prototype.rpop = function(key) {
524      var set, value;
525      if (this.exists(key)) {
526        set = this._get_set(key);
527        value = set.pop();
528        this._set_packed(key, set);
529        return value;
530      }
531    };
532    Lodis.prototype.rpoplpush = function(hash_key, other_hash_key) {
533      var value;
534      if (this.exists(hash_key)) {
535        value = this.rpop(hash_key);
536        this.lpush(other_hash_key, value);
537        return value;
538      }
539    };
540    Lodis.prototype.sadd = function() {
541      var key, member, members, set, _i, _len, _results;
542      key = arguments[0], members = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
543      set = this._get_set(key);
544      _results = [];
545      for (_i = 0, _len = members.length; _i < _len; _i++) {
546        member = members[_i];
547        if (__indexOf.call(set, member) < 0) {
548          _results.push(this.lpush(key, member));
549        }
550      }
551      return _results;
552    };
553    Lodis.prototype.smembers = function(key) {
554      if (this.exists(key)) {
555        return this._get_set(key);
556      }
557    };
558    Lodis.prototype.save = function() {
559      return true;
560    };
561    Lodis.prototype.scard = function(key) {
562      return this._get_set(key).length;
563    };
564    Lodis.prototype.sdiff = function() {
565      var keys;
566      keys = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
567      return this._get_difference_or_intersection_for_sets.apply(this, ['DIFF'].concat(__slice.call(keys)));
568    };
569    Lodis.prototype.sdiffstore = function() {
570      var destination, keys;
571      destination = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
572      return this._set_packed(destination, this.sdiff.apply(this, keys));
573    };
574    Lodis.prototype.select = function(db) {
575      return db === 0;
576    };
577    Lodis.prototype.setex = function(key, expire, value) {
578      this.set(key, value);
579      return this.expire(key, expire);
580    };
581    Lodis.prototype.setnx = function(key, value) {
582      if (!this.exists(key)) {
583        return this.set(key, value);
584      }
585    };
586    Lodis.prototype.setrange = function(key, offset, value) {
587      var i, old_value, result;
588      old_value = (function() {
589        if (this.exists(key)) {
590          return this.get(key).substr(0, offset);
591        } else {
592          result = new String;
593          for (i = 0; 0 <= offset ? i < offset : i > offset; 0 <= offset ? i++ : i--) {
594            result += " ";
595          }
596          return result;
597        }
598      }).call(this);
599      return this.set(key, "" + old_value + value);
600    };
601    Lodis.prototype.shutdown = function() {
602      return true;
603    };
604    Lodis.prototype.sinter = function() {
605      var keys;
606      keys = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
607      return this._get_difference_or_intersection_for_sets.apply(this, ['INTER'].concat(__slice.call(keys)));
608    };
609    Lodis.prototype.sinterstore = function() {
610      var destination, keys;
611      destination = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
612      return this._set_packed(destination, this.sinter.apply(this, keys));
613    };
614    Lodis.prototype.sismember = function(key, value) {
615      var set;
616      if (this.exists(key)) {
617        set = this._get_set(key);
618        return set.indexOf(value) > -1;
619      }
620    };
621    Lodis.prototype.smove = function(source, destination, member) {
622      var result;
623      if (this.exists(source)) {
624        if (__indexOf.call(this.smembers(source), member) >= 0) {
625          result = this._extract_from_set(source, member);
626          this._set_packed(source, result);
627          this.rpush(destination, member);
628          return true;
629        } else {
630          return false;
631        }
632      }
633    };
634    Lodis.prototype.spop = function(key) {
635      var set;
636      if (this.exists(key)) {
637        set = this._get_set(key);
638        set.pop();
639        return this._set_packed(key, set);
640      }
641    };
642    Lodis.prototype.srandmember = function(key) {
643      var set;
644      if (this.exists(key)) {
645        set = this._get_set(key);
646        return set[Math.floor(Math.random() * set.length)];
647      }
648    };
649    Lodis.prototype.srem = function() {
650      var key, members, result, set;
651      key = arguments[0], members = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
652      if (this.exists(key)) {
653        set = this._get_set(key);
654        result = this._extract_from_set.apply(this, [key].concat(__slice.call(members)));
655        return this._set_packed(key, result);
656      }
657    };
658    Lodis.prototype.strlen = function(key) {
659      if (this.exists(key)) {
660        return this.get(key).length;
661      } else {
662        return 0;
663      }
664    };
665    Lodis.prototype.type = function(key) {
666      if (this.exists(key)) {
667        return this._get_unpacked(key).constructor.name.toLowerCase();
668      }
669    };
670    return Lodis;
671  })();
672}).call(this);