hari 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/LICENSE +17 -15
- data/README.md +131 -11
- data/lib/hari/entity/property.rb +1 -2
- data/lib/hari/entity/serialization.rb +8 -8
- data/lib/hari/entity.rb +5 -0
- data/lib/hari/keys/key.rb +48 -0
- data/lib/hari/keys/list.rb +132 -0
- data/lib/hari/keys/set.rb +101 -0
- data/lib/hari/keys/sorted_set.rb +115 -0
- data/lib/hari/keys/string.rb +81 -0
- data/lib/hari/keys.rb +9 -0
- data/lib/hari/node/queries/relation/backend/sorted_set.rb +14 -4
- data/lib/hari/node/queries/relation.rb +13 -7
- data/lib/hari/node/queries/type.rb +62 -0
- data/lib/hari/node/queries.rb +10 -8
- data/lib/hari/relation/sorted_set.rb +33 -4
- data/lib/hari/relation.rb +0 -3
- data/lib/hari/version.rb +1 -1
- data/lib/hari.rb +10 -3
- data/spec/hari/keys/key_spec.rb +41 -0
- data/spec/hari/{node → keys}/lists_spec.rb +1 -1
- data/spec/hari/{node → keys}/sets_spec.rb +1 -1
- data/spec/hari/{node → keys}/sorted_sets_spec.rb +1 -1
- data/spec/hari/keys/string_spec.rb +57 -0
- data/spec/hari/node_spec.rb +45 -0
- data/spec/hari_spec.rb +13 -0
- metadata +28 -24
- data/lib/hari/node/queries/list.rb +0 -147
- data/lib/hari/node/queries/relation/backend/list.rb +0 -35
- data/lib/hari/node/queries/set.rb +0 -116
- data/lib/hari/node/queries/sorted_set.rb +0 -130
- data/lib/hari/relation/linked_list.rb +0 -16
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MTA3OTM4MTkxN2E3MWM0YjRkNjBkYjNhNzc1OWIxMjZhMzU2NTJlYmZlNjRl
|
10
|
-
NmZmOTZkZjY3Yzk4ZTY3Zjk3NzRiMjJkMjdlMTNjNDgyZGFiZGQ1ZGY2YmQw
|
11
|
-
ZmZiN2JkZmEzYzkwZDI3Y2M4YzQ1NDlmZTExOTM0ODY0N2NlMDQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZDBlNjJiYTg3NWRiMzU5YTkzNDRiNzRlOGE3MDFhYzI3ZDI0YWI4M2UzZDkx
|
14
|
-
NjljYTE1ODUwZjlkODIxZjc5Y2E4N2Q1ZjU0OGYxMTM4MDgxYzRlMTZiZDEw
|
15
|
-
ZWY2ZDIyNmIwYjU5NjRjMDI5ZjQyYWM5MTZhZDQ2YmJiZWQxNDg=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6bec03d308713945bce8a8b110c663beb57450f7
|
4
|
+
data.tar.gz: 4679c39080577b390539c16921264c6d69ce0b50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d1b9c6f45f02be08c99b3f01286031d7c94a64a91d9f14c904acfd9934e0c3c9fa986cdf05a77b8af93d4e37ba25d2d8837d59fc1082cf112c315229a306ab3
|
7
|
+
data.tar.gz: 984b40a10bc769cb874b6879bfd10de44b970225480ed2d73285d6536ef5aed4f148d114721e160c7a79fc6ecd73646fc7e9f42edfe72c47a740579d35c9f139
|
data/LICENSE
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
|
2
|
-
All rights reserved.
|
1
|
+
The MIT License (MIT)
|
3
2
|
|
4
|
-
|
3
|
+
Copyright (c) 2013 ClubJudge B.V.
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,22 +1,142 @@
|
|
1
1
|
[![Build Status](https://travis-ci.org/Clubjudge/hari.png?branch=master)](https://travis-ci.org/Clubjudge/hari)
|
2
2
|
|
3
|
-
|
3
|
+
# Hari
|
4
4
|
|
5
|
-
|
5
|
+
## Mile-high view
|
6
6
|
|
7
|
-
|
7
|
+
**Hari** is a tool to abstract complex relationships between **Ruby** objects onto **Redis** data structures. It allows for expressive querying of those relationships as well, in an easy way. It is mostly geared towards typical social networking concepts like news feeds, activity logs, friends of friends, mutual friends, and so on.
|
8
8
|
|
9
|
-
|
9
|
+
## Basic concepts
|
10
10
|
|
11
|
-
|
11
|
+
Hari embraces normal objects, and allows 2 major modes of operation: abstraction of Redis operations, and actual relationship creation and querying.
|
12
|
+
|
13
|
+
## Abstraction of Redis operations (lists, sets, sorted sets, etc)
|
14
|
+
|
15
|
+
Imagine this `User` model class:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
class User
|
19
|
+
|
20
|
+
attr_reader :id
|
21
|
+
|
22
|
+
def initialize(id)
|
23
|
+
@id = id
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
You can create a **set** to store the user relation with his friends:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
user = User.new(20)
|
33
|
+
|
34
|
+
Hari(user).set(:friends_ids) << 10 # REDIS: SADD hari:user#20:friends_ids 10
|
35
|
+
```
|
36
|
+
|
37
|
+
Then it's possible, for instance, to query the mutual friends between users:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
Hari(user: 20).set(:friends_ids) & Hari(user: 30).set(:friends_ids)
|
41
|
+
|
42
|
+
=> ["10", "25", "40"]
|
43
|
+
```
|
44
|
+
|
45
|
+
By now, you're probably wandering what the `Hari()` method does. It accepts an object like `user` as a parameter, or an identification of this object like `"user#20"`, or even `{user: 30}` and returns a `Hari::Node` representation of the object referenced so you can call all operations available in Hari.
|
46
|
+
|
47
|
+
### [Lists](https://github.com/Clubjudge/hari/wiki/Lists), [Sets](https://github.com/Clubjudge/hari/wiki/Sets) and [Sorted Sets](https://github.com/Clubjudge/hari/wiki/Sorted-Sets) operations are available in the Wiki.
|
48
|
+
|
49
|
+
## Relationships
|
50
|
+
|
51
|
+
Hari uses the power of Redis data structures to create relations between objects, allowing you to traverse nodes and its relations like a graph.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# this gets the last 20 comments from the entities the user#1 follows
|
55
|
+
Hari(user: 1).out(:follow).out(:comments).limit(20)
|
56
|
+
```
|
12
57
|
|
13
58
|
Creating a relation can be as simple as:
|
14
59
|
|
15
|
-
|
60
|
+
```ruby
|
61
|
+
Hari.relation! :follow, user, artist
|
62
|
+
```
|
63
|
+
|
64
|
+
To remove a relation, do:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
Hari.remove_relation! :follow, user, artist
|
68
|
+
```
|
69
|
+
|
70
|
+
Let's mount some queries:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# artist followers
|
74
|
+
Hari(artist).in(:follow)
|
75
|
+
|
76
|
+
# entities that user follow
|
77
|
+
Hari(user).out(:follow)
|
78
|
+
|
79
|
+
# just the last 10 followers of artist
|
80
|
+
Hari(artist).in(:follow).limit(10)
|
81
|
+
|
82
|
+
# paginates from a score (timestamp.to_f),
|
83
|
+
# bringing the next 10 followers up from a last timestamp,
|
84
|
+
# (useful for pooling streams)
|
85
|
+
Hari(artist).in(:follow).limit(10).from(1375977470.382)
|
86
|
+
|
87
|
+
# paginates from a score down,
|
88
|
+
# bringing the previous 10 followers from a last timestamp
|
89
|
+
Hari(artist).in(:follow).limit(10).from(1375977470.382, :down)
|
90
|
+
|
91
|
+
# chaining relations between nodes
|
92
|
+
# last 10 entities to be followed by who user follows
|
93
|
+
Hari(user).out(:follow).out(:follow).limit(10)
|
94
|
+
|
95
|
+
# All users following artist
|
96
|
+
Hari(artist).in(:follow).type(:user)
|
97
|
+
```
|
98
|
+
|
99
|
+
All the calls above return a lazy query expression. The ruby code still didn't fetch the Redis backend, it's mounting a composable query.
|
100
|
+
|
101
|
+
Below there are some of the methods that make the query come to an end:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
# how many followers
|
105
|
+
Hari(artist).in(:follow).count
|
106
|
+
=> 2001
|
107
|
+
|
108
|
+
# returns all followers nodes ids
|
109
|
+
Hari(artist).in(:follow).nodes_ids!
|
110
|
+
=> ['artist#20', 'user#30', 'user#33']
|
111
|
+
|
112
|
+
|
113
|
+
# returns all followers instances of Hari::Node
|
114
|
+
# depends that you have the nodes persisted for each object
|
115
|
+
# this is the default implementation when you do .to_a
|
116
|
+
Hari(artist).in(:follow).nodes!
|
117
|
+
|
118
|
+
tiesto_followers = Hari(artist: 21).in(:follow).type(:user)
|
119
|
+
daftpunk_followers = Hari(artist: 42).in(:follow).type(:user)
|
120
|
+
|
121
|
+
# count of common users following two artists
|
122
|
+
tiesto_followers.intersect_count(daft_punk_followers)
|
123
|
+
=> 6
|
124
|
+
|
125
|
+
# actual users ids following two artists
|
126
|
+
tiesto_followers.intersect(daft_punk_followers)
|
127
|
+
=> [17, 29, 3, 173, 919, 11]
|
128
|
+
|
129
|
+
# paginating through them (start + stop)
|
130
|
+
tiesto_followers.intersect(daft_punk_followers, 2, 5)
|
131
|
+
=> [3, 173, 919]
|
132
|
+
|
133
|
+
user_friends = Hari(user).out(:follow).type(:user)
|
16
134
|
|
17
|
-
|
135
|
+
# bringing all followers of artist, but user's friends first
|
136
|
+
tiesto_followers.sort_by user_friends
|
137
|
+
=> [883, 317, 211, 157, 163, 103, 47, 53, 7]
|
18
138
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
139
|
+
# paginating through them (offset + count)
|
140
|
+
tiesto_followers.sort_by user_friends, 3, 5
|
141
|
+
=> [157, 163, 103, 47, 53]
|
142
|
+
```
|
data/lib/hari/entity/property.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require 'hari/entity/serialization/boolean'
|
2
|
-
require 'hari/entity/serialization/date'
|
3
|
-
require 'hari/entity/serialization/datetime'
|
4
|
-
require 'hari/entity/serialization/float'
|
5
|
-
require 'hari/entity/serialization/integer'
|
6
|
-
require 'hari/entity/serialization/string'
|
7
|
-
require 'hari/entity/serialization/time'
|
8
|
-
|
9
1
|
module Hari
|
10
2
|
class Entity
|
11
3
|
module Serialization
|
12
4
|
extend ActiveSupport::Concern
|
13
5
|
|
6
|
+
autoload :Boolean, 'hari/entity/serialization/boolean'
|
7
|
+
autoload :Date, 'hari/entity/serialization/date'
|
8
|
+
autoload :DateTime, 'hari/entity/serialization/datetime'
|
9
|
+
autoload :Float, 'hari/entity/serialization/float'
|
10
|
+
autoload :Integer, 'hari/entity/serialization/integer'
|
11
|
+
autoload :String, 'hari/entity/serialization/string'
|
12
|
+
autoload :Time, 'hari/entity/serialization/time'
|
13
|
+
|
14
14
|
def to_json
|
15
15
|
hash = self.class.properties.inject({}) do |buffer, prop|
|
16
16
|
buffer.merge prop.name => prop.serialize(send(prop.name))
|
data/lib/hari/entity.rb
CHANGED
@@ -7,6 +7,11 @@ module Hari
|
|
7
7
|
extend ActiveModel::Naming
|
8
8
|
extend ActiveModel::Callbacks
|
9
9
|
include ActiveModel::Validations
|
10
|
+
|
11
|
+
autoload :Property, 'hari/entity/property'
|
12
|
+
autoload :Repository, 'hari/entity/property'
|
13
|
+
autoload :Serialization, 'hari/entity/property'
|
14
|
+
|
10
15
|
extend Property::Builder
|
11
16
|
include Repository
|
12
17
|
include Serialization
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Hari
|
2
|
+
module Keys
|
3
|
+
class Key
|
4
|
+
|
5
|
+
attr_reader :node, :name
|
6
|
+
|
7
|
+
def initialize(node = nil)
|
8
|
+
@node = node
|
9
|
+
end
|
10
|
+
|
11
|
+
def key
|
12
|
+
@key ||= begin
|
13
|
+
prefix = node ? "#{Hari.node_key(node)}:" : ''
|
14
|
+
prefix + name.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete!
|
19
|
+
Hari.redis.del key
|
20
|
+
end
|
21
|
+
|
22
|
+
def exists?
|
23
|
+
Hari.redis.exists key
|
24
|
+
end
|
25
|
+
|
26
|
+
def expire(milliseconds)
|
27
|
+
Hari.redis.pexpire key, milliseconds
|
28
|
+
end
|
29
|
+
|
30
|
+
def expire_at(timestamp)
|
31
|
+
Hari.redis.expireat key, ::Time.parse(timestamp).to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def persist
|
35
|
+
Hari.redis.persist key
|
36
|
+
end
|
37
|
+
|
38
|
+
def type
|
39
|
+
Hari.redis.type key
|
40
|
+
end
|
41
|
+
|
42
|
+
def ttl
|
43
|
+
Hari.redis.ttl key
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Hari
|
2
|
+
module Keys
|
3
|
+
class List < Key
|
4
|
+
|
5
|
+
def list(name)
|
6
|
+
@name = name
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def list!(name)
|
11
|
+
@name = name
|
12
|
+
range
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](*args)
|
16
|
+
arg = args.first
|
17
|
+
|
18
|
+
if args.size == 2
|
19
|
+
range *args
|
20
|
+
elsif arg.kind_of? Integer
|
21
|
+
at arg
|
22
|
+
elsif arg.kind_of? Range
|
23
|
+
range arg.first, arg.last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def first
|
28
|
+
self[0]
|
29
|
+
end
|
30
|
+
|
31
|
+
def last
|
32
|
+
self[-1]
|
33
|
+
end
|
34
|
+
|
35
|
+
def []=(index, member)
|
36
|
+
Hari.redis.lset key, index, member
|
37
|
+
end
|
38
|
+
|
39
|
+
def range(start = 0, stop = -1)
|
40
|
+
Hari.redis.lrange key, start, stop
|
41
|
+
end
|
42
|
+
|
43
|
+
alias :members :range
|
44
|
+
alias :to_a :range
|
45
|
+
|
46
|
+
def from(index)
|
47
|
+
range index
|
48
|
+
end
|
49
|
+
|
50
|
+
def to(index)
|
51
|
+
range 0, index
|
52
|
+
end
|
53
|
+
|
54
|
+
def at(index)
|
55
|
+
Hari.redis.lindex key, index
|
56
|
+
end
|
57
|
+
|
58
|
+
alias :index :at
|
59
|
+
|
60
|
+
def trim(start, stop)
|
61
|
+
Hari.redis.ltrim key, start, stop
|
62
|
+
end
|
63
|
+
|
64
|
+
def count
|
65
|
+
Hari.redis.llen key
|
66
|
+
end
|
67
|
+
|
68
|
+
alias :size :count
|
69
|
+
alias :length :count
|
70
|
+
|
71
|
+
def empty?
|
72
|
+
count == 0
|
73
|
+
end
|
74
|
+
|
75
|
+
def one?
|
76
|
+
count == 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def many?
|
80
|
+
count > 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def include?(member)
|
84
|
+
range.include? member
|
85
|
+
end
|
86
|
+
|
87
|
+
alias :member? :include?
|
88
|
+
|
89
|
+
def push(*members)
|
90
|
+
Hari.redis.rpush key, members
|
91
|
+
end
|
92
|
+
|
93
|
+
alias :rpush :push
|
94
|
+
alias :add :push
|
95
|
+
|
96
|
+
def lpush(*members)
|
97
|
+
Hari.redis.lpush key, members
|
98
|
+
end
|
99
|
+
|
100
|
+
def <<(member)
|
101
|
+
push member
|
102
|
+
end
|
103
|
+
|
104
|
+
def insert_before(pivot, member)
|
105
|
+
Hari.redis.linsert key, :before, pivot, member
|
106
|
+
end
|
107
|
+
|
108
|
+
def insert_after(pivot, member)
|
109
|
+
Hari.redis.linsert key, :after, pivot, member
|
110
|
+
end
|
111
|
+
|
112
|
+
alias :insert :insert_after
|
113
|
+
|
114
|
+
def delete(member, count = 0)
|
115
|
+
Hari.redis.lrem key, count, member
|
116
|
+
end
|
117
|
+
|
118
|
+
def pop
|
119
|
+
Hari.redis.rpop key
|
120
|
+
end
|
121
|
+
|
122
|
+
alias :rpop :pop
|
123
|
+
|
124
|
+
def shift
|
125
|
+
Hari.redis.lpop key
|
126
|
+
end
|
127
|
+
|
128
|
+
alias :lpop :shift
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Hari
|
2
|
+
module Keys
|
3
|
+
class Set < Key
|
4
|
+
|
5
|
+
def set(name)
|
6
|
+
@name = name
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def set!(name)
|
11
|
+
@name = name
|
12
|
+
members
|
13
|
+
end
|
14
|
+
|
15
|
+
def members
|
16
|
+
Hari.redis.smembers key
|
17
|
+
end
|
18
|
+
|
19
|
+
def rand(count = 1)
|
20
|
+
Hari.redis.srandmember key, count
|
21
|
+
end
|
22
|
+
|
23
|
+
def count
|
24
|
+
Hari.redis.scard key
|
25
|
+
end
|
26
|
+
|
27
|
+
alias :size :count
|
28
|
+
alias :length :count
|
29
|
+
|
30
|
+
def empty?
|
31
|
+
count == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def one?
|
35
|
+
count == 1
|
36
|
+
end
|
37
|
+
|
38
|
+
def many?
|
39
|
+
count > 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def include?(member)
|
43
|
+
Hari.redis.sismember key, member
|
44
|
+
end
|
45
|
+
|
46
|
+
alias :member? :include?
|
47
|
+
|
48
|
+
def add(*members)
|
49
|
+
Hari.redis.sadd key, members
|
50
|
+
end
|
51
|
+
|
52
|
+
def <<(member)
|
53
|
+
add member
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete(*members)
|
57
|
+
Hari.redis.srem key, members
|
58
|
+
end
|
59
|
+
|
60
|
+
def pop
|
61
|
+
Hari.redis.spop key
|
62
|
+
end
|
63
|
+
|
64
|
+
def intersect(*set_queries)
|
65
|
+
Hari.redis.sinter key, set_query_keys(set_queries)
|
66
|
+
end
|
67
|
+
|
68
|
+
def &(other_set_query)
|
69
|
+
intersect other_set_query
|
70
|
+
end
|
71
|
+
|
72
|
+
def diff(*set_queries)
|
73
|
+
Hari.redis.sdiff key, set_query_keys(set_queries)
|
74
|
+
end
|
75
|
+
|
76
|
+
def -(other_set_query)
|
77
|
+
diff other_set_query
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def set_query_keys(set_queries)
|
83
|
+
keys = set_queries.map do |query|
|
84
|
+
ensure_set_query! query
|
85
|
+
query.key
|
86
|
+
end
|
87
|
+
|
88
|
+
fail 'no query keys' if keys.empty?
|
89
|
+
|
90
|
+
keys
|
91
|
+
end
|
92
|
+
|
93
|
+
def ensure_set_query!(query)
|
94
|
+
unless query.kind_of?(Hari::Keys::Set)
|
95
|
+
fail 'not a set query'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Hari
|
2
|
+
module Keys
|
3
|
+
class SortedSet < Key
|
4
|
+
|
5
|
+
def sorted_set(name)
|
6
|
+
@name = name
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def sorted_set!(name)
|
11
|
+
@name = name
|
12
|
+
members
|
13
|
+
end
|
14
|
+
|
15
|
+
def range(start = 0, stop = -1, options = {})
|
16
|
+
return revrange(start, stop, options) if options[:desc]
|
17
|
+
|
18
|
+
Hari.redis.zrange key, start, stop, options.slice(:with_scores)
|
19
|
+
end
|
20
|
+
|
21
|
+
alias :members :range
|
22
|
+
|
23
|
+
def range_with_scores
|
24
|
+
range 0, -1, with_scores: true
|
25
|
+
end
|
26
|
+
|
27
|
+
def revrange(start = 0, stop = -1, options = {})
|
28
|
+
Hari.redis.zrevrange key, start, stop, options.slice(:with_scores)
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :reverse_range :revrange
|
32
|
+
alias :desc_range :revrange
|
33
|
+
|
34
|
+
def revrange_with_scores
|
35
|
+
revrange 0, -1, with_scores: true
|
36
|
+
end
|
37
|
+
|
38
|
+
def range_by_score(min, max, options = {})
|
39
|
+
return revrange_by_score(min, max, options) if options[:desc]
|
40
|
+
|
41
|
+
Hari.redis.zrangebyscore key, min, max, options.slice(:with_scores, :limit)
|
42
|
+
end
|
43
|
+
|
44
|
+
def revrange_by_score(min, max, options = {})
|
45
|
+
Hari.redis.zrevrangebyscore key, max, min, options.slice(:with_scores, :limit)
|
46
|
+
end
|
47
|
+
|
48
|
+
def rank(member, options = {})
|
49
|
+
return revrank(member, options) if options[:desc]
|
50
|
+
|
51
|
+
Hari.redis.zrank key, member
|
52
|
+
end
|
53
|
+
|
54
|
+
alias :ranking :rank
|
55
|
+
alias :position :rank
|
56
|
+
|
57
|
+
def revrank(member)
|
58
|
+
Hari.redis.zrevrank key, member
|
59
|
+
end
|
60
|
+
|
61
|
+
alias :reverse_ranking :revrank
|
62
|
+
alias :reverse_position :revrank
|
63
|
+
|
64
|
+
def count
|
65
|
+
Hari.redis.zcard key
|
66
|
+
end
|
67
|
+
|
68
|
+
alias :size :count
|
69
|
+
alias :length :count
|
70
|
+
|
71
|
+
def empty?
|
72
|
+
count == 0
|
73
|
+
end
|
74
|
+
|
75
|
+
def one?
|
76
|
+
count == 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def many?
|
80
|
+
count > 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def include?(member)
|
84
|
+
score(member).present?
|
85
|
+
end
|
86
|
+
|
87
|
+
alias :member? :include?
|
88
|
+
|
89
|
+
def score(member)
|
90
|
+
Hari.redis.zscore key, member
|
91
|
+
end
|
92
|
+
|
93
|
+
def add(*score_members)
|
94
|
+
Hari.redis.zadd key, score_members.to_a.flatten
|
95
|
+
end
|
96
|
+
|
97
|
+
def <<(*score_members)
|
98
|
+
add score_members
|
99
|
+
end
|
100
|
+
|
101
|
+
def delete(*members)
|
102
|
+
Hari.redis.zrem key, members
|
103
|
+
end
|
104
|
+
|
105
|
+
def trim_by_rank(start, stop)
|
106
|
+
Hari.redis.zremrangebyrank key, start, stop
|
107
|
+
end
|
108
|
+
|
109
|
+
def trim_by_score(min, max)
|
110
|
+
Hari.redis.zremrangebyscore key, min, max
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|