relix 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDQwM2VkOWJiYjk5NGQzYmNiMjA4ZThjNzQ3ZDRmNmQzZDJmZjRlZg==
5
+ data.tar.gz: !binary |-
6
+ N2Q3YTYyZWEyNjk2YTFjOGNiODQ0MDhmMGFmNTY1NTI5NDUxODE2ZQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YzI2MTNmZmVmYTVlNTllNmQ2NDhkOTUxYjkwM2IxNGQ0NGI1NjQzMGNiYmE3
10
+ NWUxNjIzYjk1YWI1OGNkODdlYTNiMmZlNTcwZjdmOWI0MzlmYzYwMjAxMzQw
11
+ YWM5NzAwZGU2ODE5ZmMzOGExMzY2NmE5OWE2NGYzZDdkMzczYzY=
12
+ data.tar.gz: !binary |-
13
+ ZTgxNzA5Y2I0YjZkMTVlYjM4NzBkYzUwYTAyNTExOTIwOTYwOGZlZWVmNjk3
14
+ Mjg3ZmVlNWQ2YWMyNGNhZWMzNzlhMTY1YjYwNWM0ZTNjMGU5YzY0ZTRmYTYz
15
+ MzdkY2E2NzczYTRlYTkyNjA0ZTY3M2ZkODZhNDNhYjM0OTBiZTk=
data/HISTORY.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### 1.4.0
2
+
3
+ * Add #deindex_by_primary_key. (ntalbott)
4
+ * Add license. (ntalbott)
5
+
1
6
  ### 1.3.0
2
7
 
3
8
  * Update redis-rb dependency to 3.0. (ntalbott)
data/README.md CHANGED
@@ -2,12 +2,14 @@
2
2
 
3
3
  A Redis-backed indexing layer that can be used with any (or no) backend data storage.
4
4
 
5
+
5
6
  ## Rationale
6
7
 
7
8
  With the rise in popularity of non-relational databases, and the regular use of relational databases in non-relational ways, data indexing has become an aspect of data storage that you can't simply assume is handled for you. More and more applications are storing their data in databases that treat that stored data as opaque, and thus there's no query engine sitting on top of the data making sure that it can be quickly and flexibly looked up.
8
9
 
9
10
  Relix is a layer that can be added on to any model to make all the normal types of querying you want to do: equality, less than/greater than, in set, range, limit, etc., quick and painless. Relix depends on Redis to be awesome at what it does - blazingly fast operations on basic data types - and layers on top of that pluggable indexing of your data for fast lookup.
10
11
 
12
+
11
13
  ## Philosophy
12
14
 
13
15
  * Performance is paramount - be FAST.
@@ -17,6 +19,7 @@ Relix is a layer that can be added on to any model to make all the normal types
17
19
  ** Make continuous index repair easy since the chaos monkey could attack at any time.
18
20
  * Be pluggable; keep the core simple and allow easy extensibility
19
21
 
22
+
20
23
  ## Installation
21
24
 
22
25
  If you're using bundler, add Relix to your Gemfile:
@@ -92,6 +95,7 @@ Since the :primary_key index is ordered by insertion order, we've also declared
92
95
 
93
96
  p Transaction.lookup{|q| q[:by_created_at].all} # => [4,2,1,3]
94
97
 
98
+
95
99
  ## Querying
96
100
 
97
101
  Relix uses a simple query language based on method chaining. A "root" query is passed in to the lookup block, and then query terms are chained off of it:
@@ -142,7 +146,6 @@ When there are multiple attributes, they are specified in a hash:
142
146
  {storage_state: 'cached', account_id: 'bob'}, limit: 10)
143
147
  end
144
148
 
145
-
146
149
  ### Space efficiency
147
150
 
148
151
  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:
@@ -154,6 +157,19 @@ Model attributes that are indexed on but that never change can be marked as immu
154
157
  This can also provide concurrency benefits since the keys for the indexes on immutable attributes don't have to be watched for concurrent modification.
155
158
 
156
159
 
160
+ ## Deindexing
161
+
162
+ You'll probably want to remove an object from the index at some point. To do that simply call `#deindex!` on it:
163
+
164
+ person.deindex!
165
+
166
+ You can also remove something from the index even if you don't have the complete object in hand anymore; simply call `.deindex_by_primary_key!` on its class:
167
+
168
+ Person.deindex_by_primary_key!(44)
169
+
170
+ The class-level `deindex_by_primary_key` cannot clean up immutable indexes other than the primary key (since the current value of immutable keys is not stored), so calling plain `deindex!` on an object is preferred.
171
+
172
+
157
173
  ## Index Types
