Skip to content

Commit 89920ef

Browse files
committed
Add support for using url instead of options for redis options. Closes #26
1 parent 116247d commit 89920ef

File tree

4 files changed

+94
-3
lines changed

4 files changed

+94
-3
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ multiCache.wrap(key2, function (cb) {
124124
});
125125
```
126126

127+
### Using a URL instead of options (if url is correct it overrides options host, port, db, auth_pass and ttl)
128+
Urls should be in this format `redis://[:password@]host[:port][/db-number][?ttl=value]`
129+
```js
130+
var cacheManager = require('cache-manager');
131+
var redisStore = require('cache-manager-redis');
132+
133+
var redisCache = cacheManager.caching({
134+
store: redisStore,
135+
url: 'redis://:XXXX@localhost:6379/0?ttl=600'
136+
});
137+
138+
// proceed with redisCache
139+
```
140+
127141
Tests
128142
-----
129143

index.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var RedisPool = require('sol-redis-pool');
44
var EventEmitter = require('events').EventEmitter;
5+
var redisUrl = require('redis-url');
56

67
/**
78
* The cache manager Redis Store module
@@ -20,11 +21,11 @@ function redisStore(args) {
2021

2122
// cache-manager should always pass in args
2223
/* istanbul ignore next */
23-
var redisOptions = args || {};
24+
var redisOptions = getFromUrl(args) || args || {};
2425
var poolSettings = redisOptions;
2526

26-
redisOptions.host = args.host || '127.0.0.1';
27-
redisOptions.port = args.port || 6379;
27+
redisOptions.host = redisOptions.host || '127.0.0.1';
28+
redisOptions.port = redisOptions.port || 6379;
2829

2930
var pool = new RedisPool(redisOptions, poolSettings);
3031

@@ -88,6 +89,43 @@ function redisStore(args) {
8889
};
8990
}
9091

92+
/**
93+
* Extracts options from an args.url
94+
* @param {Object} args
95+
* @param {String} args.url a string in format of redis://[:password@]host[:port][/db-number][?option=value]
96+
* @returns {Object} the input object args if it is falsy, does not contain url or url is not string, otherwise a new object with own properties of args
97+
* but with host, port, db, ttl and auth_pass properties overridden by those provided in args.url.
98+
*/
99+
function getFromUrl(args) {
100+
if (!args || !args.url || typeof args.url !== 'string') return args;
101+
102+
try {
103+
var options = redisUrl.parse(args.url);
104+
// make a copy so we don't change input args
105+
var newArgs = {};
106+
for(var key in args){
107+
if (key && args.hasOwnProperty(key)) {
108+
newArgs[key] = args[key];
109+
}
110+
}
111+
112+
newArgs.isCacheableValue = args.isCacheableValue && args.isCacheableValue.bind(newArgs);
113+
newArgs.host = options.hostname;
114+
newArgs.port = parseInt(options.port, 10);
115+
newArgs.db = parseInt(options.database, 10);
116+
newArgs.auth_pass = options.password;
117+
if(options.query && options.query.ttl){
118+
newArgs.ttl = parseInt(options.query.ttl, 10);
119+
}
120+
121+
return newArgs;
122+
} catch (e) {
123+
//url is unparsable so returning original
124+
return args;
125+
}
126+
127+
}
128+
91129
/**
92130
* Get a value for a given key.
93131
* @method get

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"license": "MIT",
2424
"dependencies": {
2525
"cache-manager": "^1.2.2",
26+
"redis-url": "^1.2.1",
2627
"sol-redis-pool": "^0.2.1"
2728
},
2829
"devDependencies": {

spec/lib/redis-store-spec.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,44 @@ describe('redisErrorEvent', function () {
346346
});
347347
});
348348

349+
describe('uses url to override redis options', function () {
350+
var redisCacheByUrl;
351+
352+
beforeAll(function () {
353+
redisCacheByUrl = require('cache-manager').caching({
354+
store: redisStore,
355+
// redis://[:password@]host[:port][/db-number][?option=value]
356+
url: 'redis://:' + config.redis.auth_pass +'@' + config.redis.host + ':' + config.redis.port + '/' + config.redis.db +'?ttl=' + config.redis.ttl,
357+
// some fakes to see that url overrides them
358+
host: 'test-host',
359+
port: -78,
360+
db: -7,
361+
auth_pass: 'test_pass',
362+
ttl: -6
363+
});
364+
});
365+
366+
it('should ignore other options if set in url', function() {
367+
expect(redisCacheByUrl.store._pool._redis_host).toBe(config.redis.host);
368+
expect(redisCacheByUrl.store._pool._redis_port).toBe(config.redis.port);
369+
expect(redisCacheByUrl.store._pool._redis_default_db).toBe(config.redis.db);
370+
expect(redisCacheByUrl.store._pool._redis_options.auth_pass).toBe(config.redis.auth_pass);
371+
});
372+
373+
it('should get and set values without error', function (done) {
374+
var key = 'byUrlKey';
375+
var value = 'test';
376+
redisCacheByUrl.set(key, value, function (err) {
377+
expect(err).toBe(null);
378+
redisCacheByUrl.get(key, function(getErr, val){
379+
expect(getErr).toBe(null);
380+
expect(val).toEqual(value);
381+
done();
382+
});
383+
});
384+
});
385+
});
386+
349387
describe('overridable isCacheableValue function', function () {
350388
var redisCache2;
351389

0 commit comments

Comments
 (0)