leaderboard 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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