sequel-cacheable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format doc
data/Gemfile ADDED
@@ -0,0 +1,30 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+
9
+ gem 'sequel', '~> 3.32.0'
10
+ gem 'msgpack', '~> 0.4.6'
11
+ gem 'hashr', '~> 0.0.19'
12
+
13
+ group :development do
14
+ gem "bundler", ">= 1.0.0"
15
+
16
+ gem "rspec", "~> 2.8.0"
17
+ gem "yard", "~> 0.7"
18
+ gem "rdoc", "~> 3.12"
19
+ gem "jeweler", "~> 1.8.3"
20
+ gem 'simplecov', "~> 0.6.1", :require => false
21
+
22
+ gem "guard", '~> 1.0.0'
23
+ gem "guard-rspec", '~> 0.6.0'
24
+ gem "growl"
25
+
26
+ gem "sqlite3"
27
+ gem "memcache"
28
+ gem "redis"
29
+ gem "queencheck"
30
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,66 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ colorize (0.5.8)
5
+ diff-lcs (1.1.3)
6
+ ffi (1.0.11)
7
+ git (1.2.5)
8
+ growl (1.0.3)
9
+ guard (1.0.0)
10
+ ffi (>= 0.5.0)
11
+ thor (~> 0.14.6)
12
+ guard-rspec (0.6.0)
13
+ guard (>= 0.10.0)
14
+ hashr (0.0.19)
15
+ jeweler (1.8.3)
16
+ bundler (~> 1.0)
17
+ git (>= 1.2.5)
18
+ rake
19
+ rdoc
20
+ json (1.6.5)
21
+ memcache (1.2.13)
22
+ msgpack (0.4.6)
23
+ multi_json (1.1.0)
24
+ queencheck (1.0.0)
25
+ colorize (>= 0.5.8)
26
+ rake (0.9.2.2)
27
+ rdoc (3.12)
28
+ json (~> 1.4)
29
+ redis (2.2.2)
30
+ rspec (2.8.0)
31
+ rspec-core (~> 2.8.0)
32
+ rspec-expectations (~> 2.8.0)
33
+ rspec-mocks (~> 2.8.0)
34
+ rspec-core (2.8.0)
35
+ rspec-expectations (2.8.0)
36
+ diff-lcs (~> 1.1.2)
37
+ rspec-mocks (2.8.0)
38
+ sequel (3.32.0)
39
+ simplecov (0.6.1)
40
+ multi_json (~> 1.0)
41
+ simplecov-html (~> 0.5.3)
42
+ simplecov-html (0.5.3)
43
+ sqlite3 (1.3.5)
44
+ thor (0.14.6)
45
+ yard (0.7.5)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ bundler (>= 1.0.0)
52
+ growl
53
+ guard (~> 1.0.0)
54
+ guard-rspec (~> 0.6.0)
55
+ hashr (~> 0.0.19)
56
+ jeweler (~> 1.8.3)
57
+ memcache
58
+ msgpack (~> 0.4.6)
59
+ queencheck
60
+ rdoc (~> 3.12)
61
+ redis
62
+ rspec (~> 2.8.0)
63
+ sequel (~> 3.32.0)
64
+ simplecov (~> 0.6.1)
65
+ sqlite3
66
+ yard (~> 0.7)
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, :cli => '--color --format doc' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Sho Kusano <rosylilly>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = sequel-cacheable
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to sequel-cacheable
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2012 Sho Kusano <rosylilly>. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "sequel-cacheable"
18
+ gem.homepage = "http://github.com/rosylilly/sequel-cacheable"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{This plug-in caching mechanism to implement the Model of the Sequel}
21
+ gem.description = %Q{This plug-in caching mechanism to implement the Model of the Sequel}
22
+ gem.email = "rosylilly@aduca.org"
23
+ gem.authors = ["Sho Kusano <rosylilly>"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ require 'simplecov'
36
+ SimpleCov.start
37
+ spec.pattern = 'spec/**/*_spec.rb'
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'yard'
43
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,193 @@
1
+ require 'sequel'
2
+ require 'hashr'
3
+ require 'msgpack'
4
+
5
+ module Sequel::Plugins
6
+ module Cacheable
7
+ def self.configure(model, store, options = {})
8
+ model.instance_eval do
9
+ @cache_store = store
10
+ @cache_store_type = Hashr.new({
11
+ :set_with_ttl => store.respond_to?(:set) ? store.method(:set).arity != 2 : false,
12
+ :delete_method => (
13
+ (store.respond_to?(:del) && :del) ||
14
+ (store.respond_to?(:delete) && :delete) ||
15
+ (raise NoMethodError, "#{store.class} is not implemented delete method")
16
+ )
17
+ })
18
+ @cache_options = Hashr.new(options, {
19
+ :ttl => 3600,
20
+ :ignore_exception => false,
21
+ :pack_lib => MessagePack,
22
+ :query_cache => store.respond_to?(:keys)
23
+ })
24
+ end
25
+ end
26
+
27
+ module ClassMethods
28
+ attr_reader :cache_store
29
+ attr_reader :cache_store_type
30
+ attr_reader :cache_options
31
+
32
+ def inherited(subclass)
33
+ super
34
+ cache = [@cache_store, @cache_store_type, @cache_options]
35
+ subclass.instance_eval do
36
+ @cache_store = cache[0]
37
+ @cache_store_type = cache[1]
38
+ @cache_options = cache[2]
39
+ end
40
+ end
41
+
42
+ def cache_set(key, obj, ttl = nil)
43
+ return obj if obj.nil?
44
+
45
+ ttl = ttl || cache_options.ttl
46
+ if cache_options.pack_lib?
47
+ obj = obj.map{|o| o.msgpack_hash } if obj.kind_of?(Array)
48
+ obj = cache_options.pack_lib.pack(obj)
49
+ end
50
+
51
+ args = [key, obj]
52
+ args << ttl if cache_store_type.set_with_ttl?
53
+ cache_store.set(*args)
54
+ unless cache_store_type.set_with_ttl?
55
+ cache_store.expire(key, ttl)
56
+ end
57
+ end
58
+
59
+ def cache_get(key)
60
+ if cache_options.ignore_exceptions?
61
+ obj = cache_store.get(key) rescue nil
62
+ else
63
+ obj = cache_store.get(key)
64
+ end
65
+
66
+ if obj && cache_options.pack_lib?
67
+ obj = restore_cache(cache_options.pack_lib.unpack(obj))
68
+ end
69
+
70
+ obj
71
+ end
72
+
73
+ def cache_del(key)
74
+ cache_store.send(cache_store_type.delete_method, key)
75
+ end
76
+
77
+ def cache_set_get(key, ttl = nil)
78
+ if (val = cache_get(key)).nil?
79
+ val = yield
80
+ cache_set(key, val, ttl)
81
+ end
82
+ val
83
+ end
84
+
85
+ def restore_cache(object)
86
+ return object if object.nil?
87
+
88
+ return object.map{|o| restore_cache(o) } if object.kind_of?(Array)
89
+
90
+ object.keys.each do | key |
91
+ value = object.delete(key)
92
+ key = key.to_sym rescue key
93
+ case db_schema[key][:type]
94
+ when :time
95
+ value = Sequel::SQLTime.at(value[0], value[1])
96
+ end
97
+ object[key] = value
98
+ end
99
+ new(object, true)
100
+ end
101
+
102
+ def clear_query_cache
103
+ cache_store.keys("#{model.name}::Query::*").each do | key |
104
+ cache_del(key)
105
+ end
106
+ end
107
+
108
+ def primary_key_lookup(key)
109
+ cache_set_get("#{model}::#{key}") do
110
+ super(key)
111
+ end
112
+ end
113
+ end
114
+
115
+ module InstanceMethods
116
+ def msgpack_hash
117
+ hash = {}
118
+ @values.each_pair do | key, value |
119
+ case value
120
+ when Sequel::SQLTime
121
+ value = [value.to_i, value.usec]
122
+ end
123
+ hash[key] = value
124
+ end
125
+ hash
126
+ end
127
+
128
+ def to_msgpack(*args)
129
+ msgpack_hash.to_msgpack
130
+ end
131
+
132
+ def after_initialize
133
+ store_cache
134
+ super
135
+ end
136
+
137
+ def after_update
138
+ restore_cache
139
+ super
140
+ end
141
+
142
+ def delete
143
+ delete_cache
144
+ super
145
+ end
146
+
147
+ def destroy(*args)
148
+ delete_cache
149
+ super(*args)
150
+ end
151
+
152
+ def store_cache
153
+ model.cache_set(cache_key, self)
154
+ end
155
+
156
+ def delete_cache
157
+ model.cache_del(cache_key)
158
+ model.clear_query_cache
159
+ end
160
+
161
+ def restore_cache
162
+ delete_cache
163
+ store_cache
164
+ end
165
+
166
+ def cache_key
167
+ "#{self.class.name}::#{self.id.to_s}"
168
+ end
169
+ end
170
+
171
+ module DatasetMethods
172
+ def all(*args)
173
+ if model.cache_options.query_cache? && @row_proc.kind_of?(Class) && @row_proc.included_modules.include?(Sequel::Model::InstanceMethods)
174
+ @row_proc.cache_set_get(query_to_cache_key) { super(*args) }
175
+ else
176
+ super(*args)
177
+ end
178
+ end
179
+
180
+ def first(*args)
181
+ if model.cache_options.query_cache? && @row_proc.kind_of?(Class) && @row_proc.included_modules.include?(Sequel::Model::InstanceMethods)
182
+ @row_proc.cache_set_get(query_to_cache_key) { super(*args) }
183
+ else
184
+ super(*args)
185
+ end
186
+ end
187
+
188
+ def query_to_cache_key
189
+ model.name + '::Query::' + select_sql.gsub(/ /, '_')
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ class RedisModel < Sequel::Model(:spec)
4
+ end
5
+
6
+ class MemcacheModel < Sequel::Model(:spec)
7
+ plugin :cacheable, MemcacheCli
8
+ end
9
+
10
+ QueenCheck::Arbitrary(Float, Fixnum.arbitrary.gen)
11
+ QueenCheck::Arbitrary(String, QueenCheck::Gen.quadratic(200).bind { | length |
12
+ if length.zero?
13
+ QueenCheck::Gen.unit("")
14
+ else
15
+ QueenCheck::Gen.rand.resize(1, length).fmap { | r |
16
+ str = []
17
+ r.times { str << QueenCheck::Alphabet.arbitrary.gen.value(0)[0] }
18
+ str.join()
19
+ }
20
+ end
21
+ })
22
+
23
+ describe Sequel::Plugins::Cacheable do
24
+ QueenCheck("Generate Test Datas",
25
+ String, Fixnum, Float) do |string, fixnum, float|
26
+ float = float * 1.0 / (10 ** (rand(4) + 1))
27
+ RedisModel.create({
28
+ :string => string,
29
+ :int => fixnum,
30
+ :float => float,
31
+ :time => Time.now
32
+ })
33
+ true
34
+ end
35
+
36
+ context "NoNameClass" do
37
+ before {
38
+ @model = Class.new(Sequel::Model(:rspec))
39
+ }
40
+
41
+ it "should raise NoMethodError if the delete method is not found" do
42
+ proc {
43
+ @model.plugin :cacheable, 1
44
+ }.should raise_error(NoMethodError)
45
+ end
46
+ end
47
+
48
+ context MemcacheModel do
49
+ subject { MemcacheModel }
50
+
51
+ its("cache_store") { should == MemcacheCli }
52
+ its("cache_store_type.set_with_ttl?") { should be_true }
53
+ its("cache_store_type.delete_method") { should == :delete }
54
+ its("cache_options.ttl") { should == 3600 }
55
+ its("cache_options.ignore_exceptions") { should be_false }
56
+ its("cache_options.pack_lib") { should == MessagePack }
57
+
58
+ describe "cache control" do
59
+ it "set" do
60
+ MemcacheModel.cache_set('MemcacheModel::test', MemcacheModel[1])
61
+ end
62
+
63
+ it "get" do
64
+ cache = MemcacheModel.cache_get('MemcacheModel::test')
65
+ cache.should == MemcacheModel[1]
66
+ end
67
+
68
+ it "del" do
69
+ MemcacheModel.cache_del('MemcacheModel::test')
70
+ MemcacheModel.cache_get('MemcacheModel::test').should be_nil
71
+ end
72
+ end
73
+ end
74
+
75
+ context RedisModel do
76
+ subject { RedisModel }
77
+
78
+ it "should raise LoadError if the plugin is not found" do
79
+ proc{ RedisModel.plugin :something_or_other}.should raise_error(LoadError)
80
+ end
81
+
82
+ its("columns") { should == [:id, :string, :int, :float, :time]}
83
+
84
+ its("plugins") {
85
+ should_not include(Sequel::Plugins::Cacheable)
86
+ RedisModel.plugin :cacheable, RedisCli
87
+ should include(Sequel::Plugins::Cacheable)
88
+ }
89
+
90
+ its("cache_store") { should == RedisCli }
91
+ its("cache_store_type.set_with_ttl?") { should be_false }
92
+ its("cache_store_type.delete_method") { should == :del }
93
+ its("cache_options.ttl") { should == 3600 }
94
+ its("cache_options.ignore_exceptions") { should be_false }
95
+ its("cache_options.pack_lib") { should == MessagePack }
96
+
97
+ describe "cache control" do
98
+ it "set" do
99
+ RedisModel.cache_set('RedisModel::test', RedisModel[1])
100
+ end
101
+
102
+ it "get" do
103
+ RedisModel.cache_get('RedisModel::test').should == RedisModel[1]
104
+ end
105
+
106
+ it "del" do
107
+ RedisModel.cache_del('RedisModel::test')
108
+ RedisModel.cache_get('RedisModel::test').should be_nil
109
+ end
110
+ end
111
+
112
+ describe "act as cache" do
113
+ context "Model[50]" do
114
+ before do
115
+ @obj = RedisModel[50]
116
+ end
117
+
118
+ it "stored cache" do
119
+ RedisCli.keys(@obj.cache_key).should == [@obj.cache_key]
120
+ end
121
+
122
+ it "restoreble cache data" do
123
+ cached = MessagePack.unpack(RedisCli.get(@obj.cache_key))
124
+ cached['string'].should == @obj.string
125
+ Time.at(cached['time'][0], cached['time'][1]).should === @obj.time
126
+ end
127
+
128
+ it "update cache data" do
129
+ @obj.string = 'modified++'
130
+ cached = MessagePack.unpack(RedisCli.get(@obj.cache_key))
131
+ cached['string'].should_not == @obj.string
132
+ @obj.save
133
+ cached = MessagePack.unpack(RedisCli.get(@obj.cache_key))
134
+ cached['string'].should == @obj.string
135
+ end
136
+
137
+ it "delete cache data" do
138
+ @obj.delete
139
+ RedisCli.keys(@obj.cache_key).should == []
140
+ RedisModel[50].should be_nil
141
+ end
142
+
143
+ it "destroy cache data" do
144
+ @obj = RedisModel[51]
145
+ @obj.delete
146
+ RedisCli.keys(@obj.cache_key).should == []
147
+ RedisModel[51].should be_nil
148
+ end
149
+ end
150
+ end
151
+
152
+ describe "query cache" do
153
+ it "set and get" do
154
+ models = RedisModel.limit(3).all
155
+ cache_key = RedisCli.keys('RedisModel::Query::*')[0]
156
+ RedisModel.cache_get(cache_key).should == models
157
+ end
158
+
159
+ it "clear on update" do
160
+ RedisModel.all
161
+ cache_key = RedisCli.keys('RedisModel::Query::*')
162
+ cache_key.should_not be_empty
163
+ RedisModel[2].save({:string => 'test++'})
164
+ RedisCli.keys('RedisModel::Query::*').should be_empty
165
+ end
166
+
167
+ it "clear on delete" do
168
+ RedisModel.all
169
+ cache_key = RedisCli.keys('RedisModel::Query::*')
170
+ cache_key.should_not be_empty
171
+ RedisModel[2].delete
172
+ RedisCli.keys('RedisModel::Query::*').should be_empty
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup(:default, :development)
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'rspec'
8
+ require 'sequel-cacheable'
9
+ require 'redis'
10
+ require 'memcache'
11
+ require 'queencheck/rspec'
12
+
13
+ # Requires supporting files with custom matchers and macros, etc,
14
+ # in ./support/ and its subdirectories.
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
16
+
17
+ RSpec.configure do |config|
18
+ DB = Sequel.sqlite
19
+ DB.create_table(:spec) do
20
+ primary_key :id, :auto_increment => true
21
+ string :string
22
+ integer :int
23
+ float :float
24
+ time :time
25
+ end
26
+ RedisCli = Redis.new(:host => 'localhost', :port => 6379)
27
+ MemcacheCli = Memcache.new(:server => 'localhost:11211')
28
+
29
+ config.after(:all) {
30
+ RedisCli.flushall
31
+ MemcacheCli.flush_all
32
+ }
33
+ end
metadata ADDED
@@ -0,0 +1,238 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel-cacheable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sho Kusano <rosylilly>
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sequel
16
+ requirement: &70115283680940 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.32.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70115283680940
25
+ - !ruby/object:Gem::Dependency
26
+ name: msgpack
27
+ requirement: &70115283680240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.4.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70115283680240
36
+ - !ruby/object:Gem::Dependency
37
+ name: hashr
38
+ requirement: &70115283678820 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.0.19
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70115283678820
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &70115283693140 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70115283693140
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70115283690620 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 2.8.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70115283690620
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: &70115283689440 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '0.7'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70115283689440
80
+ - !ruby/object:Gem::Dependency
81
+ name: rdoc
82
+ requirement: &70115283688660 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '3.12'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70115283688660
91
+ - !ruby/object:Gem::Dependency
92
+ name: jeweler
93
+ requirement: &70115283688000 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 1.8.3
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70115283688000
102
+ - !ruby/object:Gem::Dependency
103
+ name: simplecov
104
+ requirement: &70115283687380 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 0.6.1
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70115283687380
113
+ - !ruby/object:Gem::Dependency
114
+ name: guard
115
+ requirement: &70115283686480 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ version: 1.0.0
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70115283686480
124
+ - !ruby/object:Gem::Dependency
125
+ name: guard-rspec
126
+ requirement: &70115283701860 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 0.6.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70115283701860
135
+ - !ruby/object:Gem::Dependency
136
+ name: growl
137
+ requirement: &70115283700860 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *70115283700860
146
+ - !ruby/object:Gem::Dependency
147
+ name: sqlite3
148
+ requirement: &70115283699440 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *70115283699440
157
+ - !ruby/object:Gem::Dependency
158
+ name: memcache
159
+ requirement: &70115283698020 !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: *70115283698020
168
+ - !ruby/object:Gem::Dependency
169
+ name: redis
170
+ requirement: &70115283696780 !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: *70115283696780
179
+ - !ruby/object:Gem::Dependency
180
+ name: queencheck
181
+ requirement: &70115283695460 !ruby/object:Gem::Requirement
182
+ none: false
183
+ requirements:
184
+ - - ! '>='
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: *70115283695460
190
+ description: This plug-in caching mechanism to implement the Model of the Sequel
191
+ email: rosylilly@aduca.org
192
+ executables: []
193
+ extensions: []
194
+ extra_rdoc_files:
195
+ - LICENSE.txt
196
+ - README.rdoc
197
+ files:
198
+ - .document
199
+ - .rspec
200
+ - Gemfile
201
+ - Gemfile.lock
202
+ - Guardfile
203
+ - LICENSE.txt
204
+ - README.rdoc
205
+ - Rakefile
206
+ - VERSION
207
+ - lib/sequel-cacheable.rb
208
+ - spec/lib/sequel-cacheable_spec.rb
209
+ - spec/spec_helper.rb
210
+ homepage: http://github.com/rosylilly/sequel-cacheable
211
+ licenses:
212
+ - MIT
213
+ post_install_message:
214
+ rdoc_options: []
215
+ require_paths:
216
+ - lib
217
+ required_ruby_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ segments:
224
+ - 0
225
+ hash: -213750302155396124
226
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
+ none: false
228
+ requirements:
229
+ - - ! '>='
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ requirements: []
233
+ rubyforge_project:
234
+ rubygems_version: 1.8.11
235
+ signing_key:
236
+ specification_version: 3
237
+ summary: This plug-in caching mechanism to implement the Model of the Sequel
238
+ test_files: []