redpear 0.4.3 → 0.5.0

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.
@@ -2,9 +2,12 @@ class Redpear::Column < String
2
2
  attr_reader :type, :model
3
3
 
4
4
  # Creates a new column.
5
- # @param [Redpear::Model] model the model the column is associated with
6
- # @param [String] name the column name
7
- # @param [Symbol] type the column type (:string (default), :counter, :integer, :timestamp)
5
+ # @param [Redpear::Model] model
6
+ # the model the column is associated with
7
+ # @param [String] name
8
+ # the column name
9
+ # @param [Symbol] type
10
+ # the column type (:string (default), :counter, :integer, :timestamp)
8
11
  def initialize(model, name, type = nil)
9
12
  super name.to_s
10
13
  @model = model
@@ -46,7 +46,7 @@ module Redpear::Finders
46
46
  # @param id the ID to check
47
47
  # @return [Boolean] true or false
48
48
  def exists?(id)
49
- members.exists?(id)
49
+ members.include?(id)
50
50
  end
51
51
 
52
52
  def instantiate(*a)
data/lib/redpear/index.rb CHANGED
@@ -14,11 +14,11 @@ class Redpear::Index < Redpear::Column
14
14
  #
15
15
  # index = Comment.columns.lookup["post_id"]
16
16
  # index.nest(123) # => "comments:[post_id]:123"
17
- # index.nest(nil) # => nil
18
- # index.nest("") # => nil
17
+ # index.nest(nil) # => "comments:[post_id]:_"
18
+ # index.nest("") # => "comments:[post_id]:_"
19
19
  #
20
20
  def nest(value)
21
- return nil if value.nil? || (value.respond_to?(:empty?) && value.empty?)
21
+ value = "_" if value.nil? || (value.respond_to?(:empty?) && value.empty?)
22
22
  namespace[value]
23
23
  end
24
24
 
@@ -1,37 +1,83 @@
1
1
  class Redpear::Members
2
2
  include Enumerable
3
3
 
4
+ attr_reader :nest
5
+
6
+ # Constructor
7
+ # @param [Redpear::Nest] nest
8
+ # the nest object
4
9
  def initialize(nest)
5
- @nest = nest
6
- @members = Set.new unless @nest
10
+ @nest = nest
7
11
  end
8
12
 
13
+ # @return [Boolean] true if member have been loaded
9
14
  def loaded?
10
15
  !@members.nil?
11
16
  end
12
17
 
18
+ # @yield [String] do something with each member
13
19
  def each(&block)
14
20
  members.each(&block)
15
21
  end
16
22
 
17
- def exists?(value)
18
- loaded? ? @members.include?(value.to_s) : @nest.sismember(value)
23
+ # @param [String] value
24
+ # check if this value is a member
25
+ # @return [Boolean] true if members contain the value
26
+ def include?(value)
27
+ loaded? ? @members.include?(value.to_s) : is_member?(value)
19
28
  end
20
29
 
30
+ # @return [Set] the actual members
21
31
  def members
22
- @members ||= @nest.smembers.to_set
32
+ @members ||= nest.smembers.to_set
23
33
  end
24
34
 
35
+ # @return [Integer] then count of members
25
36
  def count
26
- members.count
37
+ @count ||= loaded? ? @members.size : cardinality
27
38
  end
39
+ alias_method :size, :count
28
40
 
29
- def size
30
- members.size
41
+ # Compares members
42
+ # @param [Object] other the object to compare with
43
+ # @return [Boolean] true if same as other
44
+ def ==(other)
45
+ case other
46
+ when Redpear::Members
47
+ other.members == members
48
+ when Set
49
+ other == members
50
+ when Array
51
+ other.to_set == members
52
+ else
53
+ super
54
+ end
31
55
  end
32
56
 
33
- def ==(other)
34
- other.is_a?(Array) ? to_a == other : super
57
+ # Is the value a member? This method is not cached, try using #include? instead.
58
+ # @param [String] value
59
+ def is_member?(value)
60
+ nest.sismember(value)
61
+ end
62
+
63
+ # @return [Integer] the cardinaliry of this set.
64
+ # This method is not cached, try using #count instead.
65
+ def cardinality
66
+ nest.scard
67
+ end
68
+
69
+ # Add a member to this set
70
+ # @param [Model] record
71
+ def add(record)
72
+ @members << record.id if loaded?
73
+ nest.sadd(record.id)
74
+ end
75
+
76
+ # Remove a member from this set
77
+ # @param [Model] record
78
+ def remove(record)
79
+ @members.delete(record.id) if loaded?
80
+ nest.srem(record.id)
35
81
  end
36
82
 
37
83
  end
@@ -52,7 +52,7 @@ module Redpear::Persistence
52
52
 
