leaderboard 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.markdown CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## leaderboard 3.0.2 (2013-02-22)
4
+
5
+ * Fixed a data leak in `expire_leaderboard` and `expire_leaderboard_at` to also set expiration on the member data hash.
6
+
3
7
  ## leaderboard 3.0.1 (2012-12-19)
4
8
 
5
9
  * Fixed a bug in `remove_member` that would remove all of the optional member data.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2012 David Czarnecki
1
+ Copyright (c) 2011-2013 David Czarnecki
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -146,6 +146,12 @@ highscore_lb.remove_member_data('84849292')
146
146
  ```
147
147
 
148
148
  If you delete the leaderboard, ALL of the member data is deleted as well.
149
+
150
+ #### Optional member data notes
151
+
152
+ If you use optional member data, the use of the `remove_members_in_score_range` will leave data around in the member data
153
+ hash. This is because the internal Redis method, `zremrangebyscore`, only returns the number of items removed. It does
154
+ not return the members that it removed.
149
155
 
150
156
  Get some information about a specific member(s) in the leaderboard:
151
157
 
@@ -404,10 +410,10 @@ end
404
410
 
405
411
  The following ports have been made of the leaderboard gem.
406
412
 
413
+ * CoffeeScript: https://github.com/agoragames/leaderboard-coffeescript
407
414
  * Java: https://github.com/agoragames/java-leaderboard
408
- * NodeJS: https://github.com/omork/node-leaderboard
409
415
  * PHP: https://github.com/agoragames/php-leaderboard
410
- * Python: https://github.com/agoragames/python-leaderboard
416
+ * Python: https://github.com/agoragames/leaderboard-python
411
417
  * Scala: https://github.com/agoragames/scala-leaderboard
412
418
 
413
419
  ## Contributing to leaderboard
@@ -422,5 +428,5 @@ The following ports have been made of the leaderboard gem.
422
428
 
423
429
  ## Copyright
424
430
 
425
- Copyright (c) 2011-2012 David Czarnecki. See LICENSE.txt for further details.
431
+ Copyright (c) 2011-2013 David Czarnecki. See LICENSE.txt for further details.
426
432
 
data/lib/leaderboard.rb CHANGED
@@ -109,7 +109,7 @@ class Leaderboard
109
109
  #
110
110
  # @param member [String] Member name.
111
111
  # @param score [float] Member score.
112
- # @param member_data [Hash] Optional member data.
112
+ # @param member_data [String] Optional member data.
113
113
  def rank_member(member, score, member_data = nil)
114
114
  rank_member_in(@leaderboard_name, member, score, member_data)
115
115
  end
@@ -119,7 +119,7 @@ class Leaderboard
119
119
  # @param leaderboard_name [String] Name of the leaderboard.
120
120
  # @param member [String] Member name.
121
121
  # @param score [float] Member score.
122
- # @param member_data [Hash] Optional member data.
122
+ # @param member_data [String] Optional member data.
123
123
  def rank_member_in(leaderboard_name, member, score, member_data = nil)
124
124
  @redis_connection.multi do |transaction|
125
125
  transaction.zadd(leaderboard_name, score, member)
@@ -127,7 +127,7 @@ class Leaderboard
127
127
  end
128
128
  end
129
129
 
130
- # Rank a member in the leaderboard based on execution of the +rank_conditional+.
130
+ # Rank a member in the leaderboard based on execution of the +rank_conditional+.
131
131
  #
132
132
  # The +rank_conditional+ is passed the following parameters:
133
133
  # member: Member name.
@@ -138,13 +138,13 @@ class Leaderboard
138
138
  #
139
139
  # @param rank_conditional [lambda] Lambda which must return +true+ or +false+ that controls whether or not the member is ranked in the leaderboard.
140
140
  # @param member [String] Member name.
141
- # @param score [String] Member score.
142
- # @param member_data [Hash] Optional member_data.
141
+ # @param score [float] Member score.
142
+ # @param member_data [String] Optional member_data.
143
143
  def rank_member_if(rank_conditional, member, score, member_data = nil)
144
144
  rank_member_if_in(@leaderboard_name, rank_conditional, member, score, member_data)
145
145
  end
146
146
 
147
- # Rank a member in the named leaderboard based on execution of the +rank_conditional+.
147
+ # Rank a member in the named leaderboard based on execution of the +rank_conditional+.
148
148
  #
149
149
  # The +rank_conditional+ is passed the following parameters:
150
150
  # member: Member name.
@@ -156,10 +156,10 @@ class Leaderboard
156
156
  # @param leaderboard_name [String] Name of the leaderboard.
157
157
  # @param rank_conditional [lambda] Lambda which must return +true+ or +false+ that controls whether or not the member is ranked in the leaderboard.
158
158
  # @param member [String] Member name.
159
- # @param score [String] Member score.
160
- # @param member_data [Hash] Optional member_data.
159
+ # @param score [float] Member score.
160
+ # @param member_data [String] Optional member_data.
161
161
  def rank_member_if_in(leaderboard_name, rank_conditional, member, score, member_data = nil)
162
- current_score = @redis_connection.zscore(leaderboard_name, member)
162
+ current_score = @redis_connection.zscore(leaderboard_name, member)
163
163
  current_score = current_score.to_f if current_score
164
164
 
165
165
  if rank_conditional.call(member, current_score, score, member_data, {:reverse => @reverse})
@@ -171,7 +171,7 @@ class Leaderboard
171
171
  #
172
172
  # @param member [String] Member name.
173
173
  #
174
- # @return Hash of optional member data.
174
+ # @return String of optional member data.
175
175
  def member_data_for(member)
176
176
  member_data_for_in(@leaderboard_name, member)
177
177
  end
@@ -181,7 +181,7 @@ class Leaderboard
181
181
  # @param leaderboard_name [String] Name of the leaderboard.
182
182
  # @param member [String] Member name.
183
183
  #
184
- # @return Hash of optional member data.
184
+ # @return String of optional member data.
185
185
  def member_data_for_in(leaderboard_name, member)
186
186
  @redis_connection.hget(member_data_key(leaderboard_name), member)
187
187
  end
@@ -189,7 +189,7 @@ class Leaderboard
189
189
  # Update the optional member data for a given member in the leaderboard.
190
190
  #
191
191
  # @param member [String] Member name.
192
- # @param member_data [Hash] Optional member data.
192
+ # @param member_data [String] Optional member data.
193
193
  def update_member_data(member, member_data)
194
194
  update_member_data_in(@leaderboard_name, member, member_data)
195
195
  end
@@ -198,7 +198,7 @@ class Leaderboard
198
198
  #
199
199
  # @param leaderboard_name [String] Name of the leaderboard.
200
200
  # @param member [String] Member name.
201
- # @param member_data [Hash] Optional member data.
201
+ # @param member_data [String] Optional member data.
202
202
  def update_member_data_in(leaderboard_name, member, member_data)
203
203
  @redis_connection.hset(member_data_key(leaderboard_name), member, member_data)
204
204
  end
@@ -336,7 +336,7 @@ class Leaderboard
336
336
  # Retrieve the rank for a member in the leaderboard.
337
337
  #
338
338
  # @param member [String] Member name.
339
- #
339
+ #
340
340
  # @return the rank for a member in the leaderboard.
341
341
  def rank_for(member)
342
342
  rank_for_in(@leaderboard_name, member)
@@ -346,7 +346,7 @@ class Leaderboard
346
346
  #
347
347
  # @param leaderboard_name [String] Name of the leaderboard.
348
348
  # @param member [String] Member name.
349
- #
349
+ #
350
350
  # @return the rank for a member in the leaderboard.
351
351
  def rank_for_in(leaderboard_name, member)
352
352
  if @reverse
@@ -372,7 +372,7 @@ class Leaderboard
372
372
  #
373
373
  # @return the score for a member in the leaderboard or +nil+ if the member is not in the leaderboard.
374
374
  def score_for_in(leaderboard_name, member)
375
- score = @redis_connection.zscore(leaderboard_name, member)
375
+ score = @redis_connection.zscore(leaderboard_name, member)
376
376
  score.to_f if score
377
377
  end
378
378
 
@@ -422,8 +422,8 @@ class Leaderboard
422
422
 
423
423
  responses[0] = responses[0].to_f if responses[0]
424
424
  responses[1] = responses[1] + 1 rescue nil
425
-
426
- {:member => member, :score => responses[0], :rank => responses[1]}
425
+
426
+ {:member => member, :score => responses[0], :rank => responses[1]}
427
427
  end
428
428
 
429
429
  # Remove members from the leaderboard in a given score range.
@@ -521,7 +521,10 @@ class Leaderboard
521
521
  # @param leaderboard_name [String] Name of the leaderboard.
522
522
  # @param seconds [int] Number of seconds after which the leaderboard will be expired.
523
523
  def expire_leaderboard_for(leaderboard_name, seconds)
524
- @redis_connection.expire(leaderboard_name, seconds)
524
+ @redis_connection.multi do |transaction|
525
+ transaction.expire(leaderboard_name, seconds)
526
+ transaction.expire(member_data_key(leaderboard_name), seconds)
527
+ end
525
528
  end
526
529
 
527
530
  # Expire the current leaderboard at a specific UNIX timestamp. Do not use this with
@@ -540,7 +543,10 @@ class Leaderboard
540
543
  # @param leaderboard_name [String] Name of the leaderboard.
541
544
  # @param timestamp [int] UNIX timestamp at which the leaderboard will be expired.
542
545
  def expire_leaderboard_at_for(leaderboard_name, timestamp)
543
- @redis_connection.expireat(leaderboard_name, timestamp)
546
+ @redis_connection.multi do |transaction|
547
+ transaction.expireat(leaderboard_name, timestamp)
548
+ transaction.expireat(member_data_key(leaderboard_name), timestamp)
549
+ end
544
550
  end
545
551
 
546
552
  # Retrieve a page of leaders from the leaderboard.
@@ -873,10 +879,10 @@ class Leaderboard
873
879
  # Key for retrieving optional member data.
874
880
  #
875
881
  # @param leaderboard_name [String] Name of the leaderboard.
876
- #
882
+ #
877
883
  # @return a key in the form of +leaderboard_name:member_data+
878
884
  def member_data_key(leaderboard_name)
879
- "#{leaderboard_name}:member_data"
885
+ "#{leaderboard_name}:member_data"
880
886
  end
881
887
 
882
888
  # Validate and return the page size. Returns the +DEFAULT_PAGE_SIZE+ if the page size is less than 1.
@@ -1,4 +1,3 @@
1
1
  class Leaderboard
2
- # Leaderboard version
3
- VERSION = '3.0.1'.freeze
2
+ VERSION = '3.0.2'.freeze
4
3
  end
@@ -528,6 +528,10 @@ describe 'Leaderboard' do
528
528
  ttl.should be > 1
529
529
  ttl.should be <= 3
530
530
  end
531
+ @redis_connection.ttl(@leaderboard.send(:member_data_key, @leaderboard.leaderboard_name)).tap do |ttl|
532
+ ttl.should be > 1
533
+ ttl.should be <= 3
534
+ end
531
535
  end
532
536
 
533
537
  it 'should set an expire on the leaderboard using a timestamp' do
@@ -538,6 +542,10 @@ describe 'Leaderboard' do
538
542
  ttl.should be > 1
539
543
  ttl.should be <= 10
540
544
  end
545
+ @redis_connection.ttl(@leaderboard.send(:member_data_key, @leaderboard.leaderboard_name)).tap do |ttl|
546
+ ttl.should be > 1
547
+ ttl.should be <= 10
548
+ end
541
549
  end
542
550
 
543
551
  it 'should allow you to rank multiple members with a variable number of arguments' do
data/spec/version_spec.rb CHANGED
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Leaderboard::VERSION' do
4
4
  it 'should be the correct version' do
5
- Leaderboard::VERSION.should == '3.0.1'
5
+ Leaderboard::VERSION.should == '3.0.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leaderboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-19 00:00:00.000000000 Z
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -93,15 +93,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
93
  - - ! '>='
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ segments:
97
+ - 0
98
+ hash: 1304683116950225093
96
99
  required_rubygems_version: !ruby/object:Gem::Requirement
97
100
  none: false
98
101
  requirements:
99
102
  - - ! '>='
100
103
  - !ruby/object:Gem::Version
101
104
  version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 1304683116950225093
102
108
  requirements: []
103
109
  rubyforge_project: leaderboard
104
- rubygems_version: 1.8.24
110
+ rubygems_version: 1.8.25
105
111
  signing_key:
106
112
  specification_version: 3
107
113
  summary: Leaderboards backed by Redis in Ruby