Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added redis and in-memory backends.

  • Loading branch information...
commit 0818e0c12e00a414a7fccae1e22fc9e897bf7a4e 1 parent c7723d8
@manast manast authored
Showing with 295 additions and 0 deletions.
  1. +149 −0 lib/memory-backend.js
  2. +146 −0 lib/redis-backend.js
View
149 lib/memory-backend.js
@@ -0,0 +1,149 @@
+/**
+ Memory Backend.
+
+ In-memory implementation of the storage.
+*/
+
+var
+ contract = require('./contract'),
+ _ = require('underscore');
+
+function MemoryBackend(){
+ this._buckets = {};
+};
+
+MemoryBackend.prototype = {
+ /**
+ Begins a transaction.
+ */
+ begin : function(){
+ // returns a transaction object(just an array of functions will do here.)
+ return [];
+ },
+
+ /**
+ Ends a transaction (and executes it)
+ */
+ end : function(transaction, cb){
+ contract(arguments).params('array', 'function').end();
+
+ // Execute transaction
+ for(var i=0, len=transaction.length;i<len;i++){
+ transaction[i]();
+ }
+ cb();
+ },
+
+ /**
+ Cleans the whole storage.
+ */
+ clean : function(cb){
+ contract(arguments).params('function').end();
+ this._buckets = {};
+ cb();
+ },
+
+ /**
+ Gets the contents at the bucket's key.
+ */
+ get : function(bucket, key, cb){
+ contract(arguments)
+ .params('string', 'string', 'function')
+ .end();
+
+ if(this._buckets[bucket]){
+ cb(null, this._buckets[bucket][key] || []);
+ }else{
+ cb();
+ }
+ },
+
+ /**
+ Returns the union of the values in the given keys.
+ */
+ union : function(bucket, keys, cb){
+ contract(arguments)
+ .params('string', 'array', 'function')
+ .end();
+
+ if(this._buckets[bucket]){
+ var keyArrays = [];
+ for(var i=0,len=keys.length;i<len;i++){
+ if(this._buckets[bucket][keys[i]]){
+ keyArrays.push.apply(keyArrays, this._buckets[bucket][keys[i]]);
+ }
+ }
+ cb(undefined, _.union(keyArrays));
+ }else{
+ cb();
+ }
+ },
+
+ /**
+ Adds values to a given key inside a bucket.
+ */
+ add : function(transaction, bucket, key, values){
+ contract(arguments)
+ .params('array', 'string', 'string','string|array')
+ .end();
+
+ var self = this;
+ values = makeArray(values);
+
+ transaction.push(function(){
+ if(!self._buckets[bucket]){
+ self._buckets[bucket] = {};
+ }
+ if(!self._buckets[bucket][key]){
+ self._buckets[bucket][key] = values;
+ }else{
+ self._buckets[bucket][key] = _.union(values, self._buckets[bucket][key]);
+ }
+ })
+ },
+
+ /**
+ Delete the given key(s) at the bucket
+ */
+ del : function(transaction, bucket, keys){
+ contract(arguments)
+ .params('array', 'string', 'string|array')
+ .end();
+
+ var self = this;
+ keys = makeArray(keys);
+
+ transaction.push(function(){
+ if(self._buckets[bucket]){
+ for(var i=0, len=keys.length;i<len;i++){
+ delete self._buckets[bucket][keys[i]];
+ }
+ }
+ })
+ },
+
+ /**
+ Removes values from a given key inside a bucket.
+ */
+ remove : function(transaction, bucket, key, values){
+ contract(arguments)
+ .params('array', 'string', 'string','string|array')
+ .end();
+
+ var self = this;
+ values = makeArray(values);
+ transaction.push(function(){
+ var old;
+ if(self._buckets[bucket] && (old = self._buckets[bucket][key])){
+ self._buckets[bucket][key] = _.difference(old, values);
+ }
+ console.log("REMOVE:"+self._buckets[bucket][key])
+ });
+ },
+}
+
+function makeArray(arr){
+ return Array.isArray(arr) ? arr : [arr];
+}
+
+exports = module.exports = MemoryBackend;
View
146 lib/redis-backend.js
@@ -0,0 +1,146 @@
+/**
+ Redis Backend.
+
+ Implementation of the storage backend using Redis
+*/
+
+var contract = require('./contract');
+
+function noop(){};
+
+function RedisBackend(redis, prefix){
+ this.redis = redis;
+ this.prefix = prefix || 'acl';
+}
+
+RedisBackend.prototype = {
+
+ /**
+ Begins a transaction
+ */
+ begin : function(){
+ return this.redis.multi();
+ },
+
+ /**
+ Ends a transaction (and executes it)
+ */
+ end : function(transaction, cb){
+ contract(arguments).params('object', 'function').end();
+ transaction.exec(function(){cb()});
+ },
+
+ /**
+ Cleans the whole storage.
+ */
+ clean : function(cb){
+ contract(arguments).params('function').end();
+ var self = this;
+ self.redis.keys(self.prefix+'*', function(err, keys){
+ if(keys.length){
+ self.redis.del(keys, function(){cb()});
+ }else{
+ cb();
+ }
+ });
+ },
+
+ /**
+ Gets the contents at the bucket's key.
+ */
+ get : function(bucket, key, cb){
+ contract(arguments)
+ .params('string', 'string', 'function')
+ .end();
+
+ key = this.bucketKey(bucket, key);
+
+ this.redis.smembers(key, cb);
+ },
+
+ /**
+ Returns the union of the values in the given keys.
+ */
+ union : function(bucket, keys, cb){
+ contract(arguments)
+ .params('string', 'array', 'function')
+ .end();
+
+ keys = this.bucketKey(bucket, keys);
+ this.redis.sunion(keys, cb);
+ },
+
+ /**
+ Adds values to a given key inside a bucket.
+ */
+ add : function(transaction, bucket, key, values){
+ contract(arguments)
+ .params('object', 'string', 'string','string|array')
+ .end();
+
+ key = this.bucketKey(bucket, key);
+
+ if (Array.isArray(values)){
+ values.forEach(function(value){
+ transaction.sadd(key, value);
+ });
+ }else{
+ transaction.sadd(key, values);
+ }
+ },
+
+ /**
+ Delete the given key(s) at the bucket
+ */
+ del : function(transaction, bucket, keys){
+ contract(arguments)
+ .params('object', 'string', 'string|array')
+ .end();
+
+ var self = this;
+
+ keys = Array.isArray(keys) ? keys : [keys]
+
+ keys = keys.map(function(key){
+ return self.bucketKey(bucket, key);
+ });
+
+ transaction.del(keys);
+ },
+
+ /**
+ Removes values from a given key inside a bucket.
+ */
+ remove : function(transaction, bucket, key, values){
+ contract(arguments)
+ .params('object', 'string', 'string','string|array')
+ .end();
+
+ key = this.bucketKey(bucket, key);
+
+ if (Array.isArray(values)){
+ values.forEach(function(value){
+ transaction.srem(key, value);
+ });
+ }else{
+ transaction.srem(key, values);
+ }
+ },
+
+ //
+ // Private methods
+ //
+
+ bucketKey : function(bucket, keys){
+ var self = this;
+ if(Array.isArray(keys)){
+ return keys.map(function(key){
+ return self.prefix+'_'+bucket+'@'+key;
+ });
+ }else{
+ return self.prefix+'_'+bucket+'@'+keys;
+ }
+ }
+}
+
+exports = module.exports = RedisBackend;
Please sign in to comment.
Something went wrong with that request. Please try again.