53
53
  # Load attributes from DB (destructive)
54
54
  def refresh_attributes
55
- update nest.mapped_hmget(*self.class.columns.names) if persisted?
55
+ update nest.mapped_hmget(*__loadable_attributes__) if persisted?
56
56
  @__loaded__ = true
57
57
  self
58
58
  end
@@ -69,7 +69,7 @@ module Redpear::Persistence
69
69
 
70
70
  transaction do
71
71
  nest.mapped_hmset __persistable_attributes__
72
- __relevant_sets__.each {|s| s.sadd(id) }
72
+ __relevant_member_sets__.each {|s| s.add(self) }
73
73
  expire options[:expire]
74
74
  yield(self) if block
75
75
  end
@@ -86,7 +86,7 @@ module Redpear::Persistence
86
86
 
87
87
  transaction do
88
88
  nest.del
89
- __relevant_sets__.each {|s| s.srem(id) }
89
+ __relevant_member_sets__.each {|s| s.remove(self) }
90
90
  end
91
91
 
92
92
  true
@@ -118,7 +118,7 @@ module Redpear::Persistence
118
118
  def after_destroy
119
119
  end
120
120
 
121
- private
121
+ protected
122
122
 
123
123
  # Attributes that can be persisted
124
124
  def __persistable_attributes__
@@ -130,6 +130,11 @@ module Redpear::Persistence
130
130
  result
131
131
  end
132
132
 
133
+ # Attributes that can be loaded
134
+ def __loadable_attributes__
135
+ self.class.columns.names
136
+ end
137
+
133
138
  def __persistable_value__(value)
134
139
  case value
135
140
  when Time
@@ -140,8 +145,8 @@ module Redpear::Persistence
140
145
  end
141
146
 
142
147
  # Return relevant set nests
143
- def __relevant_sets__
144
- @__relevant_sets__ ||= [self.class.mb_nest] + self.class.columns.indices.map {|i| i.nest self[i] }.compact
148
+ def __relevant_member_sets__
149
+ @__relevant_member_sets__ ||= [self.class.members] + self.class.columns.indices.map {|i| i.members(self[i]) if self[i] }.compact
145
150
  end
146
151
 
147
152
  end
@@ -2,17 +2,9 @@
2
2
  class Redpear::Schema::Collection < Array
3
3
 
4
4
  # @param [multiple] the column definition. Please see Redpear::Column#initialize
5
- def column(*args)
5
+ def store(klass, *args)
6
6
  reset!
7
- Redpear::Column.new(*args).tap do |col|
8
- self << col
9
- end
10
- end
11
-
12
- # @param [multiple] the index definition. Please see Redpear::Column#initialize
13
- def index(*args)
14
- reset!
15
- Redpear::Index.new(*args).tap do |col|
7
+ klass.new(*args).tap do |col|
16
8
  self << col
17
9
  end
18
10
  end
@@ -11,14 +11,21 @@ module Redpear::Schema
11
11
 
12
12
  # @param [multiple] the column definition. Please see Redpear::Column#initialize
13
13
  def column(*args)
14
- columns.column(self, *args).tap do |col|
14
+ columns.store(Redpear::Column, self, *args).tap do |col|
15
15
  __define_attribute_accessors__(col)
16
16
  end
17
17
  end
18
18
 
19
- # @param [multiple] the index definition. Please see Redpear::Column#initialize
19
+ # @param [multiple] the index definition. Please see Redpear::Index#initialize
20
20
  def index(*args)
21
- columns.index(self, *args).tap do |col|
21
+ columns.store(Redpear::Index, self, *args).tap do |col|
22
+ __define_attribute_accessors__(col)
23
+ end
24
+ end
25
+
26
+ # @param [multiple] the sorted index definition. Please see Redpear::ZIndex#initialize
27
+ def zindex(*args)
28
+ columns.store(Redpear::ZIndex, self, *args).tap do |col|
22
29
  __define_attribute_accessors__(col)
23
30
  end
24
31
  end