158
174
 
159
175
  ### PrimaryKeyIndex
@@ -164,10 +180,9 @@ The primary key index is the only index that is required on a model. Under the c
164
180
  primary_key :id
165
181
  end
166
182
 
167
- **Supported Operators**: eq, all
183
+ **Supported Operators**: eq, all
168
184
  **Ordering**: insertion
169
185
 
170
-
171
186
  ### MultiIndex
172
187
 
173
188
  Multi indexes allow multiple matching primary keys per indexed value, and are ideal for one to many relationships. They can include an ordering, and are declared using #multi in the relix block:
@@ -176,10 +191,9 @@ Multi indexes allow multiple matching primary keys per indexed value, and are id
176
191
  multi :account_id, order: :created_at
177
192
  end
178
193
 
179
- **Supported Operators**: eq
194
+ **Supported Operators**: eq
180
195
  **Ordering**: can be ordered on any numeric attribute (default is the to_i of the indexed value)
181
196
 
182
-
183
197
  ### UniqueIndex
184
198
 
185
199
  Unique indexes will raise an error if the same value is indexed twice for a different primary key. They also provide super fast lookups. They are declared using #unique in the relix block:
@@ -190,7 +204,7 @@ Unique indexes will raise an error if the same value is indexed twice for a diff
190
204
 
191
205
  Unique indexes ignore nil values - they will not be indexed and an error is not raised if there is more than one object with a value of nil. A multi-value unique index will be completely skipped if any value in it is nil.
192
206
 
193
- **Supported Operators**: eq, all
207
+ **Supported Operators**: eq, all
194
208
  **Ordering**: can be ordered on any numeric attribute (default is the to_i of the indexed value)
195
209
 
196
210
  ### OrderedIndex
@@ -202,7 +216,7 @@ primary keys per indexed value. They are declared using #ordered in the relix bl
202
216
  ordered :birthdate
203
217
  end
204
218
 
205
- **Supported Operators**: eq, lt, lte, gt, gte, order, limit, offset
219
+ **Supported Operators**: eq, lt, lte, gt, gte, order, limit, offset
206
220
  **Ordering**: ordered ascending by the indexed value, but can be queried in
207
221
  reverse order if you use `order(:desc)`.
208
222
 
@@ -218,6 +232,7 @@ Ordered indexes support a flexible fluent interface for specifying the query:
218
232
 
219
233
  This query returns the primary keys of the 10 youngest people born in 1990.
220
234
 
235
+
221
236
  ## Keying
222
237
 
223
238
  A big part of using Redis well is choosing solid keys; Relix has a pluggable keying infrastructure that makes it easy to use different key names for different situations. This actually rose out of the fact that the first release of Relix had a pathetic set of keys, and the need to support existing deployments while moving to something better going forward. Keyers are set on a per-model basis along with other configuration:
data/lib/relix/core.rb CHANGED
@@ -25,6 +25,10 @@ module Relix
25
25
  def lookup(&block)
26
26
  relix.lookup(&block)
27
27
  end
28
+
29
+ def deindex_by_primary_key!(pk)
30
+ relix.deindex_by_primary_key!(pk)
31
+ end
28
32
  end
29
33
 
30
34
  def relix
@@ -113,7 +113,22 @@ module Relix
113
113
  end
114
114
 
115
115
  ((watch = index.watch(old_value)) && @redis.watch(*watch))
116
- proc { index.deindex(@redis, pk, object, old_value) }
116
+ proc { index.deindex(@redis, pk, old_value) }
117
+ end.tap { |ops| ops << proc { @redis.del current_values_name } }
118
+ end
119
+ end
120
+
121
+ def deindex_by_primary_key!(pk)
122
+ handle_concurrent_modifications(pk) do
123
+ current_values_name = current_values_name(pk)
124
+ @redis.watch current_values_name
125
+ current_values = @redis.hgetall(current_values_name)
126
+
127
+ indexes.map do |name, index|
128
+ old_value = current_values[name]
129
+
130
+ ((watch = index.watch(old_value)) && @redis.watch(*watch))
131
+ proc { index.deindex(@redis, pk, old_value) }
117
132
  end.tap { |ops| ops << proc { @redis.del current_values_name } }
