redpear 0.6.4 → 0.7.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.
- data/lib/redpear/connection.rb +110 -17
- data/lib/redpear/model/expiration.rb +18 -0
- data/lib/redpear/model/factory_girl.rb +27 -0
- data/lib/redpear/model/finders.rb +37 -0
- data/lib/redpear/model/machinist.rb +54 -0
- data/lib/redpear/model.rb +186 -63
- data/lib/redpear/schema/collection.rb +7 -7
- data/lib/redpear/{column.rb → schema/column.rb} +12 -6
- data/lib/redpear/schema/index.rb +22 -0
- data/lib/redpear/schema/score.rb +13 -0
- data/lib/redpear/schema.rb +9 -6
- data/lib/redpear/store/base.rb +120 -0
- data/lib/redpear/store/counter.rb +44 -0
- data/lib/redpear/store/enumerable.rb +8 -0
- data/lib/redpear/store/hash.rb +120 -0
- data/lib/redpear/store/list.rb +144 -0
- data/lib/redpear/store/lock.rb +108 -0
- data/lib/redpear/store/set.rb +147 -0
- data/lib/redpear/store/sorted_set.rb +239 -0
- data/lib/redpear/store/value.rb +66 -0
- data/lib/redpear/store.rb +11 -0
- data/lib/redpear.rb +7 -22
- metadata +45 -30
- data/lib/redpear/core_ext/stringify_keys.rb +0 -17
- data/lib/redpear/counters.rb +0 -26
- data/lib/redpear/expiration.rb +0 -27
- data/lib/redpear/finders.rb +0 -59
- data/lib/redpear/index.rb +0 -31
- data/lib/redpear/machinist.rb +0 -51
- data/lib/redpear/members.rb +0 -83
- data/lib/redpear/namespace.rb +0 -79
- data/lib/redpear/nest.rb +0 -100
- data/lib/redpear/persistence.rb +0 -147
- data/lib/redpear/zindex.rb +0 -26
- data/lib/redpear/zmembers.rb +0 -68
data/lib/redpear/expiration.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Redpear::Expiration
|
2
|
-
|
3
|
-
# Expires the record.
|
4
|
-
# @param [Time, Integer] either a Time or an Integer period (in seconds)
|
5
|
-
def expire(value)
|
6
|
-
return false unless persisted?
|
7
|
-
|
8
|
-
case value
|
9
|
-
when Time
|
10
|
-
nest.expireat(value.to_i)
|
11
|
-
when Integer
|
12
|
-
nest.expire(value)
|
13
|
-
when String
|
14
|
-
value = Kernel::Integer(value) rescue nil
|
15
|
-
expire(value)
|
16
|
-
else
|
17
|
-
false
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# @return [Integer] the period this record has to live.
|
22
|
-
# May return -1 for non-expiring records and nil for non-persisted records.
|
23
|
-
def ttl
|
24
|
-
nest.ttl if persisted?
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
data/lib/redpear/finders.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
module Redpear::Finders
|
2
|
-
extend Redpear::Concern
|
3
|
-
|
4
|
-
module ClassMethods
|
5
|
-
|
6
|
-
# @return [Array] the IDs of all existing records
|
7
|
-
def members
|
8
|
-
Redpear::Members.new(mb_nest)
|
9
|
-
end
|
10
|
-
|
11
|
-
# @return [Integer] the number of total records
|
12
|
-
def count
|
13
|
-
members.count
|
14
|
-
end
|
15
|
-
|
16
|
-
# @return [Array] all records
|
17
|
-
def all
|
18
|
-
members.map {|id| find(id) }.compact
|
19
|
-
end
|
20
|
-
|
21
|
-
# @yield [Model] applies a block to each object
|
22
|
-
def find_each(&block)
|
23
|
-
members.each do |id|
|
24
|
-
record = find(id)
|
25
|
-
yield(record) if record
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Finds a single record.
|
30
|
-
#
|
31
|
-
# @param id the ID of the record to retrieve
|
32
|
-
# @param [Hash] options additional options
|
33
|
-
# @option :lazy defaults to true, set to false to load the record instantly
|
34
|
-
# @return [Redpear::Model] a record, or nil when not found
|
35
|
-
def find(id, options = {})
|
36
|
-
record = instantiate('id' => id.to_s) # Initialize
|
37
|
-
if record.nest.exists # Do we have a record key?
|
38
|
-
record.refresh_attributes if options[:lazy] == false
|
39
|
-
record
|
40
|
-
else # Must be an expired or orphaned one
|
41
|
-
record.destroy # Destroy (removes from mb_nest set)
|
42
|
-
nil
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# @param id the ID to check
|
47
|
-
# @return [Boolean] true or false
|
48
|
-
def exists?(id)
|
49
|
-
members.include?(id)
|
50
|
-
end
|
51
|
-
|
52
|
-
def instantiate(*a)
|
53
|
-
new(*a).tap do |instance|
|
54
|
-
instance.send :instance_variable_set, :@__loaded__, false
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
data/lib/redpear/index.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
class Redpear::Index < Redpear::Column
|
2
|
-
|
3
|
-
# @return [Redpear::Nest] the namespace of the index. Example:
|
4
|
-
#
|
5
|
-
# index = Comment.columns.lookup["post_id"]
|
6
|
-
# index.namespace # => "comments:[post_id]"
|
7
|
-
#
|
8
|
-
def namespace
|
9
|
-
model.namespace["[#{to_s}]"]
|
10
|
-
end
|
11
|
-
|
12
|
-
# @param [String] value the index value
|
13
|
-
# @return [Redpear::Nest] the nest for a specific value. Example:
|
14
|
-
#
|
15
|
-
# index = Comment.columns.lookup["post_id"]
|
16
|
-
# index.nest(123) # => "comments:[post_id]:123"
|
17
|
-
# index.nest(nil) # => "comments:[post_id]:_"
|
18
|
-
# index.nest("") # => "comments:[post_id]:_"
|
19
|
-
#
|
20
|
-
def nest(value)
|
21
|
-
value = "_" if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
22
|
-
namespace[value]
|
23
|
-
end
|
24
|
-
|
25
|
-
# @param [String] value the index value
|
26
|
-
# @return [Array] the IDs of all existing records for a given index value
|
27
|
-
def members(value)
|
28
|
-
Redpear::Members.new nest(value)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
data/lib/redpear/machinist.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'redpear'
|
2
|
-
require 'machinist'
|
3
|
-
|
4
|
-
# Machinist module for your tests/specs. Example:
|
5
|
-
#
|
6
|
-
# # spec/support/blueprints.rb
|
7
|
-
# require "redpear/machinist"
|
8
|
-
#
|
9
|
-
# Post.blueprint do
|
10
|
-
# title { "A Title" }
|
11
|
-
# created_at { 2.days.ago }
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
module Redpear::Machinist
|
15
|
-
|
16
|
-
class Blueprint < Machinist::Blueprint
|
17
|
-
|
18
|
-
def make!(attributes = {})
|
19
|
-
make(attributes).tap &:save
|
20
|
-
end
|
21
|
-
|
22
|
-
def lathe_class #:nodoc:
|
23
|
-
Lathe
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
class Lathe < Machinist::Lathe
|
29
|
-
protected
|
30
|
-
|
31
|
-
def make_one_value(attribute, args)
|
32
|
-
return unless block_given?
|
33
|
-
raise_argument_error(attribute) unless args.empty?
|
34
|
-
yield
|
35
|
-
end
|
36
|
-
|
37
|
-
def assign_attribute(key, value) #:nodoc:
|
38
|
-
@assigned_attributes[key.to_sym] = value
|
39
|
-
@object.load key => value
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Redpear::Model #:nodoc:
|
46
|
-
extend Machinist::Machinable
|
47
|
-
|
48
|
-
def self.blueprint_class
|
49
|
-
Redpear::Machinist::Blueprint
|
50
|
-
end
|
51
|
-
end
|
data/lib/redpear/members.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
class Redpear::Members
|
2
|
-
include Enumerable
|
3
|
-
|
4
|
-
attr_reader :nest
|
5
|
-
|
6
|
-
# Constructor
|
7
|
-
# @param [Redpear::Nest] nest
|
8
|
-
# the nest object
|
9
|
-
def initialize(nest)
|
10
|
-
@nest = nest
|
11
|
-
end
|
12
|
-
|
13
|
-
# @return [Boolean] true if member have been loaded
|
14
|
-
def loaded?
|
15
|
-
!@members.nil?
|
16
|
-
end
|
17
|
-
|
18
|
-
# @yield [String] do something with each member
|
19
|
-
def each(&block)
|
20
|
-
members.each(&block)
|
21
|
-
end
|
22
|
-
|
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)
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Set] the actual members
|
31
|
-
def members
|
32
|
-
@members ||= nest.smembers.to_set
|
33
|
-
end
|
34
|
-
|
35
|
-
# @return [Integer] then count of members
|
36
|
-
def count
|
37
|
-
@count ||= loaded? ? @members.size : cardinality
|
38
|
-
end
|
39
|
-
alias_method :size, :count
|
40
|
-
|
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
|
55
|
-
end
|
56
|
-
|
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)
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
data/lib/redpear/namespace.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
# Namespace organization for models. Example:
|
2
|
-
#
|
3
|
-
# class Comment < Model
|
4
|
-
# index :post_id
|
5
|
-
# end
|
6
|
-
# instance = Comment.save(:post_id => 2)
|
7
|
-
#
|
8
|
-
# Comment.namespace.keys
|
9
|
-
# # => ['comments:1', 'comments:+', 'comments:*', 'comments:post_id:2']
|
10
|
-
#
|
11
|
-
# # Instance nesting
|
12
|
-
# instance.nest # => 'comments:1'
|
13
|
-
# instance.nest.hgetall # => { "post_id" => "2" }
|
14
|
-
#
|
15
|
-
# # Member nesting
|
16
|
-
# Comment.mb_nest # "comments:[~]"
|
17
|
-
# Comment.mb_nest.smembers # => #<Set: {1}>
|
18
|
-
#
|
19
|
-
# # PK nesting
|
20
|
-
# Comment.pk_nest # "comments:[+]"
|
21
|
-
# Comment.pk_nest.get # 1 = last ID
|
22
|
-
#
|
23
|
-
# # Index nesting
|
24
|
-
# Comment.columns["post_id"].nest(2) # "comments:post_id:2"
|
25
|
-
# Comment.columns["post_id"].nest(2).smembers # #<Set: {1}>
|
26
|
-
#
|
27
|
-
module Redpear::Namespace
|
28
|
-
extend Redpear::Concern
|
29
|
-
|
30
|
-
module ClassMethods
|
31
|
-
|
32
|
-
# @return [Redpear::Nest] the namespace of this model, Example:
|
33
|
-
#
|
34
|
-
# Comment.namespace # => "comments":Redpear::Nest
|
35
|
-
#
|
36
|
-
def namespace
|
37
|
-
@namespace ||= Redpear::Nest.new(scope, master_connection, slave_connection)
|
38
|
-
end
|
39
|
-
|
40
|
-
# @return [String] the scope of this model. Example:
|
41
|
-
#
|
42
|
-
# Comment.scope # => "comments"
|
43
|
-
#
|
44
|
-
# Override if you want to use a differnet scope schema.
|
45
|
-
def scope
|
46
|
-
@scope ||= "#{name.split('::').last.downcase}s"
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [Redpear::Nest] the nest for the members store. Example:
|
50
|
-
#
|
51
|
-
# Comment.mb_nest # => 'comments:*'
|
52
|
-
# Comment.mb_nest.smembers # => [1, 2, 3]
|
53
|
-
#
|
54
|
-
def mb_nest
|
55
|
-
@mb_nest ||= namespace["[~]"]
|
56
|
-
end
|
57
|
-
|
58
|
-
# @return [Redpear::Nest] the nest for the primary-key incrementor. Example:
|
59
|
-
#
|
60
|
-
# Comment.pk_nest # => 'comments:+'
|
61
|
-
# Comment.pk_nest.get # => 0
|
62
|
-
# Comment.pk_nest.incr # => 1
|
63
|
-
#
|
64
|
-
def pk_nest
|
65
|
-
@pk_nest ||= namespace["[+]"]
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
# @return [Redpear::Nest] the nest for the current record. Example:
|
71
|
-
#
|
72
|
-
# comment.nest # => 'comments:123'
|
73
|
-
# Comment.new.nest # => 'comments:_'
|
74
|
-
#
|
75
|
-
def nest
|
76
|
-
self.class.namespace[id || '_']
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
data/lib/redpear/nest.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# Nested redis key-value store, with master slave support
|
2
|
-
# Heavily "inspired" by the nest library
|
3
|
-
# Original copyright: Michel Martens & Damian Janowski
|
4
|
-
class Redpear::Nest < ::String
|
5
|
-
|
6
|
-
MASTER_METHODS = %w|
|
7
|
-
append auth
|
8
|
-
bgrewriteaof bgsave blpop brpop brpoplpush
|
9
|
-
config
|
10
|
-
decr decrby del discard
|
11
|
-
exec expire expireat
|
12
|
-
flushall flushdb getset
|
13
|
-
hset hsetnx hincrby hmset hdel
|
14
|
-
incr incrby
|
15
|
-
linsert lpop lpush lpushx lrem lset ltrim
|
16
|
-
mapped_hmset mapped_mset mapped_msetnx
|
17
|
-
move mset msetnx multi
|
18
|
-
persist pipelined psubscribe punsubscribe quit
|
19
|
-
rename renamenx rpop rpoplpush rpush rpushx
|
20
|
-
sadd save sdiffstore set setbit
|
21
|
-
setex setnx setrange sinterstore
|
22
|
-
shutdown smove spop srem subscribe
|
23
|
-
sunionstore sync synchronize
|
24
|
-
unsubscribe unwatch watch
|
25
|
-
zadd zincrby zinterstore zrem
|
26
|
-
zremrangebyrank zremrangebyscore zunionstore
|
27
|
-
|.freeze
|
28
|
-
|
29
|
-
SLAVE_METHODS = %w|
|
30
|
-
dbsize debug get getbit getrange
|
31
|
-
echo exists
|
32
|
-
hget hmget hexists hlen hkeys hvals hgetall
|
33
|
-
info keys lastsave lindex llen lrange
|
34
|
-
mapped_hmget mapped_mget mget monitor
|
35
|
-
object ping publish randomkey
|
36
|
-
scard sdiff select sinter sismember slaveof
|
37
|
-
smembers sort srandmember strlen substr sunion
|
38
|
-
ttl type
|
39
|
-
zcard zcount zrange zrangebyscore zrank
|
40
|
-
zrevrange zrevrangebyscore zrevrank zscore
|
41
|
-
|.freeze
|
42
|
-
|
43
|
-
attr_reader :master, :slave, :current
|
44
|
-
|
45
|
-
# Constructor
|
46
|
-
# @param [String] key
|
47
|
-
# The redis key
|
48
|
-
# @param [Redis::Client|Redis::Namespace|ConnectionPool] master
|
49
|
-
# The master connection, optional, defaults to the current connection
|
50
|
-
# @param [Redis::Client|Redis::Namespace|ConnectionPool] slave
|
51
|
-
# The slave connection, optional, defaults to master
|
52
|
-
def initialize(key, master = Redis.current, slave = nil)
|
53
|
-
super(key)
|
54
|
-
@master = master
|
55
|
-
@slave = slave || master
|
56
|
-
end
|
57
|
-
|
58
|
-
# @param [multiple] keys
|
59
|
-
# Nest within these keys
|
60
|
-
# @return [Redpear::Nest]
|
61
|
-
# The nested key
|
62
|
-
def [](*keys)
|
63
|
-
self.class.new [self, *keys].join(':'), master, slave
|
64
|
-
end
|
65
|
-
|
66
|
-
# @param [Symbol] name
|
67
|
-
# Either :master or :slave
|
68
|
-
# @yield
|
69
|
-
# Perform a block with the given connection
|
70
|
-
def with_connection(name)
|
71
|
-
@current = send(name)
|
72
|
-
yield
|
73
|
-
ensure
|
74
|
-
@current = nil
|
75
|
-
end
|
76
|
-
alias_method :with, :with_connection
|
77
|
-
|
78
|
-
MASTER_METHODS.each do |meth|
|
79
|
-
define_method(meth) do |*args, &block|
|
80
|
-
client = current || master
|
81
|
-
if Redis.instance_method(meth).arity.zero?
|
82
|
-
client.send(meth, &block)
|
83
|
-
else
|
84
|
-
client.send(meth, self, *args, &block)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
SLAVE_METHODS.each do |meth|
|
90
|
-
define_method(meth) do |*args, &block|
|
91
|
-
client = current || slave
|
92
|
-
if Redis.instance_method(meth).arity.zero?
|
93
|
-
client.send(meth, &block)
|
94
|
-
else
|
95
|
-
client.send(meth, self, *args, &block)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
data/lib/redpear/persistence.rb
DELETED
@@ -1,147 +0,0 @@
|
|
1
|
-
# Redpear's persistence methods
|
2
|
-
module Redpear::Persistence
|
3
|
-
extend Redpear::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
|
7
|
-
# Runs a bulk-operation.
|
8
|
-
# @yield [] operations that should be run in the transaction
|
9
|
-
def transaction(&block)
|
10
|
-
namespace.multi(&block)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Create or update a record. Example:
|
14
|
-
#
|
15
|
-
# Post.save :body => "Hello World!" # => creates a new Post
|
16
|
-
# Post.save :id => 3, :body => "Hello World!" # => updates an existing Post
|
17
|
-
#
|
18
|
-
def save(*args)
|
19
|
-
new(*args).tap(&:save)
|
20
|
-
end
|
21
|
-
alias_method :save!, :save
|
22
|
-
|
23
|
-
# Destroys a record. Example:
|
24
|
-
# @param id the ID of the record to destroy
|
25
|
-
# @return [Redpear::Model] the destroyed record
|
26
|
-
def destroy(id)
|
27
|
-
new('id' => id).tap(&:destroy)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Generates the next ID
|
31
|
-
def next_id
|
32
|
-
pk_nest.incr.to_s
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns true for new records
|
38
|
-
def new_record?
|
39
|
-
!id
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns true for existing records
|
43
|
-
def persisted?
|
44
|
-
!new_record?
|
45
|
-
end
|
46
|
-
|
47
|
-
# Reloads the record (destructive)
|
48
|
-
def reload
|
49
|
-
replace self.class.find(id, :lazy => false) if persisted?
|
50
|
-
self
|
51
|
-
end
|
52
|
-
|
53
|
-
# Load attributes from DB (destructive)
|
54
|
-
def refresh_attributes
|
55
|
-
update nest.hgetall if persisted?
|
56
|
-
@__loaded__ = true
|
57
|
-
self
|
58
|
-
end
|
59
|
-
|
60
|
-
# Saves the record.
|
61
|
-
#
|
62
|
-
# @param [Hash] options additional options
|
63
|
-
# @option options [Integer|Date] :expire expiration period or timestamp
|
64
|
-
# @yield [record] Additional block, applied as part of the save transaction
|
65
|
-
# @return [Redpear::Model] the saved record
|
66
|
-
def save(options = {}, &block)
|
67
|
-
before_save
|
68
|
-
update "id" => self.class.next_id unless persisted?
|
69
|
-
|
70
|
-
transaction do
|
71
|
-
nest.mapped_hmset __persistable_attributes__
|
72
|
-
__relevant_member_sets__.each {|s| s.add(self) }
|
73
|
-
expire options[:expire]
|
74
|
-
yield(self) if block
|
75
|
-
end
|
76
|
-
ensure
|
77
|
-
after_save
|
78
|
-
end
|
79
|
-
alias_method :save!, :save
|
80
|
-
|
81
|
-
# Destroy the record.
|
82
|
-
# @return [Boolean] true or false
|
83
|
-
def destroy
|
84
|
-
return false unless persisted?
|
85
|
-
before_destroy
|
86
|
-
|
87
|
-
transaction do
|
88
|
-
nest.del
|
89
|
-
__relevant_member_sets__.each {|s| s.remove(self) }
|
90
|
-
end
|
91
|
-
|
92
|
-
true
|
93
|
-
ensure
|
94
|
-
after_destroy
|
95
|
-
end
|
96
|
-
|
97
|
-
protected
|
98
|
-
|
99
|
-
# Run in a DB transaction, returns self
|
100
|
-
def transaction(&block)
|
101
|
-
self.class.transaction(&block)
|
102
|
-
self
|
103
|
-
end
|
104
|
-
|
105
|
-
# "Cheap" callback, override in subclasses
|
106
|
-
def before_save
|
107
|
-
end
|
108
|
-
|
109
|
-
# "Cheap" callback, override in subclasses
|
110
|
-
def after_save
|
111
|
-
end
|
112
|
-
|
113
|
-
# "Cheap" callback, override in subclasses
|
114
|
-
def before_destroy
|
115
|
-
end
|
116
|
-
|
117
|
-
# "Cheap" callback, override in subclasses
|
118
|
-
def after_destroy
|
119
|
-
end
|
120
|
-
|
121
|
-
protected
|
122
|
-
|
123
|
-
# Attributes that can be persisted
|
124
|
-
def __persistable_attributes__
|
125
|
-
result = {}
|
126
|
-
each do |key, value|
|
127
|
-
next unless self.class.columns.include?(key)
|
128
|
-
result[key] = __persistable_value__(value)
|
129
|
-
end
|
130
|
-
result
|
131
|
-
end
|
132
|
-
|
133
|
-
def __persistable_value__(value)
|
134
|
-
case value
|
135
|
-
when Time
|
136
|
-
value.to_i
|
137
|
-
else
|
138
|
-
value
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Return relevant set nests
|
143
|
-
def __relevant_member_sets__
|
144
|
-
@__relevant_member_sets__ ||= [self.class.members] + self.class.columns.indices.map {|i| i.members(self[i]) if self[i] }.compact
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
data/lib/redpear/zindex.rb
DELETED
@@ -1,26 +0,0 @@
|
|
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, :float, :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
|
data/lib/redpear/zmembers.rb
DELETED
@@ -1,68 +0,0 @@
|
|
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
|