@@ -0,0 +1,26 @@
1
+ class Redpear::ZIndex < Redpear::Index
2
+
3
+ attr_reader :callback
4
+
5
+ # Creates a new ZIndex.
6
+ # @param [Redpear::Model] model
7
+ # the model the column is associated with
8
+ # @param [String] name
9
+ # the column name
10
+ # @param [Symbol] callback
11
+ # method to be call on the object, to determine the score
12
+ # @param [Symbol] type
13
+ # the column type (:string (default), :counter, :integer, :timestamp)
14
+ def initialize(model, name, callback, type = nil)
15
+ super(model, name, type)
16
+ @callback = callback
17
+ end
18
+
19
+ # @param [String] value
20
+ # the index value
21
+ # @return [Redpear::SortedMembers] the IDs of all existing records for a given index value
22
+ def members(value)
23
+ Redpear::ZMembers.new nest(value), callback
24
+ end
25
+
26
+ end
@@ -0,0 +1,68 @@
1
+ class Redpear::ZMembers < Redpear::Members
2
+
3
+ # Constructor
4
+ # @param [Redpear::Nest] nest
5
+ # the nest object
6
+ # @param [Symbol] callback
7
+ # the method to use for scoring when members are added
8
+ def initialize(nest, callback)
9
+ super(nest)
10
+ @callback = callback.to_sym
11
+ end
12
+
13
+ # @return [Hash] the actual members
14
+ def members
15
+ @members ||= range.to_set
16
+ end
17
+
18
+ # @param [Hash] options
19
+ # @option [Integer] start, start index, defaults to 0
20
+ # @option [Integer] stop, stop index, defaults to -1
21
+ # @returns [Hash] range of members, lowest rank first
22
+ def range(options = {})
23
+ options = options.merge(:start => 0, :stop => -1)
24
+ nest.zrange options.delete(:start), options.delete(:stop), options
25
+ end
26
+
27
+ # @param [Hash] options
28
+ # @option [Integer] start, start index, defaults to 0
29
+ # @option [Integer] stop, stop index, defaults to -1
30
+ # @returns [Hash] range or members, highest rank first
31
+ def reverse_range(options = {})
32
+ options = options.merge(:start => 0, :stop => -1)
33
+ nest.zrevrange options.delete(:start), options.delete(:stop), options
34
+ end
35
+
36
+ # Is the value a member? This method is not cached, try using #include? instead.
37
+ # @param [String] value
38
+ def is_member?(value)
39
+ !!nest.zscore(value)
40
+ end
41
+
42
+ # @return [Integer] the cardinality of this set.
43
+ # This method is not cached, try using #count instead.
44
+ def cardinality
45
+ nest.zcard
46
+ end
47
+
48
+ # @return [Integer] the score for a member
49
+ # This method is not cached.
50
+ def score(value)
51
+ nest.zscore(value)
52
+ end
53
+
54
+ # Add a member to this set
55
+ # @param [Model] record
56
+ def add(record)
57
+ @members << record.id if loaded?
58
+ nest.zadd(record.send(@callback), record.id)
59
+ end
60
+
61
+ # Remove a member from this set
62
+ # @param [Model] record
63
+ def remove(record, score = 0)
64
+ @members.delete(record.id) if loaded?
65
+ nest.zrem(record.id)
66
+ end
67
+
68
+ end
data/lib/redpear.rb CHANGED
@@ -21,5 +21,7 @@ module Redpear
21
21
  autoload :Nest
22
22
  autoload :Persistence
23
23
  autoload :Schema
24
+ autoload :ZIndex
25
+ autoload :ZMembers
24
26
 
25
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redpear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-28 00:00:00.000000000Z
12
+ date: 2011-12-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &16450640 !ruby/object:Gem::Requirement
16
+ requirement: &19999180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *16450640
24
+ version_requirements: *19999180
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nest
27
- requirement: &16450180 !ruby/object:Gem::Requirement
27
+ requirement: &19998660 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.1.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *16450180
35
+ version_requirements: *19998660
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &16449800 !ruby/object:Gem::Requirement
38
+ requirement: &19998180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *16449800
46
+ version_requirements: *19998180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &16449340 !ruby/object:Gem::Requirement
49
+ requirement: &19997620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *16449340
57
+ version_requirements: *19997620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &16448360 !ruby/object:Gem::Requirement
60
+ requirement: &19997060 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *16448360
68
+ version_requirements: *19997060
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: fakeredis
71
- requirement: &16447900 !ruby/object:Gem::Requirement
71
+ requirement: &19996200 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *16447900
79
+ version_requirements: *19996200
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: shoulda-matchers
82
- requirement: &16447400 !ruby/object:Gem::Requirement
82
+ requirement: &19995740 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *16447400
90
+ version_requirements: *19995740
91
91
  description: Simple, elegant & efficient ORM for Redis
92
92
  email: dimitrij@blacksquaremedia.com
93
93
  executables: []
@@ -99,9 +99,11 @@ files:
99
99
  - lib/redpear/schema/collection.rb
100
100
  - lib/redpear/core_ext/stringify_keys.rb
101
101
  - lib/redpear/concern.rb
102
+ - lib/redpear/zmembers.rb
102
103
  - lib/redpear/namespace.rb
103
104
  - lib/redpear/nest.rb
104
105
  - lib/redpear/finders.rb
106
+ - lib/redpear/zindex.rb
105
107
  - lib/redpear/persistence.rb
106
108
  - lib/redpear/expiration.rb
107
109
  - lib/redpear/column.rb