easyredis 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +6 -0
- data/README.md +73 -0
- data/Rakefile +100 -0
- data/easyredis.gemspec +35 -0
- data/lib/easyredis.rb +348 -0
- data/tests/benchmark.rb +44 -0
- data/tests/test.rb +10 -0
- metadata +89 -0
data/Manifest
ADDED
data/README.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# EasyRedis
|
2
|
+
|
3
|
+
EasyRedis is a simple ruby framework designed to make using Redis as a database simpler.
|
4
|
+
|
5
|
+
Redis is a very fast key-value store that supports data structures like lists, (sorted) sets, and hashes, but because of its simplicity, using Redis to store traditional database data can be somewhat tedious. EasyRedis streamlines this process.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
You can get the source with git:
|
10
|
+
|
11
|
+
$ git clone git://github.com/alecbenzer/easyredis.git
|
12
|
+
|
13
|
+
or just download and extract a tar archive with the Downloads button.
|
14
|
+
|
15
|
+
Once you have the source, run:
|
16
|
+
|
17
|
+
$ rake
|
18
|
+
$ gem install pkg/easyredis-x.x.x.gem
|
19
|
+
|
20
|
+
Where x.x.x is the current version number.
|
21
|
+
|
22
|
+
## Basics
|
23
|
+
|
24
|
+
First, create a simple model:
|
25
|
+
|
26
|
+
require 'easyredis'
|
27
|
+
|
28
|
+
class Post < EasyRedis::Model
|
29
|
+
field :title
|
30
|
+
field :body
|
31
|
+
end
|
32
|
+
|
33
|
+
EasyRedis.connect
|
34
|
+
|
35
|
+
This creates a Post model and connects to a redis server running on localhost on the default port (you can pass options to EasyRedis.connect like you would to Redis.new)
|
36
|
+
|
37
|
+
We can now make post objects:
|
38
|
+
|
39
|
+
p = Post.new
|
40
|
+
p.title = "My First Post"
|
41
|
+
p.body = "This is my very first post!"
|
42
|
+
|
43
|
+
Posts are automatically given ids that we can then use to retrive them:
|
44
|
+
|
45
|
+
id = p.id
|
46
|
+
p = Post[id] # or Post.find(id)
|
47
|
+
p.title # => "My First Post"
|
48
|
+
|
49
|
+
We also get a created_at field for free that we can sort by.
|
50
|
+
|
51
|
+
p.created_at # a ruby Time object
|
52
|
+
Post.all # get all posts, ordered by creation time
|
53
|
+
Post.all :order => :desc # specifying an order option
|
54
|
+
|
55
|
+
## Searching and Sorting
|
56
|
+
|
57
|
+
We can also tell EasyRedis to optimize sorting and searching on certain fields. If we had defined Post as:
|
58
|
+
|
59
|
+
class Post < EasyRedis::Model
|
60
|
+
field :title
|
61
|
+
field :body
|
62
|
+
|
63
|
+
sort_on :title
|
64
|
+
end
|
65
|
+
|
66
|
+
We can now sort our posts by title:
|
67
|
+
|
68
|
+
Post.sort_by :title, :order => :desc
|
69
|
+
|
70
|
+
And also search:
|
71
|
+
|
72
|
+
Post.search_by(:title,"A common title") # all posts with this title
|
73
|
+
Post.find_by(:title,"My First Post") # just one post
|
data/Rakefile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
# spec = Gem::Specification.new do |s|
|
6
|
+
# s.platform = Gem::Platform::RUBY
|
7
|
+
# s.name = "easyredis"
|
8
|
+
# s.version = "0.0.1"
|
9
|
+
# s.author = "Alec Benzer"
|
10
|
+
# s.email = "alecbenzer@gmail.com"
|
11
|
+
# s.homepage = "https://github.com/alecbenzer/easyredis"
|
12
|
+
# s.summary = "simple framework designed to make using redis as a database simpler"
|
13
|
+
# s.files = FileList['lib/*.rb','test/*'].to_a
|
14
|
+
# s.require_path = "lib"
|
15
|
+
# s.test_files = Dir.glob('tests/*.rb')
|
16
|
+
# s.has_rdoc = true
|
17
|
+
# s.add_dependency("redis")
|
18
|
+
# s.add_dependency("activesupport")
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Rake::GemPackageTask.new(spec) do |pkg|
|
22
|
+
# pkg.need_tar = true
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
|
26
|
+
# puts "generated latest version"
|
27
|
+
# end
|
28
|
+
|
29
|
+
Echoe.new('easyredis','0.0.1') do |p|
|
30
|
+
p.description = "simple framework designed to make using redis as a database simpler"
|
31
|
+
p.url = "https://github.com/alecbenzer/easyredis"
|
32
|
+
p.author = "Alec Benzer"
|
33
|
+
p.email = "alecbezer @nospam@ gmail.com"
|
34
|
+
p.ignore_pattern = ["*.rdb"]
|
35
|
+
p.development_dependencies = ["redis","activesupport"]
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
require 'benchmark'
|
40
|
+
require './tests/test'
|
41
|
+
|
42
|
+
$names = ["Bill","Bob","John","Jack","Alec","Mark","Nick","Evan","Eamon","Joe","Vikram"]
|
43
|
+
|
44
|
+
def rand_name
|
45
|
+
$names[rand*$names.size]
|
46
|
+
end
|
47
|
+
|
48
|
+
namespace :bm do
|
49
|
+
task :clear do
|
50
|
+
count = Man.count
|
51
|
+
|
52
|
+
puts "destroying #{$count} previous entries"
|
53
|
+
Benchmark.bm do |bm|
|
54
|
+
bm.report { Man.destroy_all }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
task :add do
|
59
|
+
count = ENV["count"] ? ENV["count"].to_i : 25000
|
60
|
+
puts "adding #{count} new entries"
|
61
|
+
Benchmark.bm do |bm|
|
62
|
+
bm.report { count.times { m = Man.new ; m.name = rand_name } }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
task :populate => [:clear, :add]
|
67
|
+
|
68
|
+
task :sort do
|
69
|
+
puts "sorting #{Man.count} entries by name"
|
70
|
+
Benchmark.bm do |bm|
|
71
|
+
#bm.report("ruby:") { Man.all.sort_by { |m| m.name } }
|
72
|
+
#bm.report("redis:") { Man.sort_by(:name) }
|
73
|
+
bm.report { Man.sort_by(:name) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
task :search do
|
78
|
+
puts "searching #{Man.count} entries by a particular name"
|
79
|
+
Benchmark.bm do |bm|
|
80
|
+
name = rand_name
|
81
|
+
#bm.report("ruby:") { Man.all.select {|m| m.name == name} }
|
82
|
+
#bm.report("redis:") { Man.search_by(:name,name) }
|
83
|
+
bm.report { Man.search_by(:name,name) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
task :find do
|
88
|
+
puts "finding one of #{Man.count} entry by name"
|
89
|
+
Benchmark.bm do |bm|
|
90
|
+
name = rand_name
|
91
|
+
#bm.report("redis:") { Man.find_by(:name,name) }
|
92
|
+
bm.report { Man.find_by(:name,name) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
task :doc do
|
99
|
+
puts `rdoc lib/ --title "EasyRedis"`
|
100
|
+
end
|
data/easyredis.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{easyredis}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Alec Benzer"]
|
9
|
+
s.date = %q{2011-02-05}
|
10
|
+
s.description = %q{simple framework designed to make using redis as a database simpler}
|
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", "easyredis.gemspec"]
|
14
|
+
s.homepage = %q{https://github.com/alecbenzer/easyredis}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Easyredis", "--main", "README.md"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{easyredis}
|
18
|
+
s.rubygems_version = %q{1.5.0}
|
19
|
+
s.summary = %q{simple framework designed to make using redis as a database simpler}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
s.specification_version = 3
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
+
s.add_development_dependency(%q<redis>, [">= 0"])
|
26
|
+
s.add_development_dependency(%q<activesupport>, [">= 0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
29
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
33
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
34
|
+
end
|
35
|
+
end
|
data/lib/easyredis.rb
ADDED
@@ -0,0 +1,348 @@
|
|
1
|
+
# EasyRedis is a simple ruby framework designed to make using Redis as a database simpler.
|
2
|
+
#
|
3
|
+
# Redis is a very fast key-value store that supports data structures like lists, (sorted) sets, and hashes, but because of its simplicity, using Redis to store traditional database data can be somewhat tedious. EasyRedis streamlines this process.
|
4
|
+
#
|
5
|
+
# Author:: Alec Benzer (mailto:alecbenzer@gmail.com)
|
6
|
+
|
7
|
+
|
8
|
+
require 'redis'
|
9
|
+
require 'set'
|
10
|
+
require 'active_support/inflector'
|
11
|
+
|
12
|
+
|
13
|
+
# main EasyRedis module which
|
14
|
+
# holds all classes and helper methods
|
15
|
+
module EasyRedis
|
16
|
+
|
17
|
+
# generate a 'score' for a string
|
18
|
+
# used for storing it in a sorted set
|
19
|
+
def self.string_score(str)
|
20
|
+
str = str.downcase
|
21
|
+
mult = 1.0
|
22
|
+
scr = 0.0
|
23
|
+
str.each_byte do |b|
|
24
|
+
mult /= 27
|
25
|
+
scr += (b-'a'.ord+1)*mult
|
26
|
+
end
|
27
|
+
scr
|
28
|
+
end
|
29
|
+
|
30
|
+
# gets a score for a generic object
|
31
|
+
#
|
32
|
+
# Uses EasyRedis#string_score if the object is a string,
|
33
|
+
# and just returns the object otherwise (presumably its a number)
|
34
|
+
def self.score(obj)
|
35
|
+
if obj.is_a? String
|
36
|
+
string_score(obj)
|
37
|
+
else
|
38
|
+
obj
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# access the redis object
|
43
|
+
def self.redis
|
44
|
+
@redis
|
45
|
+
end
|
46
|
+
|
47
|
+
# connect to a redis server
|
48
|
+
def self.connect(options = {})
|
49
|
+
@redis = Redis.new(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# exception that indicates that the given field has not been indexed for sorting/searching
|
53
|
+
class FieldNotSortable < RuntimeError
|
54
|
+
def initialize(field)
|
55
|
+
@message = "field '#{field.to_s}' not sortable"
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
@message
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# exception that indicated an unknown ordering option was encountered
|
64
|
+
class UnknownOrderOption < RuntimeError
|
65
|
+
def initialize(opt)
|
66
|
+
@message = "unknown order option '#{opt}'"
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
@message
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# class representing a sort
|
75
|
+
class Sort
|
76
|
+
include Enumerable
|
77
|
+
|
78
|
+
# initialize the sort with a specific field, ordering option, and model
|
79
|
+
def initialize(field,order,klass)
|
80
|
+
raise EasyRedis::FieldNotSortable, field unless klass.sortable?(field)
|
81
|
+
raise EasyRedis::UnknownOrderOption, order unless [:asc,:desc].member? order
|
82
|
+
@field = field
|
83
|
+
@order = order
|
84
|
+
@klass = klass
|
85
|
+
end
|
86
|
+
|
87
|
+
# access elements in this sort
|
88
|
+
#
|
89
|
+
# Work's like ruby's Array#[]. It can take a specific index, a range, or an offset, amount pair.
|
90
|
+
# Calling this method will actually query the redis server for ids
|
91
|
+
def [](index,limit=nil)
|
92
|
+
if limit
|
93
|
+
offset = index
|
94
|
+
self[offset...(offset+limit)]
|
95
|
+
elsif index.is_a? Range
|
96
|
+
a = index.begin
|
97
|
+
b = index.end
|
98
|
+
b -= 1 if index.exclude_end?
|
99
|
+
ids = []
|
100
|
+
if @order == :asc
|
101
|
+
ids = EasyRedis.redis.zrange(@klass.sort_prefix(@field),a,b)
|
102
|
+
elsif @order == :desc
|
103
|
+
ids = EasyRedis.redis.zrevrange(@klass.sort_prefix(@field),a,b)
|
104
|
+
end
|
105
|
+
ids.map{|i|@klass.new(i)}
|
106
|
+
elsif index.is_a? Integer
|
107
|
+
self[index..index].first
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# iterate through all members of this sort
|
112
|
+
def each
|
113
|
+
self[0..-1].each { |o| yield o }
|
114
|
+
end
|
115
|
+
|
116
|
+
# return the number of elements in this sort
|
117
|
+
#
|
118
|
+
# As of now, idential to the Model's #count method.
|
119
|
+
# This method is explicility defined here to overwrite the default one in Enumerable, which iterates through all the entries to count them
|
120
|
+
def count
|
121
|
+
EasyRedis.zcard(@klass.sort_prefix(@field))
|
122
|
+
end
|
123
|
+
|
124
|
+
# return the fist element of this sort, or the first n elements, if n is given
|
125
|
+
def first(n = nil)
|
126
|
+
if n
|
127
|
+
self[0,n]
|
128
|
+
else
|
129
|
+
self[0]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def inspect
|
134
|
+
"#<EasyRedis::Sort model=#{@klass.name}, field=#{@field.to_s}, order=#{@order.to_s}>"
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# class representing a data model
|
141
|
+
# you want to store in redis
|
142
|
+
class Model
|
143
|
+
|
144
|
+
# add a field to the model
|
145
|
+
def self.field(name)
|
146
|
+
name = name.to_s
|
147
|
+
getter = name
|
148
|
+
setter = name + "="
|
149
|
+
instance_var = '@' + name
|
150
|
+
|
151
|
+
define_method getter.to_sym do
|
152
|
+
prev = instance_variable_get(instance_var)
|
153
|
+
if prev
|
154
|
+
prev
|
155
|
+
else
|
156
|
+
instance_variable_set(instance_var,Marshal.load(EasyRedis.redis.hget(key_name,name)))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
define_method setter.to_sym do |val|
|
161
|
+
EasyRedis.redis.hset(key_name,name,Marshal.dump(val))
|
162
|
+
instance_variable_set(instance_var,val)
|
163
|
+
|
164
|
+
if @@sorts.member? name.to_sym
|
165
|
+
# score = val.is_a?(String) ? EasyRedis.string_score(val) : val
|
166
|
+
EasyRedis.redis.zadd(sort_prefix(name),EasyRedis.score(val),@id)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# index a field to be sorted/searched
|
172
|
+
def self.sort_on(field)
|
173
|
+
@@sorts ||= []
|
174
|
+
@@sorts << field.to_sym
|
175
|
+
end
|
176
|
+
|
177
|
+
# returns number of instances of this model
|
178
|
+
def self.count
|
179
|
+
EasyRedis.redis.zcard(prefix.pluralize)
|
180
|
+
end
|
181
|
+
|
182
|
+
# get all instances of this model
|
183
|
+
# ordered by creation time
|
184
|
+
def self.all(options = {:order => :asc})
|
185
|
+
self.sort_by :created_at, options
|
186
|
+
end
|
187
|
+
|
188
|
+
# find an instance of this model based on its id
|
189
|
+
def self.find(id)
|
190
|
+
if EasyRedis.redis.zscore(prefix.pluralize,id)
|
191
|
+
new(id)
|
192
|
+
else
|
193
|
+
nil
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# alias for Model#find
|
198
|
+
def self.[](id)
|
199
|
+
find(id)
|
200
|
+
end
|
201
|
+
|
202
|
+
# get all entries where field matches val
|
203
|
+
def self.search_by(field, val, options = {})
|
204
|
+
raise EasyRedis::FieldNotSortable, field unless @@sorts.member? field.to_sym
|
205
|
+
scr = EasyRedis.score(val)
|
206
|
+
# options[:limit] = [0,options[:limit]] if options[:limit]
|
207
|
+
ids = EasyRedis.redis.zrangebyscore(sort_prefix(field),scr,scr,proc_options(options))
|
208
|
+
ids.map{|i| new(i) }
|
209
|
+
end
|
210
|
+
|
211
|
+
# get the first entry where field matches val
|
212
|
+
def self.find_by(field,val)
|
213
|
+
search_by(field,val,:limit => 1).first
|
214
|
+
end
|
215
|
+
|
216
|
+
# get all entries, sorted by the given field
|
217
|
+
def self.sort_by(field,options = {:order => :asc})
|
218
|
+
EasyRedis::Sort.new(field,options[:order],self)
|
219
|
+
end
|
220
|
+
|
221
|
+
# gives all values for the given field that begins with str
|
222
|
+
#
|
223
|
+
# This method is currently iterates through all existing entries. It is therefore very slow and should probably not be used at this time.
|
224
|
+
def self.matches(field,str)
|
225
|
+
scr = EasyRedis.score(str)
|
226
|
+
a,b = scr, scr+1/(27.0**str.size)
|
227
|
+
ids = EasyRedis.redis.zrangebyscore(sort_prefix(field), "#{a}", "(#{b}")
|
228
|
+
s = Set.new
|
229
|
+
ids.each{|i| s << new(i).send(field.to_s) }
|
230
|
+
s.to_a
|
231
|
+
end
|
232
|
+
|
233
|
+
# searches for all entries where field begins with str
|
234
|
+
#
|
235
|
+
# works with string fields that have been indexed with sort_on
|
236
|
+
def self.match(field,str, options = {})
|
237
|
+
raise EasyRedis::FieldNotSortable, filename unless @@sorts.member? field
|
238
|
+
scr = EasyRedis.score(str)
|
239
|
+
a,b = scr, scr+1/(27.0**str.size)
|
240
|
+
ids = EasyRedis.redis.zrangebyscore(sort_prefix(field), "#{a}", "(#{b}", proc_options(options))
|
241
|
+
ids.map{|i| new(i)}
|
242
|
+
end
|
243
|
+
|
244
|
+
# indicates whether field has been indexed with sort_on
|
245
|
+
def self.sortable?(field)
|
246
|
+
@@sorts.member? field or field.to_sym == :created_at
|
247
|
+
end
|
248
|
+
|
249
|
+
# destroy all instances of this model
|
250
|
+
def self.destroy_all
|
251
|
+
all.each {|x| x.destroy}
|
252
|
+
@@sorts.each {|field| EasyRedis.redis.del(sort_prefix(field)) }
|
253
|
+
EasyRedis.redis.del(prefix.pluralize)
|
254
|
+
EasyRedis.redis.del(prefix + ":next_id")
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
# the id of this entry
|
259
|
+
attr_reader :id
|
260
|
+
|
261
|
+
# create a new instance of this model
|
262
|
+
#
|
263
|
+
# If no id is passed, one is generated for you.
|
264
|
+
# Otherwise, sets the id field to the passed id, but does not check to see if it is a valid id for this model.
|
265
|
+
# Users should use Model#find or Model#[] when retiving models by id, as these check for valid ids.
|
266
|
+
def initialize(id=nil)
|
267
|
+
if id
|
268
|
+
@id = id
|
269
|
+
else
|
270
|
+
@id = EasyRedis.redis.incr(prefix + ':next_id')
|
271
|
+
EasyRedis.redis.zadd(prefix.pluralize,Time.now.to_i,@id)
|
272
|
+
@id
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# get the creation time of an entry
|
277
|
+
def created_at
|
278
|
+
Time.at(EasyRedis.redis.zscore(prefix.pluralize,@id).to_i)
|
279
|
+
end
|
280
|
+
|
281
|
+
# directly access a field of this entry's redis hash
|
282
|
+
#
|
283
|
+
# note that you cannot access created_at or id with these methods
|
284
|
+
def [](field)
|
285
|
+
EasyRedis.redis.hget(key_name,field)
|
286
|
+
end
|
287
|
+
|
288
|
+
# directly change a field of this entry's redis hash
|
289
|
+
#
|
290
|
+
# note that you cannot access created_at or id with these methods
|
291
|
+
def []=(field,val)
|
292
|
+
if val
|
293
|
+
EasyRedis.redis.hset(key_name,field,val)
|
294
|
+
else
|
295
|
+
EasyRedis.redis.hdel(key_name,field)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# remove the entry
|
300
|
+
def destroy
|
301
|
+
EasyRedis.redis.zrem(prefix.pluralize,@id)
|
302
|
+
EasyRedis.redis.del(key_name)
|
303
|
+
end
|
304
|
+
|
305
|
+
# returns the key name of this entry's redis hash
|
306
|
+
def key_name
|
307
|
+
prefix + ':' + @id.to_s
|
308
|
+
end
|
309
|
+
|
310
|
+
def inspect
|
311
|
+
"#<#{self.class.name}:#{@id}>"
|
312
|
+
end
|
313
|
+
|
314
|
+
|
315
|
+
private
|
316
|
+
|
317
|
+
def self.get_temp_key
|
318
|
+
i = EasyRedis.redis.incr prefix.pluralize + ':next_tmp_id'
|
319
|
+
"#{name}:tmp_#{i}"
|
320
|
+
end
|
321
|
+
|
322
|
+
def self.proc_options(options)
|
323
|
+
opts = {}
|
324
|
+
opts[:limit] = [0,options[:limit]] if options[:limit]
|
325
|
+
opts
|
326
|
+
end
|
327
|
+
|
328
|
+
def self.prefix
|
329
|
+
self.name.downcase
|
330
|
+
end
|
331
|
+
|
332
|
+
def self.sort_prefix(field)
|
333
|
+
if field == :created_at
|
334
|
+
prefix.pluralize
|
335
|
+
else
|
336
|
+
prefix.pluralize + ':sort_' + field.to_s
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def prefix
|
341
|
+
self.class.prefix
|
342
|
+
end
|
343
|
+
|
344
|
+
def sort_prefix(field)
|
345
|
+
self.class.sort_prefix(field)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
data/tests/benchmark.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require './tests/test'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
$names = ["Bill","Bob","John","Jack","Alec","Mark","Nick","Evan","Eamon","Joe","Vikram"]
|
5
|
+
|
6
|
+
def rand_name
|
7
|
+
$names[rand*$names.size]
|
8
|
+
end
|
9
|
+
|
10
|
+
$count = 0
|
11
|
+
$num_add = ARGV[0] ? ARGV[0].to_i : 50000
|
12
|
+
|
13
|
+
puts "counting entries"
|
14
|
+
Benchmark.bm(7) do |bm|
|
15
|
+
bm.report { $count = Man.count }
|
16
|
+
end
|
17
|
+
puts
|
18
|
+
|
19
|
+
puts "destroying #{$count} previous entries"
|
20
|
+
Benchmark.bm(7) do |bm|
|
21
|
+
bm.report { Man.destroy_all }
|
22
|
+
end
|
23
|
+
puts
|
24
|
+
|
25
|
+
puts "adding #{$num_add} new entries"
|
26
|
+
Benchmark.bm(7) do |bm|
|
27
|
+
bm.report { $num_add.times { m = Man.new ; m.name = rand_name } }
|
28
|
+
end
|
29
|
+
puts
|
30
|
+
|
31
|
+
puts "sorting by name"
|
32
|
+
Benchmark.bm(7) do |bm|
|
33
|
+
bm.report("ruby:") { Man.all.sort_by { |m| m.name } }
|
34
|
+
bm.report("redis:") { Man.sort_by(:name) }
|
35
|
+
end
|
36
|
+
puts
|
37
|
+
|
38
|
+
puts "finding all entries by a particular name"
|
39
|
+
Benchmark.bm(7) do |bm|
|
40
|
+
name = rand_name
|
41
|
+
bm.report("ruby:") { Man.all.select {|m| m.name == name} }
|
42
|
+
bm.report("redis:") { Man.search_by(:name,name) }
|
43
|
+
end
|
44
|
+
puts
|
data/tests/test.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: easyredis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alec Benzer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-02-05 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: redis
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :development
|
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: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
description: simple framework designed to make using redis as a database simpler
|
39
|
+
email: alecbezer @nospam@ gmail.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- README.md
|
46
|
+
- lib/easyredis.rb
|
47
|
+
files:
|
48
|
+
- Manifest
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- lib/easyredis.rb
|
52
|
+
- tests/benchmark.rb
|
53
|
+
- tests/test.rb
|
54
|
+
- easyredis.gemspec
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: https://github.com/alecbenzer/easyredis
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --line-numbers
|
62
|
+
- --inline-source
|
63
|
+
- --title
|
64
|
+
- Easyredis
|
65
|
+
- --main
|
66
|
+
- README.md
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "1.2"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: easyredis
|
84
|
+
rubygems_version: 1.5.0
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: simple framework designed to make using redis as a database simpler
|
88
|
+
test_files: []
|
89
|
+
|