diff --git a/lib/leaderboard.js b/lib/leaderboard.js index d98b7e3..50ee959 100644 --- a/lib/leaderboard.js +++ b/lib/leaderboard.js @@ -160,14 +160,15 @@ */ Leaderboard.prototype.rankMemberIn = function(leaderboardName, member, score, memberData, callback) { - var transaction; + var data, transaction; if (memberData == null) { memberData = null; } transaction = this.redisConnection.multi(); + data = typeof memberData === 'object' ? JSON.stringify(memberData) : memberData; transaction.zadd(leaderboardName, score, member); if (memberData != null) { - transaction.hset(this.memberDataKey(leaderboardName), member, memberData); + transaction.hset(this.memberDataKey(leaderboardName), member, data); } return transaction.exec(function(err, reply) { if (callback) { @@ -187,16 +188,17 @@ */ Leaderboard.prototype.rankMemberAcross = function(leaderboardNames, member, score, memberData, callback) { - var leaderboardName, transaction, _i, _len; + var data, leaderboardName, transaction, _i, _len; if (memberData == null) { memberData = null; } + data = typeof memberData === 'object' ? JSON.stringify(memberData) : memberData; transaction = this.redisConnection.multi(); for (_i = 0, _len = leaderboardNames.length; _i < _len; _i++) { leaderboardName = leaderboardNames[_i]; transaction.zadd(leaderboardName, score, member); if (memberData != null) { - transaction.hset(this.memberDataKey(leaderboardName), member, memberData); + transaction.hset(this.memberDataKey(leaderboardName), member, data); } } return transaction.exec(function(err, reply) { @@ -328,9 +330,13 @@ */ Leaderboard.prototype.memberDataForIn = function(leaderboardName, member, callback) { - return this.redisConnection.hget(this.memberDataKey(leaderboardName), member, function(err, reply) { - return callback(reply); - }); + return this.redisConnection.hget(this.memberDataKey(leaderboardName), member, (function(_this) { + return function(err, reply) { + var result; + result = _this.isJsonData(reply) ? JSON.parse(reply) : reply; + return callback(result); + }; + })(this)); }; @@ -357,7 +363,9 @@ */ Leaderboard.prototype.updateMemberDataFor = function(leaderboardName, member, memberData, callback) { - return this.redisConnection.hset(this.memberDataKey(leaderboardName), member, memberData, function(err, reply) { + var data; + data = typeof memberData === 'object' ? JSON.stringify(memberData) : memberData; + return this.redisConnection.hset(this.memberDataKey(leaderboardName), member, data, function(err, reply) { if (callback) { return callback(reply); } @@ -1541,6 +1549,26 @@ return "" + leaderboardName + ":" + this.memberDataNamespace; }; + + /* + * Checks a string if encoded json + * + * @param value [String] String to be checked. + * + * @return boolean of string is json + */ + + Leaderboard.prototype.isJsonData = function(value) { + var e; + try { + JSON.parse(value); + } catch (_error) { + e = _error; + return false; + } + return true; + }; + return Leaderboard; })(); diff --git a/spec/leaderboard_spec.coffee b/spec/leaderboard_spec.coffee index 5089392..970de93 100644 --- a/spec/leaderboard_spec.coffee +++ b/spec/leaderboard_spec.coffee @@ -111,6 +111,17 @@ describe 'Leaderboard', -> reply.should.equal('Optional member data') done()) + it 'should allow you to store and retrieve optional member data as object', (done) -> + data = { + index: 3, + data: 'Optional member data' + } + @leaderboard.rankMember('member', 1, data, (reply) -> ) + + @leaderboard.memberDataFor('member', (reply) -> + reply.should.deepEqual(data) + done()) + it 'should allow you to update optional member data', (done) -> @leaderboard.rankMember('member', 1, 'Optional member data', (reply) -> ) diff --git a/src/leaderboard.coffee b/src/leaderboard.coffee index 508b5b4..53c2f5f 100644 --- a/src/leaderboard.coffee +++ b/src/leaderboard.coffee @@ -112,8 +112,9 @@ class Leaderboard ### rankMemberIn: (leaderboardName, member, score, memberData = null, callback) -> transaction = @redisConnection.multi() + data = if typeof memberData is 'object' then JSON.stringify(memberData) else memberData transaction.zadd(leaderboardName, score, member) - transaction.hset(this.memberDataKey(leaderboardName), member, memberData) if memberData? + transaction.hset(this.memberDataKey(leaderboardName), member, data) if memberData? transaction.exec((err, reply) -> callback(reply) if callback) @@ -126,10 +127,11 @@ class Leaderboard # @param member_data [String] Optional member data. ### rankMemberAcross: (leaderboardNames, member, score, memberData = null, callback) -> + data = if typeof memberData is 'object' then JSON.stringify(memberData) else memberData transaction = @redisConnection.multi() for leaderboardName in leaderboardNames transaction.zadd(leaderboardName, score, member) - transaction.hset(this.memberDataKey(leaderboardName), member, memberData) if memberData? + transaction.hset(this.memberDataKey(leaderboardName), member, data) if memberData? transaction.exec((err, reply) -> callback(reply) if callback) @@ -222,8 +224,9 @@ class Leaderboard # @return String of optional member data. ### memberDataForIn: (leaderboardName, member, callback) -> - @redisConnection.hget(this.memberDataKey(leaderboardName), member, (err, reply) -> - callback(reply)) + @redisConnection.hget(this.memberDataKey(leaderboardName), member, (err, reply) => + result = if this.isJsonData(reply) then JSON.parse(reply) else reply + callback(result)) ### # Update the optional member data for a given member in the leaderboard. @@ -244,7 +247,8 @@ class Leaderboard # @param callback Optional callback for result of call. ### updateMemberDataFor: (leaderboardName, member, memberData, callback) -> - @redisConnection.hset(this.memberDataKey(leaderboardName), member, memberData, (err, reply) -> + data = if typeof memberData is 'object' then JSON.stringify(memberData) else memberData + @redisConnection.hset(this.memberDataKey(leaderboardName), member, data, (err, reply) -> callback(reply) if callback) ### @@ -1078,4 +1082,20 @@ class Leaderboard memberDataKey: (leaderboardName) -> "#{leaderboardName}:#{@memberDataNamespace}" + ### + # Checks a string if encoded json + # + # @param value [String] String to be checked. + # + # @return boolean of string is json + ### + isJsonData: (value) -> + try + JSON.parse(value); + catch e + return false + return true + + + module.exports = Leaderboard