Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created April 8, 2015 23:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattpodwysocki/637870523aad0eeca3ac to your computer and use it in GitHub Desktop.
Save mattpodwysocki/637870523aad0eeca3ac to your computer and use it in GitHub Desktop.
/**
* PouchDB backend
*/
"use strict";
var async = require('async');
var _ = require('lodash');
/**
* Creates a PouchDB Backend
*/
function PouchDBBackend(db, prefix) {
this.db = db;
this.prefix = prefix || 'acl';
}
Object.defineProperties(PouchDBBackend.prototype, {
/**
* Begins a transaction
*/
begin: {
value: function () {
return [];
}
},
/**
* Ends a transaction.
*/
end: {
value: function (transaction, cb) {
async.series(transaction, cb);
}
},
/**
* Cleans the whole storage
*/
clean: {
value: function (cb) {
this.db.destroy().then(function () {
cb(null);
}).catch(function (error) {
cb(error);
});
}
},
/**
* Gets the contents at the bucket's key.
*/
get: {
value: function (bucket, key, cb) {
this.db.get(this._bucketKey(bucket, key), function (err, doc) {
if (err && err.status === 404) {
cb(null, []);
} else if (err) {
cb(err);
} else {
cb(null, _.without(_.keys(doc), "_rev", "_id"));
}
});
}
},
/**
* Returns the union of the values in the given keys.
*/
union: {
value: function (bucket, keys, cb) {
var self = this;
var fns = keys.map(function (key) {
return function (cb) {
self.get(bucket, key, function (err, doc) {
if (err) {
cb(err);
} else {
cb(null, doc);
}
});
};
});
async.parallel(fns, function (err, results) {
if (err) {
cb(err);
} else {
var keyArrays = [];
results.forEach(function(doc){
keyArrays.push.apply(keyArrays, _.keys(doc));
});
cb(null, _.without(_.union(keyArrays),"_rev","_id"));
}
});
}
},
/**
* Adds values to a given key inside a bucket.
*/
add: {
value: function (transaction, bucket, key, values) {
var self = this;
transaction.push(function (cb) {
var kb = self._bucketKey(bucket, key),
valueArray = makeArray(values),
newDoc = {};
valueArray.forEach(function (value) { newDoc[value] = true; });
self.db.get(kb, function (err, doc) {
if (err && err.status === 404) {
self.db.put(newDoc, kb, cb);
} else if (err) {
cb(err);
} else {
self.db.put(newDoc, kb, doc['_rev'], cb);
}
});
});
}
},
/**
* Delete the given key(s) at the bucket
*/
del: {
value: function (transaction, bucket, keys) {
var self = this;
transaction.push(function (cb) {
var keyArray = makeArray(keys), kbs = this._bucketKey(bucket, keyArray);
var fns = kbs.map(function (kb) {
return function (innerCb) {
self.db.get(kb, function (err, doc) {
if (err) {
innerCb(err);
} else {
self.db.remove(doc, innerCb);
}
})
};
});
async.parallel(fns, cb);
});
}
},
/**
* Removes values from a given key inside a bucket.
*/
remove: {
value: function (transaction, bucket, key, values) {
var self = this;
transaction.push(function (cb) {
var valueArray = makeArray(values),
kb = self._bucketKey(bucket, key);
self.db.get(kb, function (err, doc) {
values.forEach(function (value) {
delete doc[value];
});
self.db.put(doc, cb);
});
});
}
},
/**
* Private key generator function.
*/
_bucketKey: {
value: function(bucket, keys) {
if (Array.isArray(keys)) {
return keys.map(function (key) {
return this.prefix+'_'+bucket+'@'+key;
}, this);
} else {
return this.prefix+'_'+bucket+'@'+keys;
}
}
}
});
function makeArray(arr) {
return Array.isArray(arr) ? arr : [arr];
}
exports = module.exports = PouchDBBackend;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment