easyredis 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|