mongoid-query_cache 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c0ccfe940fad749e4ceafff08dc37a188506349
4
+ data.tar.gz: 02bfa64270f52dfa363a3f5cec8d0e6008593b69
5
+ SHA512:
6
+ metadata.gz: 72155e3fa5918d6dcd918b9288867f9a5b00a86b56c851c75a08b9ebd28f730aba400e958c384878dd24dabb0651bc09c8ec5dffb8c0908303acece8932b7afb
7
+ data.tar.gz: 5a3dc435fcdfbbc39ed2c6d062d608cba4427d9cfe94d987868e3c2666dc8c96d9d60295b85b2e9a83b4a96127cf0a7ceb94c0bf7932a5c1e7f1706463c0f939
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-query_cache.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Philip Claren
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Philip Claren
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ Mongoid3-Query-Cache
2
+ ====================
3
+
4
+ Backport of the Mongoid 4 QueryCache for Mongoid 3.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,233 @@
1
+ require 'mongoid/query_cache/version'
2
+ require 'mongoid/query_cache/railtie' if defined? Rails
3
+
4
+ module Mongoid
5
+
6
+ # A cache of database queries on a per-request basis.
7
+ #
8
+ module QueryCache
9
+ class << self
10
+
11
+ # Get the cached queries.
12
+ #
13
+ # @example Get the cached queries from the current thread.
14
+ # QueryCache.cache_table
15
+ #
16
+ # @return [ Hash ] The hash of cached queries.
17
+ #
18
+ def cache_table
19
+ Thread.current["[mongoid]:query_cache"] ||= {}
20
+ end
21
+
22
+ # Clear the query cache.
23
+ #
24
+ # @example Clear the cache.
25
+ # QueryCache.clear_cache
26
+ #
27
+ # @return [ nil ] Always nil.
28
+ #
29
+ def clear_cache
30
+ Thread.current["[mongoid]:query_cache"] = nil
31
+ end
32
+
33
+ # Set whether the cache is enabled.
34
+ #
35
+ # @example Set if the cache is enabled.
36
+ # QueryCache.enabled = true
37
+ #
38
+ # @param [ true, false ] value The enabled value.
39
+ #
40
+ def enabled=(value)
41
+ Thread.current["[mongoid]:query_cache:enabled"] = value
42
+ end
43
+
44
+ # Is the query cache enabled on the current thread?
45
+ #
46
+ # @example Is the query cache enabled?
47
+ # QueryCache.enabled?
48
+ #
49
+ # @return [ true, false ] If the cache is enabled.
50
+ #
51
+ def enabled?
52
+ !!Thread.current["[mongoid]:query_cache:enabled"]
53
+ end
54
+
55
+ # Execute the block while using the query cache.
56
+ #
57
+ # @example Execute with the cache.
58
+ # QueryCache.cache { collection.find }
59
+ #
60
+ # @return [ Object ] The result of the block.
61
+ #
62
+ def cache
63
+ enabled = QueryCache.enabled?
64
+ QueryCache.enabled = true
65
+ yield
66
+ ensure
67
+ QueryCache.enabled = enabled
68
+ end
69
+ end
70
+
71
+ # The middleware to be added to a rack application in order to activate the
72
+ # query cache.
73
+ #
74
+ class Middleware
75
+
76
+ # Instantiate the middleware.
77
+ #
78
+ # @example Create the new middleware.
79
+ # Middleware.new(app)
80
+ #
81
+ # @param [ Object ] app The rack applciation stack.
82
+ #
83
+ def initialize(app)
84
+ @app = app
85
+ end
86
+
87
+ # Execute the request, wrapping in a query cache.
88
+ #
89
+ # @example Execute the request.
90
+ # middleware.call(env)
91
+ #
92
+ # @param [ Object ] env The environment.
93
+ #
94
+ # @return [ Object ] The result of the call.
95
+ #
96
+ def call(env)
97
+ QueryCache.cache { @app.call(env) }
98
+ ensure
99
+ QueryCache.clear_cache
100
+ end
101
+ end
102
+
103
+ module Base # :nodoc:
104
+
105
+ def alias_query_cache_clear(*method_names)
106
+ method_names.each do |method_name|
107
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
108
+ def #{method_name}_with_clear_cache(*args) # def upsert_with_clear_cache(*args)
109
+ QueryCache.clear_cache # QueryCache.clear_cache
110
+ #{method_name}_without_clear_cache(*args) # upsert_without_clear_cache(*args)
111
+ end # end
112
+ CODE
113
+
114
+ alias_method_chain method_name, :clear_cache
115
+ end
116
+ end
117
+ end
118
+
119
+ # Module to include in objects which need to wrap caching behaviour around
120
+ # them.
121
+ #
122
+ module Cacheable
123
+
124
+ private
125
+
126
+ def with_cache(context = :cursor, &block)
127
+ return yield unless QueryCache.enabled?
128
+ return yield if system_collection?
129
+ key = cache_key.push(context)
130
+
131
+ if QueryCache.cache_table.has_key?(key)
132
+ instrument(key) { QueryCache.cache_table[key] }
133
+ else
134
+ QueryCache.cache_table[key] = yield
135
+ end
136
+ end
137
+
138
+ def instrument(key, &block)
139
+ ActiveSupport::Notifications.instrument("query_cache.mongoid", key: key, &block)
140
+ end
141
+ end
142
+
143
+ # Adds behaviour around caching to a Moped Query object.
144
+ #
145
+ module Query
146
+ extend ActiveSupport::Concern
147
+ include Cacheable
148
+
149
+ included do
150
+ extend QueryCache::Base
151
+ alias_method_chain :cursor, :cache
152
+ alias_method_chain :first, :cache
153
+ alias_query_cache_clear :remove, :remove_all, :update, :update_all, :upsert
154
+ end
155
+
156
+ # Provide a wrapped query cache cursor.
157
+ #
158
+ # @example Get the wrapped caching cursor.
159
+ # query.cursor_with_cache
160
+ #
161
+ # @return [ CachedCursor ] The cached cursor.
162
+ #
163
+ def cursor_with_cache
164
+ CachedCursor.new(session, operation)
165
+ end
166
+
167
+ # Override first with caching.
168
+ #
169
+ # @example Get the first with a cache.
170
+ # query.first_with_cache
171
+ #
172
+ # @return [ Hash ] The first document.
173
+ #
174
+ def first_with_cache
175
+ with_cache(:first) do
176
+ first_without_cache
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ def cache_key
183
+ [ operation.database, operation.collection, operation.selector, operation.limit, operation.skip, operation.fields ]
184
+ end
185
+
186
+ def system_collection?
187
+ operation.collection =~ /^system./
188
+ end
189
+ end
190
+
191
+ # Adds behaviour to the query cache for collections.
192
+ #
193
+ module Collection
194
+ extend ActiveSupport::Concern
195
+
196
+ included do
197
+ extend QueryCache::Base
198
+ alias_query_cache_clear :insert
199
+ end
200
+ end
201
+
202
+ # A Cursor that attempts to load documents from memory first before hitting
203
+ # the database if the same query has already been executed.
204
+ #
205
+ class CachedCursor < Moped::Cursor
206
+ include Cacheable
207
+
208
+ # Override the loading of docs to attempt to fetch from the cache.
209
+ #
210
+ # @example Load the documents.
211
+ # cursor.load_docs
212
+ #
213
+ # @return [ Array<Hash> ] The documents.
214
+ #
215
+ def load_docs
216
+ with_cache { super }
217
+ end
218
+
219
+ private
220
+
221
+ def cache_key
222
+ [ @database, @collection, @selector, @options[:limit], @options[:skip], @options[:fields] ]
223
+ end
224
+
225
+ def system_collection?
226
+ @collection =~ /^system./
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ Moped::Query.send(:include, Mongoid::QueryCache::Query)
233
+ Moped::Collection.send(:include, Mongoid::QueryCache::Collection)
@@ -0,0 +1,7 @@
1
+ module Mongoid::QueryCache
2
+ class Railtie < Rails::Railtie
3
+ initializer 'mongoid.query_cache.insert_middleware' do |app|
4
+ app.config.middleware.use 'Mongoid::QueryCache::Middleware'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module QueryCache
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mongoid/query_cache/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'mongoid-query_cache'
8
+ spec.version = Mongoid::QueryCache::VERSION
9
+ spec.authors = ['Philip Claren']
10
+ spec.email = ['philip.claren@googlemail.com']
11
+ spec.summary = 'Backport of the Mongoid 4 QueryCache for Mongoid 3.'
12
+ spec.description = 'Backport of the Mongoid 4 QueryCache for Mongoid 3.'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'rake', '~> 10.3'
23
+ spec.add_development_dependency 'rspec', '~> 2.13'
24
+
25
+ spec.add_dependency 'mongoid', '~> 3.1'
26
+ end
@@ -0,0 +1,8 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ database: mongoid_query_cache_test
5
+ hosts:
6
+ - localhost:27017
7
+ options:
8
+ consistency: :strong
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ class Band
4
+ include Mongoid::Document
5
+ end
6
+
7
+ describe Mongoid::QueryCache do
8
+
9
+ around do |spec|
10
+ Mongoid::QueryCache.clear_cache
11
+ Mongoid::QueryCache.cache { spec.run }
12
+ end
13
+
14
+ context 'when inserting an index' do
15
+
16
+ it 'does not cache the query' do
17
+ Mongoid::QueryCache.should_receive(:cache_table).never
18
+ Band.collection.indexes.create(name: 1)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe Mongoid::QueryCache::Middleware do
24
+
25
+ let :middleware do
26
+ Mongoid::QueryCache::Middleware.new(app)
27
+ end
28
+
29
+ context 'when not touching mongoid on the app' do
30
+
31
+ let(:app) do
32
+ ->(env) { @enabled = Mongoid::QueryCache.enabled?; [200, env, "app"] }
33
+ end
34
+
35
+ it 'returns success' do
36
+ code, _ = middleware.call({})
37
+ expect(code).to eq(200)
38
+ end
39
+
40
+ it 'enableds the query cache' do
41
+ middleware.call({})
42
+ expect(@enabled).to be true
43
+ end
44
+ end
45
+
46
+ context 'when querying on the app' do
47
+
48
+ let(:app) do
49
+ ->(env) {
50
+ Band.all.to_a
51
+ [200, env, "app"]
52
+ }
53
+ end
54
+
55
+ it 'returns success' do
56
+ code, _ = middleware.call({})
57
+ expect(code).to eq(200)
58
+ end
59
+
60
+ it 'cleans the query cache after reponds' do
61
+ middleware.call({})
62
+ expect(Mongoid::QueryCache.cache_table).to be_empty
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,15 @@
1
+ # Configure Rails Environment
2
+ ENV['RACK_ENV'] = 'test'
3
+
4
+ require 'bundler/setup'
5
+ Bundler.setup
6
+
7
+ require 'mongoid'
8
+ require 'mongoid/query_cache'
9
+
10
+ Mongoid.load!(File.expand_path('../../spec/config/mongoid.yml', __FILE__))
11
+
12
+
13
+ RSpec.configure do |config|
14
+ # some (optional) config here
15
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-query_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Philip Claren
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.13'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongoid
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ description: Backport of the Mongoid 4 QueryCache for Mongoid 3.
70
+ email:
71
+ - philip.claren@googlemail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/mongoid/query_cache.rb
84
+ - lib/mongoid/query_cache/railtie.rb
85
+ - lib/mongoid/query_cache/version.rb
86
+ - mongoid-query_cache.gemspec
87
+ - spec/config/mongoid.yml
88
+ - spec/mongoid_query_cache_spec.rb
89
+ - spec/spec_helper.rb
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.2.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Backport of the Mongoid 4 QueryCache for Mongoid 3.
114
+ test_files:
115
+ - spec/config/mongoid.yml
116
+ - spec/mongoid_query_cache_spec.rb
117
+ - spec/spec_helper.rb