relix 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/HISTORY.md +5 -0
- data/README.md +18 -0
- data/lib/relix/index.rb +5 -0
- data/lib/relix/index_set.rb +22 -10
- data/lib/relix/indexes/unique.rb +6 -2
- data/lib/relix/version.rb +1 -1
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MTU3YjZmNjYxOTEzODAxN2EyM2M3Nzk5ZWVhYTg5M2IyMGFkZDE0ZGIzMmYz
|
10
|
-
NjQyYmQ2MTc3NGU4Zjc1ZmU5ZTE0Yjc5NTNkOGFmN2I0NmYzZGZiZDkxYjYy
|
11
|
-
ZjBjYTY4MDlhYmQ5OTVlM2FiZWQzZWJhMTkyYTBmZTE3NjJiNzM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NTdkZjBlMTE2YThjNTkyOTRkMWI4YWQ0ZGI4NTM2ZGY5ZDFlOTVhYTc3OWYw
|
14
|
-
MmQ0MmNlMjExZTYyOGU4YjY0ZmJjNGQyNWI1YjMwYmI5N2RlNTI1MDcxN2Fl
|
15
|
-
NTEzY2I4NjljZmU1ZTA3ZDhkYzQ2YjZlODcyNTgzYWZlNjFjNjE=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3cd2735837da417e0b1d16ef57f3682e9dd298df
|
4
|
+
data.tar.gz: d205651a776733c1371cc6e4682c5112e183fdbb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8fc398350349c460f237ec6de28a12120d9f22ade54e6f3694a93ecb6481e08433fb0b3e3ab643b77c06f79d3a6ee725cf3bb39233cbecfc3184ec0c68e45571
|
7
|
+
data.tar.gz: 0eaa69f08ace7ede18debe89bc534322bcdf036bc92af7a1265cfd8859e2b5c849b52f27537112fb18c61c8225e23692124c7d357b5e40e7968433937883ec18
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -163,6 +163,24 @@ Relix has some special handling for interrogative accessors (i.e. those ending w
|
|
163
163
|
|
164
164
|
It also auto-casts `nil` to `false` and any other object to `true` for interrogative accessors, so that lookups work like you'd expect them to in a Ruby context. If you don't want to auto-casting, just alias your interrogative to a non-interrogative name and index on that instead.
|
165
165
|
|
166
|
+
### Conditional Indexing
|
167
|
+
|
168
|
+
Relix allows you to decide on a per-object basis whether a given index should be built:
|
169
|
+
|
170
|
+
class Person
|
171
|
+
include Relix
|
172
|
+
relix do
|
173
|
+
primary_key :key
|
174
|
+
multi :name, on: %w(first last), if: full_name?
|
175
|
+
end
|
176
|
+
|
177
|
+
def full_name?
|
178
|
+
(first && last)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
People will only be indexed now if they have both a first and a last name, otherwise they will not be included in the index at all. Note that this is also smart enough to deindex an object if its condition changes.
|
183
|
+
|
166
184
|
### Space efficiency
|
167
185
|
|
168
186
|
Model attributes that are indexed on but that never change can be marked as immutable to prevent them being stored (since they don't have to be reindexed). The primary key is marked immutable by default, but other attributes can be as well:
|
data/lib/relix/index.rb
CHANGED
@@ -34,6 +34,7 @@ module Relix
|
|
34
34
|
@model_name = @set.klass.name
|
35
35
|
@accessors = Array(accessors).collect{|a| Accessor.new(a)}
|
36
36
|
@attribute_immutable = options[:immutable_attribute]
|
37
|
+
@conditional = options[:if]
|
37
38
|
@options = options
|
38
39
|
end
|
39
40
|
|
@@ -77,6 +78,10 @@ module Relix
|
|
77
78
|
true
|
78
79
|
end
|
79
80
|
|
81
|
+
def index?(r, object, value)
|
82
|
+
(@conditional ? object.send(@conditional) : true)
|
83
|
+
end
|
84
|
+
|
80
85
|
def query(r, value)
|
81
86
|
nil
|
82
87
|
end
|
data/lib/relix/index_set.rb
CHANGED
@@ -129,6 +129,7 @@ module Relix
|
|
129
129
|
current_values_name = current_values_name(pk)
|
130
130
|
redis.watch current_values_name
|
131
131
|
current_values = redis.hgetall(current_values_name)
|
132
|
+
new_current_values = {}
|
132
133
|
|
133
134
|
ops = full_index_list.collect do |name,index|
|
134
135
|
value = index.read_normalized(object)
|
@@ -136,20 +137,31 @@ module Relix
|
|
136
137
|
|
137
138
|
((watch = index.watch(value, old_value)) && redis.watch(*watch))
|
138
139
|
|
139
|
-
|
140
|
-
|
140
|
+
if index.index?(redis, object, value)
|
141
|
+
next if value == old_value
|
142
|
+
next unless index.filter(redis, object, value)
|
141
143
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
144
|
+
new_current_values[name] = value unless index.attribute_immutable?
|
145
|
+
query_value = index.query(redis, value)
|
146
|
+
proc do
|
147
|
+
index.index(redis, pk, object, value, old_value, *query_value)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
proc do
|
151
|
+
index.deindex(redis, pk, old_value)
|
152
|
+
end
|
147
153
|
end
|
148
154
|
end.compact
|
149
155
|
|
150
|
-
|
151
|
-
|
152
|
-
|
156
|
+
if new_current_values.any?
|
157
|
+
ops << proc do
|
158
|
+
redis.hmset(current_values_name, *new_current_values.flatten)
|
159
|
+
end
|
160
|
+
elsif current_values.any?
|
161
|
+
ops << proc do
|
162
|
+
redis.del(current_values_name)
|
163
|
+
end
|
164
|
+
end
|
153
165
|
|
154
166
|
ops
|
155
167
|
end
|
data/lib/relix/indexes/unique.rb
CHANGED
@@ -15,11 +15,15 @@ module Relix
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def filter(r, object, value)
|
18
|
-
return true if read(object).values.any?{|e| e.nil?}
|
19
18
|
if r.hexists(hash_name, value)
|
20
19
|
raise NotUniqueError.new("'#{value}' is not unique in index #{name}")
|
21
20
|
end
|
22
|
-
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def index?(r, object, value)
|
25
|
+
return false if read(object).values.any?{|e| e.nil?}
|
26
|
+
super
|
23
27
|
end
|
24
28
|
|
25
29
|
def index(r, pk, object, value, old_value)
|
data/lib/relix/version.rb
CHANGED
metadata
CHANGED
@@ -1,48 +1,48 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathaniel Talbott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
prerelease: false
|
15
14
|
name: hiredis
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
17
|
- - ~>
|
19
18
|
- !ruby/object:Gem::Version
|
20
19
|
version: 0.4.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
21
22
|
version_requirements: !ruby/object:Gem::Requirement
|
22
23
|
requirements:
|
23
24
|
- - ~>
|
24
25
|
- !ruby/object:Gem::Version
|
25
26
|
version: 0.4.1
|
26
|
-
type: :runtime
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
prerelease: false
|
29
28
|
name: redis
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
31
30
|
requirements:
|
32
31
|
- - ~>
|
33
32
|
- !ruby/object:Gem::Version
|
34
33
|
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
35
36
|
version_requirements: !ruby/object:Gem::Requirement
|
36
37
|
requirements:
|
37
38
|
- - ~>
|
38
39
|
- !ruby/object:Gem::Version
|
39
40
|
version: '3.0'
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
of that pluggable indexing of your data for fast lookup.'
|
41
|
+
description: 'Relix is a layer that can be added on to any model to make all the normal
|
42
|
+
types of querying you want to do: equality, less than/greater than, in set, range,
|
43
|
+
limit, etc., quick and painless. Relix depends on Redis to be awesome at what it
|
44
|
+
does - blazingly fast operations on basic data types - and layers on top of that
|
45
|
+
pluggable indexing of your data for fast lookup.'
|
46
46
|
email:
|
47
47
|
- nathaniel@talbott.ws
|
48
48
|
executables: []
|
@@ -73,17 +73,17 @@ require_paths:
|
|
73
73
|
- lib
|
74
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
75
75
|
requirements:
|
76
|
-
- -
|
76
|
+
- - '>='
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: '0'
|
79
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - '>='
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: 1.5.2
|
84
84
|
requirements: []
|
85
85
|
rubyforge_project:
|
86
|
-
rubygems_version: 2.0.
|
86
|
+
rubygems_version: 2.0.3
|
87
87
|
signing_key:
|
88
88
|
specification_version: 4
|
89
89
|
summary: A Redis-backed indexing layer that can be used with any (or no) backend data
|