easyredis 0.0.3 → 0.0.4
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/README.md +27 -8
- data/Rakefile +16 -17
- data/easyredis.gemspec +2 -5
- data/lib/easyredis.rb +154 -75
- data/tests/test.rb +1 -1
- metadata +2 -13
data/README.md
CHANGED
@@ -6,18 +6,21 @@ Redis is a very fast key-value store that supports data structures like lists, (
|
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
You can
|
9
|
+
You can just grab the gem and you're good to go:
|
10
|
+
|
11
|
+
$ gem install easyredis
|
12
|
+
|
13
|
+
Or, you can get the source with git:
|
10
14
|
|
11
15
|
$ git clone git://github.com/alecbenzer/easyredis.git
|
12
16
|
|
13
17
|
or just download and extract a tar archive with the Downloads button.
|
14
18
|
|
15
|
-
Once you have the source, run:
|
19
|
+
Once you have the source, you can run:
|
16
20
|
|
17
|
-
$ rake
|
18
|
-
$
|
19
|
-
|
20
|
-
Where x.x.x is the current version number.
|
21
|
+
$ rake manifest
|
22
|
+
$ rake build_gemspec
|
23
|
+
$ rake install easyredis.gemspec
|
21
24
|
|
22
25
|
## Basics
|
23
26
|
|
@@ -69,5 +72,21 @@ We can now sort our posts by title:
|
|
69
72
|
|
70
73
|
And also search:
|
71
74
|
|
72
|
-
Post.search_by
|
73
|
-
Post.find_by
|
75
|
+
Post.search_by :title, "A common title" # all posts with this title
|
76
|
+
Post.find_by :title, "My First Post" # just one post
|
77
|
+
|
78
|
+
## Text Search and Completions
|
79
|
+
|
80
|
+
We could have defined Post like this:
|
81
|
+
|
82
|
+
class Post < EasyRedis::Model
|
83
|
+
field :title
|
84
|
+
field :body
|
85
|
+
|
86
|
+
text_search :title
|
87
|
+
end
|
88
|
+
|
89
|
+
Now we can perform text searches and completions against our title field:
|
90
|
+
|
91
|
+
Post.matches(:title,"Fir") # titles that begin with "Fir"
|
92
|
+
Post.match(:title,"First") # posts whose titles contain "First"
|
data/Rakefile
CHANGED
@@ -2,21 +2,20 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('easyredis','0.0.
|
5
|
+
Echoe.new('easyredis','0.0.4') do |p|
|
6
6
|
p.description = "simple framework designed to make using redis as a database simpler"
|
7
7
|
p.url = "https://github.com/alecbenzer/easyredis"
|
8
8
|
p.author = "Alec Benzer"
|
9
9
|
p.email = "alecbezer @nospam@ gmail.com"
|
10
10
|
p.ignore_pattern = ["*.rdb"]
|
11
|
-
p.development_dependencies = ["redis >=2.1.1"
|
11
|
+
p.development_dependencies = ["redis >=2.1.1"]
|
12
12
|
end
|
13
13
|
|
14
14
|
|
15
15
|
require 'benchmark'
|
16
16
|
require './tests/test'
|
17
17
|
|
18
|
-
def rand_name
|
19
|
-
length = 2
|
18
|
+
def rand_name(length=2)
|
20
19
|
chars = []
|
21
20
|
length.times { chars << (rand(26) + 65).chr }
|
22
21
|
chars.join
|
@@ -26,17 +25,17 @@ end
|
|
26
25
|
namespace :bm do
|
27
26
|
task :clear do
|
28
27
|
puts "destroying #{Man.count} previous entries"
|
29
|
-
Benchmark.
|
30
|
-
|
31
|
-
end
|
28
|
+
time = Benchmark.measure { Man.destroy_all }
|
29
|
+
puts time.format
|
32
30
|
end
|
33
31
|
|
34
32
|
task :add do
|
35
33
|
count = ENV["count"] ? ENV["count"].to_i : 25000
|
36
34
|
puts "adding #{count} new entries"
|
37
35
|
time = Benchmark::Tms.new
|
36
|
+
length = Math.log(3*count,26).round
|
38
37
|
count.times do
|
39
|
-
name = rand_name
|
38
|
+
name = rand_name(length)
|
40
39
|
age = rand(100)
|
41
40
|
time += Benchmark.measure { m = Man.new ; m.name = name ; m.age = age }
|
42
41
|
end
|
@@ -48,9 +47,10 @@ namespace :bm do
|
|
48
47
|
task :search do
|
49
48
|
puts "searching #{Man.count} entries by a particular name"
|
50
49
|
name = Man.rand.name
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
count = -1
|
51
|
+
time = Benchmark.measure { count = Man.search_by(:name,name).count }
|
52
|
+
puts "retrived #{count} records in:"
|
53
|
+
puts (time*1000).format
|
54
54
|
end
|
55
55
|
|
56
56
|
task :singlesearch do
|
@@ -60,9 +60,9 @@ namespace :bm do
|
|
60
60
|
t1 = Benchmark.measure { Man.search(:age => age) }
|
61
61
|
t2 = Benchmark.measure { Man.search_by(:age,age) }
|
62
62
|
puts "Model#search:"
|
63
|
-
puts t1.format
|
63
|
+
puts (t1*1000).format
|
64
64
|
puts "Model#search_by:"
|
65
|
-
puts t2.format
|
65
|
+
puts (t2*1000).format
|
66
66
|
puts "search is #{((t1.real/t2.real) - 1)*100}% slower"
|
67
67
|
end
|
68
68
|
|
@@ -73,15 +73,14 @@ namespace :bm do
|
|
73
73
|
count = 0
|
74
74
|
time = Benchmark.measure { count = Man.search(:name => name, :age => age).size }
|
75
75
|
puts "retrived #{count} out of #{Man.count} entries in:"
|
76
|
-
puts time.format
|
76
|
+
puts (time*1000).format
|
77
77
|
end
|
78
78
|
|
79
79
|
task :find do
|
80
80
|
puts "finding one of #{Man.count} entries by name"
|
81
81
|
name = Man.rand.name
|
82
|
-
Benchmark.
|
83
|
-
|
84
|
-
end
|
82
|
+
time = Benchmark.measure { Man.find_by(:name,name) }
|
83
|
+
puts (time*1000).format
|
85
84
|
end
|
86
85
|
|
87
86
|
end
|
data/easyredis.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{easyredis}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Alec Benzer"]
|
9
|
-
s.date = %q{2011-02-
|
9
|
+
s.date = %q{2011-02-07}
|
10
10
|
s.description = %q{simple framework designed to make using redis as a database simpler}
|
11
11
|
s.email = %q{alecbezer @nospam@ gmail.com}
|
12
12
|
s.extra_rdoc_files = ["README.md", "lib/easyredis.rb"]
|
@@ -23,13 +23,10 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
25
|
s.add_development_dependency(%q<redis>, [">= 2.1.1"])
|
26
|
-
s.add_development_dependency(%q<activesupport>, [">= 3.0.0"])
|
27
26
|
else
|
28
27
|
s.add_dependency(%q<redis>, [">= 2.1.1"])
|
29
|
-
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
30
28
|
end
|
31
29
|
else
|
32
30
|
s.add_dependency(%q<redis>, [">= 2.1.1"])
|
33
|
-
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
34
31
|
end
|
35
32
|
end
|
data/lib/easyredis.rb
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
|
8
8
|
require 'redis'
|
9
9
|
require 'set'
|
10
|
-
require 'active_support/inflector'
|
11
10
|
|
12
11
|
|
13
12
|
# main EasyRedis module which
|
@@ -16,6 +15,9 @@ module EasyRedis
|
|
16
15
|
|
17
16
|
# generate a 'score' for a string
|
18
17
|
# used for storing it in a sorted set
|
18
|
+
#
|
19
|
+
# This method effectively turns a string into a base 27 floating point number,
|
20
|
+
# where 0 corresponds to no letter, 1 to A, 2 to B, etc.
|
19
21
|
def self.string_score(str)
|
20
22
|
str = str.downcase
|
21
23
|
mult = 1.0
|
@@ -29,11 +31,19 @@ module EasyRedis
|
|
29
31
|
|
30
32
|
# gets a score for a generic object
|
31
33
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
+
# The score is determined as follows:
|
35
|
+
# First, if the object is a string, string_score is used to get its score.
|
36
|
+
# Otherwise, we try calling the following methods on the object in turn, returning the first that works: score, to_f, to_i.
|
37
|
+
# If none of those work, we simply return the object itself.
|
34
38
|
def self.score(obj)
|
35
39
|
if obj.is_a? String
|
36
40
|
string_score(obj)
|
41
|
+
elsif obj.respond_to? "score"
|
42
|
+
obj.score
|
43
|
+
elsif obj.respond_to? "to_f"
|
44
|
+
obj.to_f
|
45
|
+
elsif obj.respond_to? "to_i"
|
46
|
+
obj.to_i
|
37
47
|
else
|
38
48
|
obj
|
39
49
|
end
|
@@ -62,6 +72,17 @@ module EasyRedis
|
|
62
72
|
end
|
63
73
|
end
|
64
74
|
|
75
|
+
# exception that indicates that the given field has not been indexed for text-searching
|
76
|
+
class FieldNotTextSearchable < RuntimeError
|
77
|
+
def initialize(field)
|
78
|
+
@message = "field '#{field.to_s}' not text-searchable"
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
@message
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
65
86
|
# exception that indicated an unknown ordering option was encountered
|
66
87
|
class UnknownOrderOption < RuntimeError
|
67
88
|
def initialize(opt)
|
@@ -73,23 +94,14 @@ module EasyRedis
|
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
76
|
-
# class representing a
|
77
|
-
class
|
97
|
+
# class representing a generic collection
|
98
|
+
class Collection
|
78
99
|
include Enumerable
|
79
100
|
|
80
|
-
# initialize the sort with a specific field, ordering option, and model
|
81
|
-
def initialize(field,order,klass)
|
82
|
-
raise EasyRedis::FieldNotSortable, field unless klass.sortable?(field)
|
83
|
-
raise EasyRedis::UnknownOrderOption, order unless [:asc,:desc].member? order
|
84
|
-
@field = field
|
85
|
-
@order = order
|
86
|
-
@klass = klass
|
87
|
-
end
|
88
|
-
|
89
101
|
# access elements in this sort
|
90
102
|
#
|
91
|
-
# Work's like
|
92
|
-
#
|
103
|
+
# Work's like an Array's [] method. It can take a specific index, a range, or an offset and an amount/limit.
|
104
|
+
# This method uses the underlying access method, which handles the actual retrival.
|
93
105
|
def [](index,limit=nil)
|
94
106
|
if limit
|
95
107
|
offset = index
|
@@ -101,36 +113,12 @@ module EasyRedis
|
|
101
113
|
end
|
102
114
|
end
|
103
115
|
|
104
|
-
#
|
105
|
-
#
|
106
|
-
# takes a range and returns corresponding elements
|
107
|
-
def access(range)
|
108
|
-
a = range.begin
|
109
|
-
b = range.end
|
110
|
-
b -= 1 if index.exclude_end?
|
111
|
-
ids = []
|
112
|
-
if @order == :asc
|
113
|
-
ids = EasyRedis.redis.zrange(@klass.sort_prefix(@field),a,b)
|
114
|
-
elsif @order == :desc
|
115
|
-
ids = EasyRedis.redis.zrevrange(@klass.sort_prefix(@field),a,b)
|
116
|
-
end
|
117
|
-
ids.map{|i|@klass.new(i)}
|
118
|
-
end
|
119
|
-
|
120
|
-
# iterate through all members of this sort
|
116
|
+
# iterate through all members of this collection
|
121
117
|
def each
|
122
118
|
self[0..-1].each { |o| yield o }
|
123
119
|
end
|
124
120
|
|
125
|
-
# return the
|
126
|
-
#
|
127
|
-
# As of now, idential to the Model's #count method.
|
128
|
-
# This method is explicility defined here to overwrite the default one in Enumerable, which iterates through all the entries to count them
|
129
|
-
def count
|
130
|
-
EasyRedis.zcard(@klass.sort_prefix(@field))
|
131
|
-
end
|
132
|
-
|
133
|
-
# return the fist element of this sort, or the first n elements, if n is given
|
121
|
+
# return the fist element of this collection, or the first n elements, if n is given
|
134
122
|
def first(n = nil)
|
135
123
|
if n
|
136
124
|
self[0,n]
|
@@ -139,6 +127,7 @@ module EasyRedis
|
|
139
127
|
end
|
140
128
|
end
|
141
129
|
|
130
|
+
# return the last element of this collection, or the last n elements, if n is given
|
142
131
|
def last(n = nil)
|
143
132
|
if n
|
144
133
|
self[-n..-1]
|
@@ -147,16 +136,66 @@ module EasyRedis
|
|
147
136
|
end
|
148
137
|
end
|
149
138
|
|
139
|
+
private
|
140
|
+
|
141
|
+
# access the elements corresponding to the given range
|
142
|
+
#
|
143
|
+
# meant to be overridden in child classes
|
144
|
+
def access(range)
|
145
|
+
[]
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
# class representing a sort
|
151
|
+
class Sort < Collection
|
152
|
+
|
153
|
+
# initialize the sort with a specific field, ordering option, and model
|
154
|
+
def initialize(field,order,klass)
|
155
|
+
raise EasyRedis::FieldNotSortable, field unless klass.sortable?(field)
|
156
|
+
raise EasyRedis::UnknownOrderOption, order unless [:asc,:desc].member? order
|
157
|
+
@field = field
|
158
|
+
@order = order
|
159
|
+
@klass = klass
|
160
|
+
end
|
161
|
+
|
162
|
+
# return the number of elements in this sort
|
163
|
+
#
|
164
|
+
# As of now, idential to the Model's count method.
|
165
|
+
# This method is explicility defined here to overwrite the default one in Enumerable, which iterates through all the entries to count them, which is much slower than a ZCARD command
|
166
|
+
def count
|
167
|
+
EasyRedis.zcard(@klass.sort_key(@field))
|
168
|
+
end
|
169
|
+
|
150
170
|
def inspect
|
151
171
|
"#<EasyRedis::Sort model=#{@klass.name}, field=#{@field.to_s}, order=#{@order.to_s}>"
|
152
172
|
end
|
153
173
|
|
174
|
+
private
|
175
|
+
|
176
|
+
# takes a range and returns corresponding elements
|
177
|
+
def access(range)
|
178
|
+
a = range.begin
|
179
|
+
b = range.end
|
180
|
+
b -= 1 if range.exclude_end?
|
181
|
+
ids = []
|
182
|
+
if @order == :asc
|
183
|
+
ids = EasyRedis.redis.zrange(@klass.sort_key(@field),a,b)
|
184
|
+
elsif @order == :desc
|
185
|
+
ids = EasyRedis.redis.zrevrange(@klass.sort_key(@field),a,b)
|
186
|
+
end
|
187
|
+
ids.map{|i|@klass.new(i)}
|
188
|
+
end
|
189
|
+
|
154
190
|
end
|
155
191
|
|
156
192
|
|
157
193
|
# class representing a data model
|
158
194
|
# you want to store in redis
|
159
195
|
class Model
|
196
|
+
|
197
|
+
@@sorts = []
|
198
|
+
@@text_searches = []
|
160
199
|
|
161
200
|
# add a field to the model
|
162
201
|
def self.field(name)
|
@@ -180,22 +219,33 @@ module EasyRedis
|
|
180
219
|
EasyRedis.redis.hset(key_name,name,Marshal.dump(val))
|
181
220
|
instance_variable_set(instance_var,val)
|
182
221
|
|
183
|
-
if
|
184
|
-
|
185
|
-
|
222
|
+
if self.class.sortable? name.to_sym
|
223
|
+
EasyRedis.redis.zadd(sort_key(name),EasyRedis.score(val),@id)
|
224
|
+
end
|
225
|
+
|
226
|
+
if self.class.text_search? name.to_sym
|
227
|
+
val.split.each do |term|
|
228
|
+
EasyRedis.redis.zadd term_key(name,term), created_at.to_i, id
|
229
|
+
EasyRedis.redis.zadd terms_key(name), EasyRedis.score(term), term
|
230
|
+
end
|
186
231
|
end
|
187
232
|
end
|
188
233
|
end
|
189
234
|
|
190
235
|
# index a field to be sorted/searched
|
191
236
|
def self.sort_on(field)
|
192
|
-
@@sorts ||= []
|
193
237
|
@@sorts << field.to_sym
|
194
238
|
end
|
195
239
|
|
240
|
+
# index a field for text searching
|
241
|
+
def self.text_search(field)
|
242
|
+
@@text_searches << field.to_sym
|
243
|
+
sort_on(field) unless sortable? field
|
244
|
+
end
|
245
|
+
|
196
246
|
# returns number of instances of this model
|
197
247
|
def self.count
|
198
|
-
EasyRedis.redis.zcard(prefix
|
248
|
+
EasyRedis.redis.zcard(prefix)
|
199
249
|
end
|
200
250
|
|
201
251
|
# get all instances of this model
|
@@ -204,27 +254,33 @@ module EasyRedis
|
|
204
254
|
self.sort_by :created_at, options
|
205
255
|
end
|
206
256
|
|
257
|
+
# same as all.first
|
207
258
|
def self.first(n = nil)
|
208
259
|
self.all.first(n)
|
209
260
|
end
|
210
261
|
|
262
|
+
# same as all.last
|
211
263
|
def self.last(n = nil)
|
212
264
|
self.all.last(n)
|
213
265
|
end
|
214
266
|
|
267
|
+
# returns a random entry of this model
|
215
268
|
def self.rand
|
216
269
|
self[Kernel.rand(self.count)]
|
217
270
|
end
|
218
271
|
|
219
272
|
# find an instance of this model based on its id
|
220
273
|
def self.find(id)
|
221
|
-
if EasyRedis.redis.zscore(prefix
|
274
|
+
if EasyRedis.redis.zscore(prefix,id)
|
222
275
|
new(id)
|
223
276
|
else
|
224
277
|
nil
|
225
278
|
end
|
226
279
|
end
|
227
280
|
|
281
|
+
# access entries of this model based on time
|
282
|
+
#
|
283
|
+
# same as all.[]
|
228
284
|
def self.[](index,amt=nil)
|
229
285
|
self.all[index,amt]
|
230
286
|
end
|
@@ -234,7 +290,7 @@ module EasyRedis
|
|
234
290
|
raise EasyRedis::FieldNotSortable, field unless @@sorts.member? field.to_sym
|
235
291
|
scr = EasyRedis.score(val)
|
236
292
|
# options[:limit] = [0,options[:limit]] if options[:limit]
|
237
|
-
ids = EasyRedis.redis.zrangebyscore(
|
293
|
+
ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr,proc_options(options))
|
238
294
|
ids.map{|i| new(i) }
|
239
295
|
end
|
240
296
|
|
@@ -243,12 +299,15 @@ module EasyRedis
|
|
243
299
|
search_by(field,val,:limit => 1).first
|
244
300
|
end
|
245
301
|
|
302
|
+
# search the model based on multiple parameters
|
303
|
+
#
|
304
|
+
# takes a hash of field => value pairs
|
246
305
|
def self.search(params)
|
247
306
|
return search_by(*params.first) if params.size == 1 # comment out for benchmarking purposes
|
248
307
|
result_set = nil
|
249
308
|
params.each do |field,value|
|
250
309
|
scr = EasyRedis.score(value)
|
251
|
-
ids = EasyRedis.redis.zrangebyscore(
|
310
|
+
ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr)
|
252
311
|
result_set = result_set ? (result_set & Set.new(ids)) : Set.new(ids)
|
253
312
|
end
|
254
313
|
result_set.map{|i|new(i)}
|
@@ -259,39 +318,42 @@ module EasyRedis
|
|
259
318
|
EasyRedis::Sort.new(field,options[:order],self)
|
260
319
|
end
|
261
320
|
|
262
|
-
# gives all values for the given field that
|
321
|
+
# gives all values for the given field that begin with str
|
263
322
|
#
|
264
|
-
#
|
323
|
+
# The field must have been indexed with text_search.
|
265
324
|
def self.matches(field,str)
|
325
|
+
raise FieldNotTextSearchable, field unless self.text_search? field
|
266
326
|
scr = EasyRedis.score(str)
|
267
327
|
a,b = scr, scr+1/(27.0**str.size)
|
268
|
-
|
269
|
-
s = Set.new
|
270
|
-
ids.each{|i| s << new(i).send(field.to_s) }
|
271
|
-
s.to_a
|
328
|
+
EasyRedis.redis.zrangebyscore(terms_key(field), "#{a}", "(#{b}")
|
272
329
|
end
|
273
330
|
|
274
|
-
# searches for all entries where field
|
331
|
+
# searches for all entries where field contains the string str
|
275
332
|
#
|
276
|
-
#
|
333
|
+
# The string must appear exactly as a term in field's value. To search based on the beginning of a term, you can combine this method with matches.
|
334
|
+
# The field must have been indexed with text_search.
|
277
335
|
def self.match(field,str, options = {})
|
278
|
-
raise EasyRedis::
|
279
|
-
|
280
|
-
a,b = scr, scr+1/(27.0**str.size)
|
281
|
-
ids = EasyRedis.redis.zrangebyscore(sort_prefix(field), "#{a}", "(#{b}", proc_options(options))
|
336
|
+
raise EasyRedis::FieldNotTextSearchable, filename unless text_search? field
|
337
|
+
ids = EasyRedis.redis.zrange(term_key(field,str), 0, -1, proc_options(options))
|
282
338
|
ids.map{|i| new(i)}
|
283
339
|
end
|
284
340
|
|
285
341
|
# indicates whether field has been indexed with sort_on
|
286
342
|
def self.sortable?(field)
|
287
|
-
@@sorts.member? field or field.to_sym == :created_at
|
343
|
+
@@sorts and (@@sorts.member? field or field.to_sym == :created_at)
|
344
|
+
end
|
345
|
+
|
346
|
+
# indicates whether field has been indexed with text_search
|
347
|
+
def self.text_search?(field)
|
348
|
+
@@text_searches and @@text_searches.member?(field)
|
288
349
|
end
|
289
350
|
|
290
351
|
# destroy all instances of this model
|
291
352
|
def self.destroy_all
|
292
353
|
all.each {|x| x.destroy}
|
293
|
-
@@sorts.each {|field| EasyRedis.redis.del(
|
294
|
-
EasyRedis.redis.del(
|
354
|
+
@@sorts.each {|field| EasyRedis.redis.del(sort_key(field)) }
|
355
|
+
@@text_searches.each {|field| EasyRedis.redis.del(terms_key(field)) }
|
356
|
+
EasyRedis.redis.del(prefix)
|
295
357
|
EasyRedis.redis.del(prefix + ":next_id")
|
296
358
|
end
|
297
359
|
|
@@ -303,20 +365,20 @@ module EasyRedis
|
|
303
365
|
#
|
304
366
|
# If no id is passed, one is generated for you.
|
305
367
|
# Otherwise, sets the id field to the passed id, but does not check to see if it is a valid id for this model.
|
306
|
-
# Users should use
|
368
|
+
# Users should use find when retiving models by id, as these check for valid ids.
|
307
369
|
def initialize(id=nil)
|
308
370
|
if id
|
309
371
|
@id = id
|
310
372
|
else
|
311
373
|
@id = EasyRedis.redis.incr(prefix + ':next_id')
|
312
|
-
EasyRedis.redis.zadd(prefix
|
374
|
+
EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
|
313
375
|
@id
|
314
376
|
end
|
315
377
|
end
|
316
378
|
|
317
379
|
# get the creation time of an entry
|
318
380
|
def created_at
|
319
|
-
Time.at(EasyRedis.redis.zscore(prefix
|
381
|
+
Time.at(EasyRedis.redis.zscore(prefix,@id).to_i)
|
320
382
|
end
|
321
383
|
|
322
384
|
# directly access a field of this entry's redis hash
|
@@ -339,7 +401,7 @@ module EasyRedis
|
|
339
401
|
|
340
402
|
# remove the entry
|
341
403
|
def destroy
|
342
|
-
EasyRedis.redis.zrem(prefix
|
404
|
+
EasyRedis.redis.zrem(prefix,@id)
|
343
405
|
EasyRedis.redis.del(key_name)
|
344
406
|
end
|
345
407
|
|
@@ -362,8 +424,9 @@ module EasyRedis
|
|
362
424
|
|
363
425
|
private
|
364
426
|
|
427
|
+
# generate a temporary key name associated with this model
|
365
428
|
def self.get_temp_key
|
366
|
-
i = EasyRedis.redis.incr prefix
|
429
|
+
i = EasyRedis.redis.incr "#{prefix}:next_tmp_id"
|
367
430
|
"#{name}:tmp_#{i}"
|
368
431
|
end
|
369
432
|
|
@@ -377,20 +440,36 @@ module EasyRedis
|
|
377
440
|
self.name.downcase
|
378
441
|
end
|
379
442
|
|
380
|
-
def self.
|
443
|
+
def self.sort_key(field)
|
381
444
|
if field == :created_at
|
382
|
-
prefix
|
445
|
+
prefix
|
383
446
|
else
|
384
|
-
prefix
|
447
|
+
"#{prefix}:sort_#{field.to_s}"
|
385
448
|
end
|
386
449
|
end
|
387
450
|
|
451
|
+
def self.terms_key(field)
|
452
|
+
"#{prefix}:terms_#{field.to_s}"
|
453
|
+
end
|
454
|
+
|
455
|
+
def self.term_key(field,term)
|
456
|
+
"#{prefix}:term_#{field}:#{term}"
|
457
|
+
end
|
458
|
+
|
388
459
|
def prefix
|
389
460
|
self.class.prefix
|
390
461
|
end
|
391
462
|
|
392
|
-
def
|
393
|
-
self.class.
|
463
|
+
def sort_key(field)
|
464
|
+
self.class.sort_key(field)
|
465
|
+
end
|
466
|
+
|
467
|
+
def terms_key(field)
|
468
|
+
self.class.terms_key(field)
|
469
|
+
end
|
470
|
+
|
471
|
+
def term_key(field,term)
|
472
|
+
self.class.term_key(field,term)
|
394
473
|
end
|
395
474
|
end
|
396
475
|
end
|
data/tests/test.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: easyredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Alec Benzer
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-02-
|
13
|
+
date: 2011-02-07 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,17 +24,6 @@ dependencies:
|
|
24
24
|
version: 2.1.1
|
25
25
|
type: :development
|
26
26
|
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: activesupport
|
29
|
-
prerelease: false
|
30
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
-
none: false
|
32
|
-
requirements:
|
33
|
-
- - ">="
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: 3.0.0
|
36
|
-
type: :development
|
37
|
-
version_requirements: *id002
|
38
27
|
description: simple framework designed to make using redis as a database simpler
|
39
28
|
email: alecbezer @nospam@ gmail.com
|
40
29
|
executables: []
|