easyredis 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/Manifest +2 -0
- data/README.md +12 -2
- data/Rakefile +2 -2
- data/easyredis.gemspec +6 -6
- data/lib/easyredis.rb +63 -22
- metadata +7 -5
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011 by Alec Benzer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/Manifest
CHANGED
data/README.md
CHANGED
@@ -46,14 +46,24 @@ We can now make post objects:
|
|
46
46
|
Posts are automatically given ids that we can then use to retrive them:
|
47
47
|
|
48
48
|
id = p.id
|
49
|
-
|
50
|
-
|
49
|
+
p2 = Post.find(id)
|
50
|
+
p2.title # => "My First Post"
|
51
|
+
|
52
|
+
Or, we can choose our own ids:
|
53
|
+
|
54
|
+
p = Post.new("coolpost")
|
55
|
+
p.title = "A Cool Post"
|
56
|
+
p.body = "This post has a high level of coolnes."
|
57
|
+
|
58
|
+
p2 = Post.find("coolpost") # this is a very fast lookup
|
59
|
+
p2.title # => "A Cool Post"
|
51
60
|
|
52
61
|
We also get a created_at field for free that we can sort by.
|
53
62
|
|
54
63
|
p.created_at # a ruby Time object
|
55
64
|
Post.all # get all posts, ordered by creation time
|
56
65
|
Post.all :order => :desc # specifying an order option
|
66
|
+
Post[41] # the 42nd (0-based indexing) post that was created
|
57
67
|
|
58
68
|
## Searching and Sorting
|
59
69
|
|
data/Rakefile
CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('easyredis','0.0.
|
6
|
-
p.description = "
|
5
|
+
Echoe.new('easyredis','0.0.5') do |p|
|
6
|
+
p.description = "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"
|
data/easyredis.gemspec
CHANGED
@@ -2,21 +2,21 @@
|
|
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.5"
|
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-
|
10
|
-
s.description = %q{
|
9
|
+
s.date = %q{2011-02-09}
|
10
|
+
s.description = %q{framework designed to make using redis as a database simpler}
|
11
11
|
s.email = %q{alecbezer @nospam@ gmail.com}
|
12
|
-
s.extra_rdoc_files = ["README.md", "lib/easyredis.rb"]
|
13
|
-
s.files = ["Manifest", "README.md", "Rakefile", "lib/easyredis.rb", "tests/benchmark.rb", "tests/test.rb"
|
12
|
+
s.extra_rdoc_files = ["LICENSE", "README.md", "lib/easyredis.rb"]
|
13
|
+
s.files = ["LICENSE", "Manifest", "README.md", "Rakefile", "easyredis.gemspec", "lib/easyredis.rb", "tests/benchmark.rb", "tests/test.rb"]
|
14
14
|
s.homepage = %q{https://github.com/alecbenzer/easyredis}
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Easyredis", "--main", "README.md"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{easyredis}
|
18
18
|
s.rubygems_version = %q{1.5.0}
|
19
|
-
s.summary = %q{
|
19
|
+
s.summary = %q{framework designed to make using redis as a database simpler}
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
22
|
s.specification_version = 3
|
data/lib/easyredis.rb
CHANGED
@@ -18,6 +18,9 @@ module EasyRedis
|
|
18
18
|
#
|
19
19
|
# This method effectively turns a string into a base 27 floating point number,
|
20
20
|
# where 0 corresponds to no letter, 1 to A, 2 to B, etc.
|
21
|
+
#
|
22
|
+
# @param [String] str the string we are computing a score for
|
23
|
+
# @return [Number] the string's score
|
21
24
|
def self.string_score(str)
|
22
25
|
str = str.downcase
|
23
26
|
mult = 1.0
|
@@ -32,9 +35,12 @@ module EasyRedis
|
|
32
35
|
# gets a score for a generic object
|
33
36
|
#
|
34
37
|
# The score is determined as follows:
|
35
|
-
# First, if the object is a string, string_score is used to get its score.
|
38
|
+
# First, if the object is a string, {string_score} is used to get its score.
|
36
39
|
# Otherwise, we try calling the following methods on the object in turn, returning the first that works: score, to_f, to_i.
|
37
40
|
# If none of those work, we simply return the object itself.
|
41
|
+
#
|
42
|
+
# @param obj the object to retrive a score for
|
43
|
+
# @return [Number] the object's score
|
38
44
|
def self.score(obj)
|
39
45
|
if obj.is_a? String
|
40
46
|
string_score(obj)
|
@@ -50,6 +56,7 @@ module EasyRedis
|
|
50
56
|
end
|
51
57
|
|
52
58
|
# access the redis object
|
59
|
+
# @return [Redis]
|
53
60
|
def self.redis
|
54
61
|
@redis
|
55
62
|
end
|
@@ -57,6 +64,8 @@ module EasyRedis
|
|
57
64
|
# connect to a redis server
|
58
65
|
#
|
59
66
|
# takes the same options that Redis#new does from the redis gem
|
67
|
+
#
|
68
|
+
# @param [Hash] options a hash of options to feed to Redis.new
|
60
69
|
def self.connect(options = {})
|
61
70
|
@redis = Redis.new(options)
|
62
71
|
end
|
@@ -102,6 +111,12 @@ module EasyRedis
|
|
102
111
|
#
|
103
112
|
# Work's like an Array's [] method. It can take a specific index, a range, or an offset and an amount/limit.
|
104
113
|
# This method uses the underlying access method, which handles the actual retrival.
|
114
|
+
#
|
115
|
+
# @param [Range, Number] index either a number corresponding to a specific element,
|
116
|
+
# a range corresponding to a range of elements,
|
117
|
+
# or a number indicating an offset, if limit is also specified
|
118
|
+
#
|
119
|
+
# @param [Number] limit index is interpreted as an offset and limit is the number of elements to return from that offset
|
105
120
|
def [](index,limit=nil)
|
106
121
|
if limit
|
107
122
|
offset = index
|
@@ -151,6 +166,10 @@ module EasyRedis
|
|
151
166
|
class Sort < Collection
|
152
167
|
|
153
168
|
# initialize the sort with a specific field, ordering option, and model
|
169
|
+
#
|
170
|
+
# @param [Symbol] field a symbol corresponding to a field of klass
|
171
|
+
# @param [:asc, :desc] order a symbol specifying to sort in either ascending or descending order
|
172
|
+
# @param [Class] klass the klass whose entries we are accessing
|
154
173
|
def initialize(field,order,klass)
|
155
174
|
raise EasyRedis::FieldNotSortable, field unless klass.sortable?(field)
|
156
175
|
raise EasyRedis::UnknownOrderOption, order unless [:asc,:desc].member? order
|
@@ -164,7 +183,8 @@ module EasyRedis
|
|
164
183
|
# As of now, idential to the Model's count method.
|
165
184
|
# 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
185
|
def count
|
167
|
-
EasyRedis.zcard(@klass.sort_key(@field))
|
186
|
+
@count ||= EasyRedis.redis.zcard(@klass.sort_key(@field))
|
187
|
+
@count
|
168
188
|
end
|
169
189
|
|
170
190
|
def inspect
|
@@ -184,7 +204,7 @@ module EasyRedis
|
|
184
204
|
elsif @order == :desc
|
185
205
|
ids = EasyRedis.redis.zrevrange(@klass.sort_key(@field),a,b)
|
186
206
|
end
|
187
|
-
ids.map{|i|@klass.
|
207
|
+
ids.map{|i|@klass.build(i)}
|
188
208
|
end
|
189
209
|
|
190
210
|
end
|
@@ -198,6 +218,8 @@ module EasyRedis
|
|
198
218
|
@@text_searches = []
|
199
219
|
|
200
220
|
# add a field to the model
|
221
|
+
#
|
222
|
+
# @param [Symbol] name a symbol representing the name of the field
|
201
223
|
def self.field(name)
|
202
224
|
@@fields ||= []
|
203
225
|
@@fields << name.to_sym
|
@@ -233,11 +255,15 @@ module EasyRedis
|
|
233
255
|
end
|
234
256
|
|
235
257
|
# index a field to be sorted/searched
|
258
|
+
#
|
259
|
+
# @param (see #field)
|
236
260
|
def self.sort_on(field)
|
237
261
|
@@sorts << field.to_sym
|
238
262
|
end
|
239
263
|
|
240
264
|
# index a field for text searching
|
265
|
+
#
|
266
|
+
# @param (see #field)
|
241
267
|
def self.text_search(field)
|
242
268
|
@@text_searches << field.to_sym
|
243
269
|
sort_on(field) unless sortable? field
|
@@ -254,12 +280,12 @@ module EasyRedis
|
|
254
280
|
self.sort_by :created_at, options
|
255
281
|
end
|
256
282
|
|
257
|
-
# same as all.first
|
283
|
+
# same as calling self.all.first
|
258
284
|
def self.first(n = nil)
|
259
285
|
self.all.first(n)
|
260
286
|
end
|
261
287
|
|
262
|
-
# same as all.last
|
288
|
+
# same as calling self.all.last
|
263
289
|
def self.last(n = nil)
|
264
290
|
self.all.last(n)
|
265
291
|
end
|
@@ -269,10 +295,12 @@ module EasyRedis
|
|
269
295
|
self[Kernel.rand(self.count)]
|
270
296
|
end
|
271
297
|
|
272
|
-
# find an
|
298
|
+
# find an entry of this model based on its id
|
299
|
+
#
|
300
|
+
# @param [Integer] id the id of the entry to retrive
|
273
301
|
def self.find(id)
|
274
302
|
if EasyRedis.redis.zscore(prefix,id)
|
275
|
-
|
303
|
+
build(id)
|
276
304
|
else
|
277
305
|
nil
|
278
306
|
end
|
@@ -280,28 +308,33 @@ module EasyRedis
|
|
280
308
|
|
281
309
|
# access entries of this model based on time
|
282
310
|
#
|
283
|
-
# same as all.[]
|
311
|
+
# same as calling self.all.[]
|
284
312
|
def self.[](index,amt=nil)
|
285
313
|
self.all[index,amt]
|
286
314
|
end
|
287
315
|
|
288
316
|
# get all entries where field matches val
|
317
|
+
#
|
318
|
+
# @param [Symbol] field a symbol representing the field to search on
|
319
|
+
# @param val the value of field to search for
|
289
320
|
def self.search_by(field, val, options = {})
|
290
321
|
raise EasyRedis::FieldNotSortable, field unless @@sorts.member? field.to_sym
|
291
322
|
scr = EasyRedis.score(val)
|
292
323
|
# options[:limit] = [0,options[:limit]] if options[:limit]
|
293
324
|
ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr,proc_options(options))
|
294
|
-
ids.map{|i|
|
325
|
+
ids.map{|i| build(i) }
|
295
326
|
end
|
296
327
|
|
297
328
|
# get the first entry where field matches val
|
329
|
+
#
|
330
|
+
# @param (see #search_by)
|
298
331
|
def self.find_by(field,val)
|
299
332
|
search_by(field,val,:limit => 1).first
|
300
333
|
end
|
301
334
|
|
302
335
|
# search the model based on multiple parameters
|
303
336
|
#
|
304
|
-
#
|
337
|
+
# @param [Hash] params a hash of field => value pairs
|
305
338
|
def self.search(params)
|
306
339
|
return search_by(*params.first) if params.size == 1 # comment out for benchmarking purposes
|
307
340
|
result_set = nil
|
@@ -310,7 +343,7 @@ module EasyRedis
|
|
310
343
|
ids = EasyRedis.redis.zrangebyscore(sort_key(field),scr,scr)
|
311
344
|
result_set = result_set ? (result_set & Set.new(ids)) : Set.new(ids)
|
312
345
|
end
|
313
|
-
result_set.map{|i|
|
346
|
+
result_set.map{|i|build(i)}
|
314
347
|
end
|
315
348
|
|
316
349
|
# get all entries, sorted by the given field
|
@@ -320,7 +353,7 @@ module EasyRedis
|
|
320
353
|
|
321
354
|
# gives all values for the given field that begin with str
|
322
355
|
#
|
323
|
-
#
|
356
|
+
# @param [Symbol] field a symbol representing a field indexed with text_search.
|
324
357
|
def self.matches(field,str)
|
325
358
|
raise FieldNotTextSearchable, field unless self.text_search? field
|
326
359
|
scr = EasyRedis.score(str)
|
@@ -335,7 +368,7 @@ module EasyRedis
|
|
335
368
|
def self.match(field,str, options = {})
|
336
369
|
raise EasyRedis::FieldNotTextSearchable, filename unless text_search? field
|
337
370
|
ids = EasyRedis.redis.zrange(term_key(field,str), 0, -1, proc_options(options))
|
338
|
-
ids.map{|i|
|
371
|
+
ids.map{|i| build(i)}
|
339
372
|
end
|
340
373
|
|
341
374
|
# indicates whether field has been indexed with sort_on
|
@@ -356,23 +389,27 @@ module EasyRedis
|
|
356
389
|
EasyRedis.redis.del(prefix)
|
357
390
|
EasyRedis.redis.del(prefix + ":next_id")
|
358
391
|
end
|
359
|
-
|
392
|
+
|
360
393
|
|
361
394
|
# the id of this entry
|
362
395
|
attr_reader :id
|
363
396
|
|
364
397
|
# create a new instance of this model
|
365
398
|
#
|
366
|
-
#
|
367
|
-
#
|
368
|
-
#
|
369
|
-
|
399
|
+
# @param [String] id optional id to use for the entry
|
400
|
+
# if you leave this parameter out an id will be generated for you
|
401
|
+
# @param [Boolean] check this flag is used for internal purposes.
|
402
|
+
# LEAVE IT AS TRUE
|
403
|
+
def initialize(id=nil,check=true)
|
370
404
|
if id
|
371
|
-
@id = id
|
405
|
+
@id = id.to_s
|
406
|
+
if check
|
407
|
+
raise "id #{id} is already in use" if EasyRedis.redis.zscore(prefix,id)
|
408
|
+
EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
|
409
|
+
end
|
372
410
|
else
|
373
|
-
@id = EasyRedis.redis.incr(prefix + ':next_id')
|
411
|
+
@id = EasyRedis.redis.incr(prefix + ':next_id').to_s
|
374
412
|
EasyRedis.redis.zadd(prefix,Time.now.to_i,@id)
|
375
|
-
@id
|
376
413
|
end
|
377
414
|
end
|
378
415
|
|
@@ -407,7 +444,7 @@ module EasyRedis
|
|
407
444
|
|
408
445
|
# returns the key name of this entry's redis hash
|
409
446
|
def key_name
|
410
|
-
prefix
|
447
|
+
"#{prefix}:#{@id}"
|
411
448
|
end
|
412
449
|
|
413
450
|
def inspect
|
@@ -424,6 +461,10 @@ module EasyRedis
|
|
424
461
|
|
425
462
|
private
|
426
463
|
|
464
|
+
def self.build(id)
|
465
|
+
new(id,false)
|
466
|
+
end
|
467
|
+
|
427
468
|
# generate a temporary key name associated with this model
|
428
469
|
def self.get_temp_key
|
429
470
|
i = EasyRedis.redis.incr "#{prefix}:next_tmp_id"
|
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.5
|
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-09 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,23 +24,25 @@ dependencies:
|
|
24
24
|
version: 2.1.1
|
25
25
|
type: :development
|
26
26
|
version_requirements: *id001
|
27
|
-
description:
|
27
|
+
description: framework designed to make using redis as a database simpler
|
28
28
|
email: alecbezer @nospam@ gmail.com
|
29
29
|
executables: []
|
30
30
|
|
31
31
|
extensions: []
|
32
32
|
|
33
33
|
extra_rdoc_files:
|
34
|
+
- LICENSE
|
34
35
|
- README.md
|
35
36
|
- lib/easyredis.rb
|
36
37
|
files:
|
38
|
+
- LICENSE
|
37
39
|
- Manifest
|
38
40
|
- README.md
|
39
41
|
- Rakefile
|
42
|
+
- easyredis.gemspec
|
40
43
|
- lib/easyredis.rb
|
41
44
|
- tests/benchmark.rb
|
42
45
|
- tests/test.rb
|
43
|
-
- easyredis.gemspec
|
44
46
|
has_rdoc: true
|
45
47
|
homepage: https://github.com/alecbenzer/easyredis
|
46
48
|
licenses: []
|
@@ -73,6 +75,6 @@ rubyforge_project: easyredis
|
|
73
75
|
rubygems_version: 1.5.0
|
74
76
|
signing_key:
|
75
77
|
specification_version: 3
|
76
|
-
summary:
|
78
|
+
summary: framework designed to make using redis as a database simpler
|
77
79
|
test_files: []
|
78
80
|
|