swagger 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,6 +17,7 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ .rvmrc
20
21
 
21
22
  ## PROJECT::SPECIFIC
22
23
  test.db
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -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!
@@ -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 :value, :text
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 'rubygems'
2
- require 'rake'
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
- Spec::Rake::SpecTask.new(:rcov) do |spec|
29
- spec.libs << 'lib' << 'spec'
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
- require 'rake/rdoctask'
39
- Rake::RDocTask.new do |rdoc|
40
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
8
+ RSpec::Core::RakeTask.new
41
9
 
42
- rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "swagger #{version}"
44
- rdoc.rdoc_files.include('README*')
45
- rdoc.rdoc_files.include('lib/**/*.rb')
46
- end
10
+ task :default => :spec
@@ -1,11 +1,11 @@
1
1
  Resque.module_eval do
2
2
  def swagger!
3
3
  define_method(:redis=) do |*args|
4
- @redis = RedisImpersonator.new
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
@@ -1,3 +1,2 @@
1
1
  class ResqueValue < ActiveRecord::Base
2
-
3
2
  end
@@ -1,4 +1,7 @@
1
1
  require 'active_record'
2
2
  require 'resque_value'
3
- require 'redis_impersonator'
4
- require 'resque_extension'
3
+ require 'swagger/redis'
4
+ require 'resque_extension'
5
+
6
+ module Swagger
7
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module Commands
3
+ module Helpers
4
+ module_function
5
+
6
+ def select_values(sql)
7
+ ResqueValue.connection.select_values(sanitize(sql))
8
+ end
9
+
10
+ def sanitize(sql)
11
+ ResqueValue.send(:sanitize_sql, sql)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -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