118
133
  end
119
134
  end
@@ -11,7 +11,7 @@ module Relix
11
11
  r.zrem(key_for(old_value), pk)
12
12
  end
13
13
 
14
- def deindex(r, pk, object, old_value)
14
+ def deindex(r, pk, old_value)
15
15
  r.zrem(key_for(old_value), pk)
16
16
  end
17
17
 
@@ -30,4 +30,4 @@ module Relix
30
30
  end
31
31
  end
32
32
  register_index MultiIndex
33
- end
33
+ end
@@ -19,7 +19,7 @@ module Relix
19
19
  r.zadd(sorted_set_name, score(object, value), pk)
20
20
  end
21
21
 
22
- def deindex(r, pk, object, old_value)
22
+ def deindex(r, pk, old_value)
23
23
  r.zrem(sorted_set_name, pk)
24
24
  end
25
25
 
@@ -23,7 +23,7 @@ module Relix
23
23
  r.zadd(name, rank, pk)
24
24
  end
25
25
 
26
- def deindex(r, pk, object, old_value)
26
+ def deindex(r, pk, old_value)
27
27
  r.zrem(name, pk)
28
28
  end
29
29
 
@@ -33,7 +33,7 @@ module Relix
33
33
  r.hdel(hash_name, old_value)
34
34
  end
35
35
 
36
- def deindex(r, pk, object, old_value)
36
+ def deindex(r, pk, old_value)
37
37
  r.hdel(hash_name, old_value)
38
38
  r.zrem(sorted_set_name, pk)
39
39
  end
@@ -49,4 +49,4 @@ module Relix
49
49
  register_index UniqueIndex
50
50
 
51
51
  class NotUniqueError < Relix::Error; end
52
- end
52
+ end
data/lib/relix/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Relix
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
metadata CHANGED
@@ -1,38 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
5
- prerelease:
4
+ version: 1.4.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nathaniel Talbott
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-11 00:00:00.000000000 Z
11
+ date: 2013-03-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
14
+ prerelease: false
15
15
  name: hiredis
16
- requirement: &70128679226480 !ruby/object:Gem::Requirement
17
- none: false
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: 0.4.1
21
+ version_requirements: !ruby/object:Gem::Requirement
18
22
  requirements:
19
23
  - - ~>
20
24
  - !ruby/object:Gem::Version
21
25
  version: 0.4.1
22
26
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70128679226480
25
27
  - !ruby/object:Gem::Dependency
28
+ prerelease: false
26
29
  name: redis
27
- requirement: &70128679224880 !ruby/object:Gem::Requirement
28
- none: false
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '3.0'
35
+ version_requirements: !ruby/object:Gem::Requirement
29
36
  requirements:
30
37
  - - ~>
31
38
  - !ruby/object:Gem::Version
32
39
  version: '3.0'
33
40
  type: :runtime
34
- prerelease: false
35
- version_requirements: *70128679224880
36
41
  description: ! 'Relix is a layer that can be added on to any model to make all the
37
42
  normal types of querying you want to do: equality, less than/greater than, in set,
38
43
  range, limit, etc., quick and painless. Relix depends on Redis to be awesome at
@@ -59,28 +64,28 @@ files:
59
64
  - lib/relix/redis.rb
60
65
  - lib/relix/version.rb
61
66
  homepage: http://github.com/ntalbott/relix
62
- licenses: []
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
63
70
  post_install_message:
64
71
  rdoc_options: []
65
72
  require_paths:
66
73
  - lib
67
74
  required_ruby_version: !ruby/object:Gem::Requirement
68
- none: false
69
75
  requirements:
70
76
  - - ! '>='
71
77
  - !ruby/object:Gem::Version
72
78
  version: '0'
73
79
  required_rubygems_version: !ruby/object:Gem::Requirement
74
- none: false
75
80
  requirements:
76
81
  - - ! '>='
77
82
  - !ruby/object:Gem::Version
78
83
  version: 1.5.2
79
84
  requirements: []
80
85
  rubyforge_project:
81
- rubygems_version: 1.8.11
86
+ rubygems_version: 2.0.0
82
87
  signing_key:
83
- specification_version: 3
88
+ specification_version: 4
84
89
  summary: A Redis-backed indexing layer that can be used with any (or no) backend data
85
90
  storage.
86
91
  test_files: []