diff --git a/lib/adapters/memory.js b/lib/adapters/memory.js index 46596d0..f9dbcc7 100644 --- a/lib/adapters/memory.js +++ b/lib/adapters/memory.js @@ -1,76 +1,76 @@ var LRU = require("lru-cache"); exports.initialize = function initializeMemory(store, callback) { - store.adapter = { - createBucket: function (options) { - return new Memory(options); - } - }; - process.nextTick(callback); + store.adapter = { + createBucket: function (options) { + return new Memory(options); + } + }; + process.nextTick(callback); }; function Memory(options) { - options = options || {}; - this.name = 'memory'; - this.bucket = LRU({ - max: options.max || 500, - maxAge: options.ttl ? options.ttl * 1000 : null - }); + options = options || {}; + this.name = 'memory'; + this.bucket = LRU({ + max: options.max || 500, + maxAge: options.ttl ? options.ttl * 1000 : null + }); } Memory.prototype.has = function (key, cb) { - cb(null, this.bucket.has(key)); - return this; + cb(null, this.bucket.has(key)); + return this; }; Memory.prototype.get = function (key, cb) { - cb(null, this.bucket.get(key)); - return this; + cb(null, this.bucket.get(key)); + return this; }; Memory.prototype.set = function (key, value, cb) { - this.bucket.set(key, value); - if (cb) cb(null, value); - return this; + this.bucket.set(key, value); + if (cb) cb(null, value); + return this; }; Memory.prototype.getset = function (key, value, cb) { - if (typeof value === 'function') { - cb = value; - value = null; - } - var result = this.bucket.get(key); - this.bucket.set(key, value); - cb(null, result); - return this; + if (typeof value === 'function') { + cb = value; + value = null; + } + var result = this.bucket.get(key); + this.bucket.set(key, value); + cb(null, result); + return this; }; Memory.prototype.getdel = function (key, cb) { - var result = this.bucket.get(key); - this.bucket.del(key); - cb(null, result); - return this; + var result = this.bucket.get(key); + this.bucket.del(key); + cb(null, result); + return this; }; Memory.prototype.del = function (key, cb) { - this.bucket.del(key); - if (cb) cb(); - return this; + this.bucket.del(key); + if (cb) cb(); + return this; }; Memory.prototype.keys = function (pattern, cb) { - if (typeof pattern === 'function') { - cb = pattern; - } - cb(null, this.bucket.keys()); - return this; + if (typeof pattern === 'function') { + cb = pattern; + } + cb(null, this.bucket.keys()); + return this; }; Memory.prototype.clear = function (pattern, cb) { - if (typeof pattern === 'function') { - cb = pattern; - } - var del_count = this.bucket.itemCount; - this.bucket.reset(); - cb(null, del_count); + if (typeof pattern === 'function') { + cb = pattern; + } + var del_count = this.bucket.itemCount; + this.bucket.reset(); + cb(null, del_count); }; diff --git a/lib/adapters/redis.js b/lib/adapters/redis.js index 6766116..d14179d 100644 --- a/lib/adapters/redis.js +++ b/lib/adapters/redis.js @@ -5,124 +5,129 @@ var defaultPort = 6379; var defaultHost = 'localhost'; var defaultPacker = { - pack: function (target) { return JSON.stringify(target); }, - unpack: function (target) { return JSON.parse(target); } + pack: function (target) { + return JSON.stringify(target); + }, + unpack: function (target) { + return JSON.parse(target); + } }; // settings ref: https://www.npmjs.com/package/redis exports.initialize = function initializeRedis(store, callback) { - var settings = store.settings || {}; - var client, packer = defaultPacker; - if (settings instanceof redis.RedisClient) { - client = settings; - process.nextTick(done); + var settings = store.settings || {}; + var client, packer = defaultPacker; + if (settings instanceof redis.RedisClient) { + client = settings; + process.nextTick(done); + } else { + if (settings.client instanceof redis.RedisClient) { + client = settings.client; } else { - if (settings.client instanceof redis.RedisClient) { - client = settings.client; + settings.port = settings.port || defaultPort; + settings.host = settings.host || defaultHost; + client = redis.createClient(settings.port, settings.host, settings); + client.on('connect', function () { + var db = settings.database || settings.db; + if (db) { + client.select(db, done); } else { - settings.port = settings.port || defaultPort; - settings.host = settings.host || defaultHost; - client = redis.createClient(settings.port, settings.host, settings); - client.on('connect', function () { - var db = settings.database || settings.db; - if (db) { - client.select(db, done); - } else { - done(); - } - }); - + done(); } - - if (settings.packer) packer = settings.packer; + }); } - store.client = client; - store.adapter = { - createBucket: function (options) { - return new Redis(client, packer, options); - } - }; + if (settings.packer) packer = settings.packer; + + } - function done() { - if (callback) callback(); + store.client = client; + store.adapter = { + createBucket: function (options) { + return new Redis(client, packer, options); } + }; + + function done() { + if (callback) callback(); + } }; function Redis(client, packer, options) { - options = options || {}; - this.name = 'redis'; - this.client = client; - this.packer = packer; - this.ttl = options.ttl; - this.type = options.type; - - this.isHash = _.contains(['hash', 'map', 'object'], this.type); + options = options || {}; + this.name = 'redis'; + this.client = client; + this.packer = packer; + this.ttl = options.ttl; + this.type = options.type; + + this.isHash = _.contains(['hash', 'map', 'object'], this.type); } Redis.prototype.get = function (key, cb) { - if (this.isHash) { - this.client.hgetall(key, cb); - } else { - var packer = this.packer; - this.client.get(key, function (err, result) { - cb(err, packer.unpack(result)); - }); - } - return this; + if (this.isHash) { + this.client.hgetall(key, cb); + } else { + var packer = this.packer; + this.client.get(key, function (err, result) { + cb(err, packer.unpack(result)); + }); + } + return this; }; Redis.prototype.set = function (key, value, cb) { - if (this.isHash) { - cb = cb || function () {}; - this.client.hmset(key, value, cb); + if (this.isHash) { + cb = cb || function () { + }; + this.client.hmset(key, value, cb); + } else { + if (this.ttl) { + this.client.setex(key, this.ttl, this.packer.pack(value), cb); } else { - if (this.ttl) { - this.client.setex(key, this.ttl, this.packer.pack(value), cb); - } else { - this.client.set(key, this.packer.pack(value), cb); - } + this.client.set(key, this.packer.pack(value), cb); } - return this; + } + return this; }; Redis.prototype.getset = function (key, value, cb) { - var self = this; - if (this.isHash) { - this.get(key, function (err, result) { - self.set(key, value, function (err) { - cb(err, result); - }); - }); - } else { - var packer = this.packer; - this.client.getset(key, packer.pack(value), function (err, result) { - cb(err, packer.unpack(result)); - }); - } - return this; + var self = this; + if (this.isHash) { + this.get(key, function (err, result) { + self.set(key, value, function (err) { + cb(err, result); + }); + }); + } else { + var packer = this.packer; + this.client.getset(key, packer.pack(value), function (err, result) { + cb(err, packer.unpack(result)); + }); + } + return this; }; Redis.prototype.getdel = function (key, cb) { - var self = this; - this.get(key, function (err, value) { - self.del(key, function (err) { - cb(err, value); - }); + var self = this; + this.get(key, function (err, value) { + self.del(key, function (err) { + cb(err, value); }); - return this; + }); + return this; }; Redis.prototype.has = function (key, cb) { - this.client.exists(key, cb); - return this; + this.client.exists(key, cb); + return this; }; Redis.prototype.del = function (key, cb) { - this.client.del(key, cb); - return this; + this.client.del(key, cb); + return this; }; /** @@ -134,15 +139,15 @@ Redis.prototype.del = function (key, cb) { */ Redis.prototype.keys = function (pattern, callback) { - if (typeof pattern === 'function') { - callback = pattern; - pattern = '*'; - } - this.client.keys(pattern, function (err, keys) { - if (err) return callback(err, null); - if (!keys) return callback(null, []); - return callback(null, keys); - }); + if (typeof pattern === 'function') { + callback = pattern; + pattern = '*'; + } + this.client.keys(pattern, function (err, keys) { + if (err) return callback(err, null); + if (!keys) return callback(null, []); + return callback(null, keys); + }); }; /** @@ -154,40 +159,41 @@ Redis.prototype.keys = function (pattern, callback) { */ Redis.prototype.clear = function (pattern, callback) { - callback = callback || function () {}; - if (typeof pattern === 'function') { - callback = pattern; - pattern = '*'; - } - var self = this; - this.keys(pattern, function (err, keys) { - if (err) return callback(err, null); - if (!keys) return callback(err, []); - var error = false, remaining = keys.length, del_count = 0; - if (remaining === 0) return callback(err, 0); - return keys.forEach(function (key) { - self.client.del(key, function (err) { - if (error) { - return null; - } else if (err) { - error = true; - return callback(err, null); - } - del_count++; - if (!--remaining) callback(err, del_count); - return null; - }); - }); + callback = callback || function () { + }; + if (typeof pattern === 'function') { + callback = pattern; + pattern = '*'; + } + var self = this; + this.keys(pattern, function (err, keys) { + if (err) return callback(err, null); + if (!keys) return callback(err, []); + var error = false, remaining = keys.length, del_count = 0; + if (remaining === 0) return callback(err, 0); + return keys.forEach(function (key) { + self.client.del(key, function (err) { + if (error) { + return null; + } else if (err) { + error = true; + return callback(err, null); + } + del_count++; + if (!--remaining) callback(err, del_count); + return null; + }); }); + }); }; Redis.prototype.close = function (cb) { - if (this.client.connected) { - this.client.once('end', cb); - this.client.quit(); - } else { - process.nextTick(cb); - } + if (this.client.connected) { + this.client.once('end', cb); + this.client.quit(); + } else { + process.nextTick(cb); + } }; diff --git a/lib/bucket.js b/lib/bucket.js index 18c2eca..7463c96 100644 --- a/lib/bucket.js +++ b/lib/bucket.js @@ -5,112 +5,113 @@ var async = require('async'); module.exports = exports = Bucket; function Bucket(namespace, adapter, options) { - this.namespace = namespace; - this.adapter = adapter; - this._load = options.load; - this._loading = {}; - this._allowStale = options.stale; + this.namespace = namespace; + this.adapter = adapter; + this._load = options.load; + this._loading = {}; + this._allowStale = options.stale; + this._delimiter = options.delimiter || ':'; } Bucket.prototype.getKey = function (key) { - if (!this.namespace) return key; - return this.namespace + ':' + key; + if (!this.namespace) return key; + return this.namespace + this._delimiter + key; }; Bucket.prototype.has = -Bucket.prototype.exists = function (key, cb) { + Bucket.prototype.exists = function (key, cb) { this.adapter.exists(this.getKey(key), cb); return this; -}; + }; Bucket.prototype.get = function (key, data, cb) { - if (typeof data === 'function') { - cb = data; - data = key; - } - var _key = this.getKey(key); - if (!this._load) return this.adapter.get(_key, cb); + if (typeof data === 'function') { + cb = data; + data = key; + } + var _key = this.getKey(key); + if (!this._load) return this.adapter.get(_key, cb); - var loading = this._loading; - if (loading[key]) return loading[key].push(cb); + var loading = this._loading; + if (loading[key]) return loading[key].push(cb); - var self = this; - async.waterfall([ - function (callback) { - self.adapter.has(_key, callback); - }, - function (has, callback) { - self.adapter.get(_key, function (err, value) { - if (err) return cb(err); - if (void 0 !== value && (has || self._allowStale)) { - return cb(null, value); - } else { - loading[key] = [cb]; - } - return self._load(data, callback); - }); - }, - function (value, callback) { - self.adapter.set(_key, value, function (err) { - callback(err, value); - }); + var self = this; + async.waterfall([ + function (callback) { + self.adapter.has(_key, callback); + }, + function (has, callback) { + self.adapter.get(_key, function (err, value) { + if (err) return cb(err); + if (void 0 !== value && (has || self._allowStale)) { + return cb(null, value); + } else { + loading[key] = [cb]; } - ], function (err, value) { - var cbs = loading[key]; - if (!cbs) return; - loading[key] = false; - if (err) value = null; - cbs.forEach(function (cb) { - cb(err, value); - }); + return self._load(data, callback); + }); + }, + function (value, callback) { + self.adapter.set(_key, value, function (err) { + callback(err, value); + }); + } + ], function (err, value) { + var cbs = loading[key]; + if (!cbs) return; + loading[key] = false; + if (err) value = null; + cbs.forEach(function (cb) { + cb(err, value); }); + }); - return self; + return self; }; Bucket.prototype.set = function (key, value, cb) { - this.adapter.set(this.getKey(key), value, cb); - return this; + this.adapter.set(this.getKey(key), value, cb); + return this; }; Bucket.prototype.getset = function (key, value, cb) { - this.adapter.getset(this.getKey(key), value, cb); - return this; + this.adapter.getset(this.getKey(key), value, cb); + return this; }; Bucket.prototype.getdel = function (key, cb) { - this.adapter.getdel(this.getKey(key), cb); - return this; + this.adapter.getdel(this.getKey(key), cb); + return this; }; Bucket.prototype.del = function (key, cb) { - this.adapter.del(this.getKey(key), cb); - return this; + this.adapter.del(this.getKey(key), cb); + return this; }; Bucket.prototype.keys = function (pattern, cb) { - if (typeof pattern === 'function') { - cb = pattern; - pattern = '*'; + if (typeof pattern === 'function') { + cb = pattern; + pattern = '*'; + } + var namespace_len = this.namespace.length + 1; + this.adapter.keys(this.namespace + ':' + pattern, function (err, keys) { + if (err) return cb(err, null); + if (!keys) return cb(null, []); + if (null == keys) return cb(null, []); + for (var i = 0, l = keys.length; i < l; i++) { + keys[i] = keys[i].substr(namespace_len); } - var namespace_len = this.namespace.length + 1; - this.adapter.keys(this.namespace + ':' + pattern, function (err, keys) { - if (err) return cb(err, null); - if (!keys) return cb(null, []); - if (null == keys) return cb(null, []); - for (var i = 0, l = keys.length; i < l; i++) { - keys[i] = keys[i].substr(namespace_len); - } - return cb(null, keys); - }); - return this; + return cb(null, keys); + }); + return this; }; Bucket.prototype.clear = function (pattern, cb) { - if (typeof pattern === 'function') { - cb = pattern; - pattern = '*'; - } - this.adapter.clear(this.namespace + ':' + pattern, cb); - return this; + if (typeof pattern === 'function') { + cb = pattern; + pattern = '*'; + } + this.adapter.clear(this.namespace + ':' + pattern, cb); + return this; }; diff --git a/lib/store.js b/lib/store.js index ad7f599..4a26ab4 100644 --- a/lib/store.js +++ b/lib/store.js @@ -10,94 +10,94 @@ module.exports = exports = Store; function Store(name, settings) { - if (!(this instanceof Store)) return new Store(name, settings); - - EventEmitter.call(this); - - this.name = name; - this.settings = settings; - - this.defaultBucketOptions = { - ttl: 0 - }; - this.defaultNamespace = 'bucket'; - this.buckets = {}; - - // and initialize store using adapter - // this is only one initialization entry point of adapter - // this module should define `adapter` member of `this` (store) - var adapter; - if (typeof name === 'object') { - adapter = name; - this.name = adapter.name; - } else if (name.match(/^\//)) { - // try absolute path - adapter = require(name); - } else if (existsSync(__dirname + '/adapters/' + name + '.js')) { - // try built-in adapter - adapter = require('./adapters/' + name); - } else { - // try foreign adapter - try { - adapter = require('kvs-' + name); - } catch (e) { - return console.log('\nWARNING: KVS adapter "' + name + '" is not installed,\nso your models would not work, to fix run:\n\n npm install kvs-' + name, '\n'); - } + if (!(this instanceof Store)) return new Store(name, settings); + + EventEmitter.call(this); + + this.name = name; + this.settings = settings; + + this.defaultBucketOptions = { + ttl: 0 + }; + this.defaultNamespace = 'bucket'; + this.buckets = {}; + + // and initialize store using adapter + // this is only one initialization entry point of adapter + // this module should define `adapter` member of `this` (store) + var adapter; + if (typeof name === 'object') { + adapter = name; + this.name = adapter.name; + } else if (name.match(/^\//)) { + // try absolute path + adapter = require(name); + } else if (existsSync(__dirname + '/adapters/' + name + '.js')) { + // try built-in adapter + adapter = require('./adapters/' + name); + } else { + // try foreign adapter + try { + adapter = require('kvs-' + name); + } catch (e) { + return console.log('\nWARNING: KVS adapter "' + name + '" is not installed,\nso your models would not work, to fix run:\n\n npm install kvs-' + name, '\n'); } - - var that = this; - adapter.initialize(this, function () { - that.initialized = true; - that.emit('ready'); + } + + var that = this; + adapter.initialize(this, function () { + that.initialized = true; + that.emit('ready'); + }); + + that.ready = function (cb) { + if (that.initialized) return cb(); + that.on('ready', function () { + cb(); }); + }; - that.ready = function (cb) { - if (that.initialized) return cb(); - that.on('ready', function () { - cb(); - }); - }; - - return this; + return this; } require('util').inherits(Store, EventEmitter); Store.prototype.bucketOptions = function (namespace) { - var bucketOptions = {}; - if (this.settings && this.settings.buckets) { - bucketOptions = this.settings.buckets[namespace] || {}; - } - return _.assign({}, this.defaultBucketOptions, bucketOptions); + var bucketOptions = {}; + if (this.settings && this.settings.buckets) { + bucketOptions = this.settings.buckets[namespace] || {}; + } + return _.assign({}, this.defaultBucketOptions, bucketOptions); }; Store.prototype.createBucket = function (namespace, options) { - if (typeof namespace === 'object') { - options = namespace; - namespace = null; - } - namespace = namespace || this.defaultNamespace; - options = options || this.bucketOptions(namespace); - return new Bucket(namespace, this.adapter.createBucket(options), options); + if (typeof namespace === 'object') { + options = namespace; + namespace = null; + } + namespace = namespace || this.defaultNamespace; + options = options || this.bucketOptions(namespace); + return new Bucket(namespace, this.adapter.createBucket(options), options); }; Store.prototype.bucket = function (namespace) { - namespace = namespace || this.defaultNamespace; - var c = this.buckets[namespace]; - if (!c) { - c = this.createBucket(namespace); - this.buckets[namespace] = c; - } - return c; + namespace = namespace || this.defaultNamespace; + var c = this.buckets[namespace]; + if (!c) { + c = this.createBucket(namespace); + this.buckets[namespace] = c; + } + return c; }; /** * Close store connection */ Store.prototype.close = function close(cb) { - if (typeof this.adapter.close === 'function') { - this.adapter.close(cb); - } else if (cb) { - cb(); - } + if (typeof this.adapter.close === 'function') { + this.adapter.close(cb); + } else if (cb) { + cb(); + } }; \ No newline at end of file