swagger 1.4.0 → 1.4.1
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/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +62 -0
- data/README.rdoc +9 -7
- data/Rakefile +7 -43
- data/lib/resque_extension.rb +3 -3
- data/lib/resque_value.rb +0 -1
- data/lib/swagger.rb +5 -2
- data/lib/swagger/commands/helpers.rb +16 -0
- data/lib/swagger/commands/keys.rb +21 -0
- data/lib/swagger/commands/lists.rb +53 -0
- data/lib/swagger/commands/sets.rb +25 -0
- data/lib/swagger/commands/sorted_sets.rb +56 -0
- data/lib/swagger/commands/strings.rb +60 -0
- data/lib/swagger/redis.rb +26 -0
- data/lib/swagger/swallow.rb +14 -0
- data/lib/swagger/version.rb +7 -0
- data/spec/resque_extension_spec.rb +6 -7
- data/spec/spec_helper.rb +17 -14
- data/spec/support/helpers.rb +7 -0
- data/spec/swagger/commands/sorted_sets_spec.rb +175 -0
- data/spec/swagger/commands/strings_spec.rb +58 -0
- data/spec/swagger/redis_spec.rb +171 -0
- data/swagger.gemspec +12 -52
- metadata +74 -35
- data/VERSION +0 -1
- data/lib/redis_impersonator.rb +0 -129
- data/spec/redis_impersonator_spec.rb +0 -171
- data/spec/spec.opts +0 -1
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
swagger (1.4.1)
|
5
|
+
activerecord
|
6
|
+
resque (>= 1.10.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activemodel (3.0.3)
|
12
|
+
activesupport (= 3.0.3)
|
13
|
+
builder (~> 2.1.2)
|
14
|
+
i18n (~> 0.4)
|
15
|
+
activerecord (3.0.3)
|
16
|
+
activemodel (= 3.0.3)
|
17
|
+
activesupport (= 3.0.3)
|
18
|
+
arel (~> 2.0.2)
|
19
|
+
tzinfo (~> 0.3.23)
|
20
|
+
activesupport (3.0.3)
|
21
|
+
arel (2.0.7)
|
22
|
+
builder (2.1.2)
|
23
|
+
diff-lcs (1.1.2)
|
24
|
+
i18n (0.5.0)
|
25
|
+
json (1.4.6)
|
26
|
+
rack (1.2.1)
|
27
|
+
rake (0.8.7)
|
28
|
+
redis (2.1.1)
|
29
|
+
redis-namespace (0.8.0)
|
30
|
+
redis (< 3.0.0)
|
31
|
+
resque (1.10.0)
|
32
|
+
json (~> 1.4.6)
|
33
|
+
redis-namespace (~> 0.8.0)
|
34
|
+
sinatra (>= 0.9.2)
|
35
|
+
vegas (~> 0.1.2)
|
36
|
+
rspec (2.4.0)
|
37
|
+
rspec-core (~> 2.4.0)
|
38
|
+
rspec-expectations (~> 2.4.0)
|
39
|
+
rspec-mocks (~> 2.4.0)
|
40
|
+
rspec-core (2.4.0)
|
41
|
+
rspec-expectations (2.4.0)
|
42
|
+
diff-lcs (~> 1.1.2)
|
43
|
+
rspec-mocks (2.4.0)
|
44
|
+
sinatra (1.1.2)
|
45
|
+
rack (~> 1.1)
|
46
|
+
tilt (~> 1.2)
|
47
|
+
sqlite3 (1.3.3)
|
48
|
+
tilt (1.2.2)
|
49
|
+
tzinfo (0.3.24)
|
50
|
+
vegas (0.1.8)
|
51
|
+
rack (>= 1.0.0)
|
52
|
+
|
53
|
+
PLATFORMS
|
54
|
+
ruby
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
activerecord
|
58
|
+
rake (~> 0.8.7)
|
59
|
+
resque (>= 1.10.0)
|
60
|
+
rspec (>= 2.4.0)
|
61
|
+
sqlite3 (>= 1.3.3)
|
62
|
+
swagger!
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Swagger = Resque + ActiveRecord - Redis
|
2
|
-
|
2
|
+
|
3
3
|
Swagger marries the power and robustness of Resque with the trivial setup of delayed_job. Swagger allows you to use all the features of Resque (http://github.com/defunkt/resque) without any of the "Redis" by adding one table to your existing database.
|
4
|
-
|
4
|
+
|
5
5
|
== Getting Started
|
6
6
|
|
7
7
|
=== 1. Add resque and swagger to your gem dependencies (order is important)
|
@@ -19,20 +19,22 @@ Swagger marries the power and robustness of Resque with the trivial setup of del
|
|
19
19
|
Resque.connect_to_database(database)
|
20
20
|
|
21
21
|
==== NOTE: This allows rails and the resque admin app to use the same initializer by executing at the console: resque-web config/initializers/resque.rb
|
22
|
-
|
22
|
+
|
23
23
|
=== 3. Create an active record migration
|
24
|
-
|
24
|
+
|
25
25
|
create_table :resque_values do |table|
|
26
26
|
table.column :key, :string
|
27
27
|
table.column :key_type, :string
|
28
|
-
table.column :
|
28
|
+
table.column :score, :integer
|
29
|
+
table.column :value, :text
|
30
|
+
table.timestamps
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
add_index :resque_values, :key
|
32
34
|
add_index :resque_values, [:key, :key_type]
|
33
35
|
|
34
36
|
== Note on Patches/Pull Requests
|
35
|
-
|
37
|
+
|
36
38
|
* Fork the project.
|
37
39
|
* Make your feature addition or bug fix.
|
38
40
|
* Add tests for it. This is important so I don't break it in a
|
data/Rakefile
CHANGED
@@ -1,46 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'jeweler'
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = "swagger"
|
8
|
-
gem.summary = %Q{Everything Resque provides minus Redis}
|
9
|
-
gem.description = %Q{Duck punch Resque to use active record for backround jobs instead of redis}
|
10
|
-
gem.email = "mdeiters@gmail.com"
|
11
|
-
gem.homepage = "http://github.com/mdeiters/swagger"
|
12
|
-
gem.authors = ["mdeiters"]
|
13
|
-
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
-
gem.add_dependency "activerecord" #, "2.3.8"
|
15
|
-
gem.add_dependency "resque", ">= 1.10.0"
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
-
end
|
21
|
-
|
22
|
-
require 'spec/rake/spectask'
|
23
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
-
spec.libs << 'lib' << 'spec'
|
25
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
-
end
|
1
|
+
require 'bundler'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler::GemHelper.install_tasks
|
27
4
|
|
28
|
-
|
29
|
-
|
30
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
-
spec.rcov = true
|
32
|
-
end
|
33
|
-
|
34
|
-
task :spec => :check_dependencies
|
35
|
-
|
36
|
-
task :default => :spec
|
5
|
+
require 'rake'
|
6
|
+
require 'rspec/core/rake_task'
|
37
7
|
|
38
|
-
|
39
|
-
Rake::RDocTask.new do |rdoc|
|
40
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
8
|
+
RSpec::Core::RakeTask.new
|
41
9
|
|
42
|
-
|
43
|
-
rdoc.title = "swagger #{version}"
|
44
|
-
rdoc.rdoc_files.include('README*')
|
45
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
-
end
|
10
|
+
task :default => :spec
|
data/lib/resque_extension.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Resque.module_eval do
|
2
2
|
def swagger!
|
3
3
|
define_method(:redis=) do |*args|
|
4
|
-
@redis =
|
4
|
+
@redis = Swagger::Redis.new
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
define_method(:connect_to_database) do |database|
|
8
8
|
ResqueValue.establish_connection database
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
11
11
|
end
|
data/lib/resque_value.rb
CHANGED
data/lib/swagger.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Commands
|
3
|
+
module Keys
|
4
|
+
|
5
|
+
def del(key)
|
6
|
+
ResqueValue.delete_all(:key => key.to_s)
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def exists(key)
|
11
|
+
ResqueValue.exists?(:key => key.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
def keys(pattern = '*')
|
15
|
+
raise "Pattern '#{pattern}' not supported" if pattern != '*'
|
16
|
+
ResqueValue.all(:select => 'DISTINCT resque_values.key').map(&:key)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Commands
|
3
|
+
module Lists
|
4
|
+
KEY_TYPE = 'list'
|
5
|
+
|
6
|
+
def llen(list_name)
|
7
|
+
ResqueValue.all(:conditions => {:key => list_name.to_s, :key_type=> KEY_TYPE }).size
|
8
|
+
end
|
9
|
+
|
10
|
+
def lset(list_name, index, value)
|
11
|
+
rpush(list_name, value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def lrange(list_name, start_range, end_range)
|
15
|
+
options = { :conditions => {
|
16
|
+
:key => list_name.to_s,
|
17
|
+
:key_type=> KEY_TYPE}}
|
18
|
+
unless end_range < 0
|
19
|
+
limit = end_range - start_range + 1
|
20
|
+
options.merge!(:limit => limit, :offset => start_range)
|
21
|
+
end
|
22
|
+
values = ResqueValue.all(options)
|
23
|
+
values.map(&:value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def lrem(list_name, count, value)
|
27
|
+
raise "Only supports count of 0 which means to remove all elements in list" if count != 0
|
28
|
+
ResqueValue.delete_all(:key => list_name.to_s, :key_type=> KEY_TYPE, :value => value )
|
29
|
+
end
|
30
|
+
|
31
|
+
def lpop(list_name)
|
32
|
+
ResqueValue.transaction do
|
33
|
+
last = ResqueValue.last(:conditions => {:key => list_name.to_s, :key_type => KEY_TYPE}, :lock => true)
|
34
|
+
if last
|
35
|
+
last.destroy
|
36
|
+
return last.value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def rpush(list_name, value)
|
42
|
+
ResqueValue.create!(:key => list_name.to_s, :key_type => KEY_TYPE, :value => value.to_s)
|
43
|
+
end
|
44
|
+
|
45
|
+
def ltrim(list_name, start_range, end_range)
|
46
|
+
limit = end_range - start_range + 1
|
47
|
+
ids = ResqueValue.all(:select => "id", :conditions => {:key => list_name}, :offset => start_range, :limit => limit)
|
48
|
+
ResqueValue.delete_all(["`key` = ? AND id NOT IN (?)", list_name, ids.collect{|i| i.id}])
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Commands
|
3
|
+
module Sets
|
4
|
+
KEY_TYPE = 'set'
|
5
|
+
|
6
|
+
def sadd(set_name, value)
|
7
|
+
sismember(set_name, value) || ResqueValue.create!(:key => set_name.to_s, :key_type => KEY_TYPE, :value => value.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def srem(set_name, value)
|
11
|
+
ResqueValue.delete_all(:key => set_name.to_s, :key_type => KEY_TYPE, :value => value.to_s)
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def smembers(set_name)
|
16
|
+
ResqueValue.all(:conditions => {:key => set_name.to_s, :key_type => KEY_TYPE}).map(&:value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def sismember(set_name, value)
|
20
|
+
ResqueValue.exists?(:key => set_name.to_s, :key_type => KEY_TYPE, :value => value.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Commands
|
3
|
+
module SortedSets
|
4
|
+
|
5
|
+
KEY_TYPE = 'sorted_set'
|
6
|
+
|
7
|
+
def zadd(key, score, value)
|
8
|
+
record = ResqueValue.find_or_initialize_by_key_and_key_type_and_value(
|
9
|
+
key.to_s, KEY_TYPE, value)
|
10
|
+
record.score = score
|
11
|
+
record.save!
|
12
|
+
record
|
13
|
+
end
|
14
|
+
|
15
|
+
def zrem(key, value)
|
16
|
+
ResqueValue.delete_all conditions(key).merge(:value => value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def zcard(key)
|
20
|
+
ResqueValue.count :conditions => conditions(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
def zrange(key, start, stop)
|
24
|
+
Helpers.select_values(
|
25
|
+
'SELECT value FROM resque_values ' \
|
26
|
+
"WHERE key = #{key} " \
|
27
|
+
'ORDER BY score'
|
28
|
+
)[start..stop]
|
29
|
+
end
|
30
|
+
|
31
|
+
def zrangebyscore(key, min, max, options = {})
|
32
|
+
min = ResqueValue.minimum(:score, :conditions => conditions(key)) || 0 if min == '-inf'
|
33
|
+
max = ResqueValue.maximum(:score, :conditions => conditions(key)) || 0 if max == '+inf'
|
34
|
+
|
35
|
+
Helpers.select_values(
|
36
|
+
[].tap do |sql|
|
37
|
+
sql << 'SELECT value FROM resque_values'
|
38
|
+
sql << "WHERE `key` = '#{key}'"
|
39
|
+
sql << "AND score BETWEEN #{min} AND #{max}"
|
40
|
+
sql << 'ORDER BY score'
|
41
|
+
if limit = options[:limit]
|
42
|
+
sql << "LIMIT #{limit.join(', ')}"
|
43
|
+
end
|
44
|
+
end.join(' ')
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def conditions(key)
|
51
|
+
{ :key => key.to_s, :key_type => KEY_TYPE }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Swagger
|
2
|
+
module Commands
|
3
|
+
module Strings
|
4
|
+
|
5
|
+
def get(key)
|
6
|
+
resque_value = ResqueValue.first(:conditions => {:key => key})
|
7
|
+
resque_value.value if resque_value
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(key, value)
|
11
|
+
resque_value = ResqueValue.find_or_initialize_by_key(key.to_s)
|
12
|
+
resque_value.value = value
|
13
|
+
resque_value.save!
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def setnx(key, value)
|
18
|
+
resque_value = ResqueValue.find_or_initialize_by_key(key.to_s)
|
19
|
+
if resque_value.new_record?
|
20
|
+
resque_value.value = value
|
21
|
+
resque_value.save!
|
22
|
+
end
|
23
|
+
resque_value.value
|
24
|
+
end
|
25
|
+
|
26
|
+
def incr(key)
|
27
|
+
incrby(key, '1')
|
28
|
+
end
|
29
|
+
|
30
|
+
def decr(key)
|
31
|
+
decrby(key, '1')
|
32
|
+
end
|
33
|
+
|
34
|
+
def incrby(key, value)
|
35
|
+
object = ResqueValue.find_or_initialize_by_key(key.to_s)
|
36
|
+
object.value = (object.value.to_i + value.to_i).to_s
|
37
|
+
object.save!
|
38
|
+
object.value
|
39
|
+
end
|
40
|
+
|
41
|
+
def decrby(key, value)
|
42
|
+
object = ResqueValue.find_or_initialize_by_key(key.to_s)
|
43
|
+
object.value = (object.value.to_i - value.to_i).to_s
|
44
|
+
object.save!
|
45
|
+
object.value
|
46
|
+
end
|
47
|
+
|
48
|
+
def mapped_mget(*keys)
|
49
|
+
Hash[*keys.zip(mget(*keys)).flatten]
|
50
|
+
end
|
51
|
+
|
52
|
+
def mget(*keys)
|
53
|
+
keys.collect!{|key| key.to_s }
|
54
|
+
resque_values = ResqueValue.all(:conditions => {:key => keys})
|
55
|
+
resque_values.map(&:value)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'swagger/swallow'
|
2
|
+
require 'swagger/commands/helpers'
|
3
|
+
require 'swagger/commands/keys'
|
4
|
+
require 'swagger/commands/lists'
|
5
|
+
require 'swagger/commands/sets'
|
6
|
+
require 'swagger/commands/sorted_sets'
|
7
|
+
require 'swagger/commands/strings'
|
8
|
+
|
9
|
+
module Swagger
|
10
|
+
class Redis
|
11
|
+
|
12
|
+
extend Swallow
|
13
|
+
|
14
|
+
swallow :namespace=
|
15
|
+
swallow :namespace, 'not applicable'
|
16
|
+
swallow :server, 'ActiveRecord'
|
17
|
+
swallow :info, self.inspect
|
18
|
+
|
19
|
+
include Commands::Keys
|
20
|
+
include Commands::Lists
|
21
|
+
include Commands::Sets
|
22
|
+
include Commands::SortedSets
|
23
|
+
include Commands::Strings
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|