easyredis 0.0.4 → 0.0.5
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/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
|
|