Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 56e49f8
Showing
8 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_Store | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
TESTS = $(shell find test/ -name '*.test.js') | ||
|
||
run-tests: | ||
@./node_modules/.bin/mocha --timeout 3000 $(TESTS) | ||
|
||
test: | ||
@$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests | ||
|
||
.PHONY: test | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
var redis = require('redis'); | ||
|
||
exports.createClient = function (port, host, prefix) { | ||
if (typeof port === 'object') { | ||
exports.redisClient = port; | ||
prefix = host; | ||
} else { | ||
exports.redisClient = redis.createClient(port, host); | ||
} | ||
exports.prefix = prefix || 'Ranaly:'; | ||
|
||
return { | ||
Amount: require('./type/amount')(exports), | ||
Realtime: require('./type/realtime')(exports), | ||
DataList: require('./type/data_list')(exports) | ||
}; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "ranaly", | ||
"version": "0.1.0", | ||
"description": "Ranaly client library", | ||
"keywords": ["ranaly"], | ||
"author": "Zihua Li <i@zihua.li> (http://zihua.li)", | ||
"main": "./index.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/luin/node_ranaly.git" | ||
}, | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"dependencies": { | ||
"redis": "0.8.2", | ||
"moment": "2.0.0" | ||
}, | ||
"devDependencies": { | ||
"redis-mock": "0.1.4", | ||
"mocha": "*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/*jshint undef:false */ | ||
var assert = require('assert'); | ||
var redis = require('redis-mock').createClient(); | ||
var ranaly = require('../index'); | ||
var client = ranaly.createClient(redis); | ||
|
||
var Amount = client.Amount; | ||
|
||
var aDay = 24 * 3600000; | ||
describe('Amount', function () { | ||
var amount = new ranaly.Amount('demo'); | ||
var hour; | ||
before(function (done) { | ||
amount._get(function (err, data) { | ||
hour = data; | ||
done(); | ||
}); | ||
}); | ||
|
||
describe('incr', function () { | ||
it('should have default increment and unixTime', function (done) { | ||
amount.incr(); | ||
hour += 1; | ||
amount._get(function (err, data) { | ||
assert.equal(hour, data); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should accept custom increment', function (done) { | ||
amount.incr(2); | ||
hour += 2; | ||
amount._get(function (err, data) { | ||
assert.equal(hour, data); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should accept custom date', function (done) { | ||
var yesterday = new Date(Date.now() - aDay); | ||
var yesterdayData; | ||
amount._get(yesterday, function (err, data) { | ||
yesterdayData = data; | ||
amount.incr(null, yesterday); | ||
amount.incr(10, yesterday); | ||
amount._get(yesterday, function (err, data) { | ||
assert.equal(yesterdayData + 11, data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
}); | ||
|
||
describe('Realtime', function () { | ||
var realtime = new ranaly.Realtime('demo'); | ||
describe('set', function () { | ||
it('should set the value successfully', function (done) { | ||
realtime.set(10, function () { | ||
realtime.get(function (err, result) { | ||
assert.equal(10, result); | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
describe('incr', function () { | ||
it('should increase the value successfully', function (done) { | ||
realtime.incr(function () { | ||
realtime.get(function (err, result) { | ||
assert.equal(11, result); | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
|
||
it('should accept a custom increment', function (done) { | ||
realtime.incr(10, function () { | ||
realtime.get(function (err, result) { | ||
assert.equal(21, result); | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
|
||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
var moment = require('moment'); | ||
var ZMSCORE = ' \ | ||
local result = {} \ | ||
local length = #ARGV \ | ||
for i = 1, length do \ | ||
local score = 0 \ | ||
if #ARGV[i] == 8 then \ | ||
for j = 0, 23 do \ | ||
local k = tostring(j) \ | ||
if #k == 1 then \ | ||
k = "0" .. k \ | ||
end \ | ||
local r = redis.call("zscore", KEYS[1], ARGV[i] .. k) \ | ||
if r then \ | ||
score = score + r \ | ||
end \ | ||
end \ | ||
else \ | ||
score = redis.call("zscore", KEYS[1], ARGV[i]) \ | ||
if not score then \ | ||
score = 0 \ | ||
else \ | ||
score = tonumber(score) \ | ||
end \ | ||
end \ | ||
result[i] = score \ | ||
end \ | ||
return result \ | ||
'; | ||
|
||
var ZSUMSCORE = ' \ | ||
local length = #ARGV \ | ||
local score = 0 \ | ||
if #ARGV >= 1 then \ | ||
for i = 1, length do \ | ||
if #ARGV[i] == 8 then \ | ||
for j = 0, 23 do \ | ||
local k = tostring(j) \ | ||
if #k == 1 then \ | ||
k = "0" .. k \ | ||
end \ | ||
local result = redis.call("zscore", KEYS[1], ARGV[i] .. k) \ | ||
if result then \ | ||
score = score + result \ | ||
end \ | ||
end \ | ||
else \ | ||
local result = redis.call("zscore", KEYS[1], ARGV[i]) \ | ||
if result then \ | ||
score = score + result \ | ||
end \ | ||
end \ | ||
end \ | ||
else \ | ||
local result = redis.call("get", KEYS[1] .. ":TOTAL") \ | ||
if result then \ | ||
score = tonumber(result) \ | ||
end \ | ||
end \ | ||
return score \ | ||
'; | ||
module.exports = function (ranaly) { | ||
var db = ranaly.redisClient; | ||
|
||
var Amount = function (bucket) { | ||
this.bucket = bucket; | ||
this.key = ranaly.prefix + 'AMOUNT' + ':' + this.bucket; | ||
}; | ||
|
||
Amount.prototype.incr = function (increment, when, callback) { | ||
if (typeof increment === 'function') { | ||
callback = increment; | ||
increment = void 0; | ||
} else if (typeof when === 'function') { | ||
callback = when; | ||
when = void 0; | ||
} | ||
if (typeof increment !== 'number') { | ||
increment = 1; | ||
} | ||
when = moment(when); | ||
db.multi() | ||
.incrby(this.key + ':TOTAL', increment) | ||
.zincrby(this.key, increment,when.format('YYYYMMDDHH')) | ||
.exec(function (err, result) { | ||
if (typeof callback === 'function') { | ||
callback(err, Array.isArray(result) ? result[0] : result); | ||
} | ||
}); | ||
}; | ||
|
||
Amount.prototype.get = function (timeList, callback) { | ||
var next = function (err, result) { | ||
callback(err, result); | ||
}; | ||
db['eval'].apply(db, [ZMSCORE].concat(1).concat(this.key).concat(timeList).concat(next)); | ||
}; | ||
|
||
Amount.prototype.sum = function (timeList, callback) { | ||
var next = function (err, result) { | ||
callback(err, result); | ||
}; | ||
var tl = [ZSUMSCORE].concat(1).concat(this.key); | ||
if (Array.isArray(timeList) && timeList.length > 0) { | ||
tl = tl.concat(timeList).concat(next); | ||
} else { | ||
tl = tl.concat(next); | ||
} | ||
db['eval'].apply(db, tl); | ||
}; | ||
|
||
return Amount; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
module.exports = function (ranaly) { | ||
var db = ranaly.redisClient; | ||
|
||
var DataList = function (bucket) { | ||
this.bucket = bucket; | ||
this.key = ranaly.prefix + 'DATALIST' + ':' + this.bucket; | ||
}; | ||
|
||
DataList.prototype.push = function (data, trim, callback) { | ||
if (typeof trim === 'function') { | ||
callback = trim; | ||
trim = void 0; | ||
} | ||
if (typeof increment !== 'number') { | ||
trim = 100; | ||
} | ||
|
||
db.multi() | ||
.lpush(this.key, JSON.stringify(data)) | ||
.ltrim(this.key, 0, trim - 1) | ||
.exec(function (err, result) { | ||
if (typeof callback === 'function') { | ||
if (!err) result = result[0]; | ||
callback(err, result); | ||
} | ||
}); | ||
}; | ||
|
||
DataList.prototype.range = function (start, stop, callback) { | ||
db.lrange(this.key, start, stop, function (err, result) { | ||
if (!err && Array.isArray(result)) { | ||
result = result.map(function (r) { | ||
return JSON.parse(r); | ||
}); | ||
} | ||
callback(err, result); | ||
}); | ||
}; | ||
|
||
DataList.prototype.len = function (callback) { | ||
db.llen(this.key, callback); | ||
}; | ||
|
||
return DataList; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module.exports = function (ranaly) { | ||
var db = ranaly.redisClient; | ||
|
||
var Realtime = function (bucket) { | ||
this.bucket = bucket; | ||
this.key = ranaly.prefix + 'REALTIME' + ':' + this.bucket; | ||
}; | ||
|
||
Realtime.prototype.incr = function (increment, callback) { | ||
if (typeof increment === 'function') { | ||
callback = increment; | ||
increment = void 0; | ||
} | ||
if (typeof increment !== 'number') { | ||
increment = 1; | ||
} | ||
|
||
db.incrby(this.key, increment, function (err, result) { | ||
if (!err) { | ||
db.publish(this.key, result); | ||
} | ||
if (typeof callback === 'function') { | ||
callback(err, result); | ||
} | ||
}); | ||
}; | ||
|
||
Realtime.prototype.get = function (callback) { | ||
db.get(this.key, function (err, result) { | ||
callback(err, parseInt(result, 10) || 0); | ||
}); | ||
}; | ||
|
||
Realtime.prototype.set = function (value, callback) { | ||
value = parseInt(value, 10) || 0; | ||
db.set(this.key, value, callback); | ||
console.log('Publish To: ' + this.key); | ||
db.publish(this.key, value); | ||
}; | ||
|
||
return Realtime; | ||
}; |