mongoid-cached-json 1.5.1 → 1.5.2

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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +6 -0
  5. data/.rubocop_todo.yml +80 -0
  6. data/.travis.yml +16 -0
  7. data/CHANGELOG.md +85 -0
  8. data/CONTRIBUTING.md +118 -0
  9. data/Gemfile +21 -0
  10. data/README.md +49 -52
  11. data/Rakefile +34 -0
  12. data/lib/mongoid-cached-json.rb +0 -1
  13. data/lib/mongoid-cached-json/array.rb +1 -3
  14. data/lib/mongoid-cached-json/cached_json.rb +52 -50
  15. data/lib/mongoid-cached-json/config.rb +20 -21
  16. data/lib/mongoid-cached-json/hash.rb +1 -3
  17. data/lib/mongoid-cached-json/key_references.rb +0 -3
  18. data/lib/mongoid-cached-json/mongoid_criteria.rb +1 -3
  19. data/lib/mongoid-cached-json/version.rb +1 -2
  20. data/mongoid-cached-json.gemspec +17 -0
  21. data/spec/array_spec.rb +48 -0
  22. data/spec/benchmark_spec.rb +115 -0
  23. data/spec/cached_json_spec.rb +501 -0
  24. data/spec/config_spec.rb +21 -0
  25. data/spec/dalli_spec.rb +37 -0
  26. data/spec/hash_spec.rb +66 -0
  27. data/spec/mongoid_criteria_spec.rb +78 -0
  28. data/spec/spec_helper.rb +20 -0
  29. data/spec/support/awesome_artwork.rb +11 -0
  30. data/spec/support/awesome_image.rb +14 -0
  31. data/spec/support/fast_json_artwork.rb +15 -0
  32. data/spec/support/fast_json_image.rb +12 -0
  33. data/spec/support/fast_json_url.rb +12 -0
  34. data/spec/support/json_embedded_foobar.rb +5 -0
  35. data/spec/support/json_employee.rb +12 -0
  36. data/spec/support/json_foobar.rb +19 -0
  37. data/spec/support/json_manager.rb +14 -0
  38. data/spec/support/json_math.rb +9 -0
  39. data/spec/support/json_parent_foobar.rb +11 -0
  40. data/spec/support/json_polymorphic_embedded_foobar.rb +9 -0
  41. data/spec/support/json_polymorphic_referenced_foobar.rb +9 -0
  42. data/spec/support/json_referenced_foobar.rb +5 -0
  43. data/spec/support/json_supervisor.rb +13 -0
  44. data/spec/support/json_transform.rb +13 -0
  45. data/spec/support/matchers/invalidate.rb +22 -0
  46. data/spec/support/person.rb +20 -0
  47. data/spec/support/poly_company.rb +10 -0
  48. data/spec/support/poly_person.rb +10 -0
  49. data/spec/support/poly_post.rb +9 -0
  50. data/spec/support/prison_cell.rb +11 -0
  51. data/spec/support/prison_inmate.rb +12 -0
  52. data/spec/support/secret_parent.rb +11 -0
  53. data/spec/support/sometimes_secret.rb +11 -0
  54. data/spec/support/tool.rb +11 -0
  55. data/spec/support/tool_box.rb +10 -0
  56. metadata +62 -137
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ require File.expand_path('../lib/mongoid-cached-json/version', __FILE__)
5
+
6
+ Bundler.setup(:default, :development)
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ require 'rake'
10
+
11
+ require 'rspec/core'
12
+ require 'rspec/core/rake_task'
13
+
14
+ RSpec::Core::RakeTask.new(:spec) do |spec|
15
+ files = FileList['spec/**/*_spec.rb']
16
+ files = files.exclude 'spec/benchmark_spec.rb'
17
+ spec.pattern = files
18
+ end
19
+
20
+ require 'rdoc/task'
21
+ Rake::RDocTask.new do |rdoc|
22
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
23
+
24
+ rdoc.rdoc_dir = 'rdoc'
25
+ rdoc.title = "mongoid-cached-json #{version}"
26
+ rdoc.rdoc_files.include('README*')
27
+ rdoc.rdoc_files.include('LICENSE*')
28
+ rdoc.rdoc_files.include('lib/**/*.rb')
29
+ end
30
+
31
+ require 'rubocop/rake_task'
32
+ RuboCop::RakeTask.new
33
+
34
+ task default: [:rubocop, :spec]
@@ -8,4 +8,3 @@ require 'mongoid-cached-json/mongoid_criteria'
8
8
  require 'mongoid-cached-json/version'
9
9
  require 'mongoid-cached-json/config'
10
10
  require 'mongoid-cached-json/cached_json'
11
-
@@ -1,5 +1,4 @@
1
1
  class Array
2
-
3
2
  def as_json_partial(options = {})
4
3
  json_keys = nil
5
4
  json = map do |i|
@@ -11,12 +10,11 @@ class Array
11
10
  i.as_json(options)
12
11
  end
13
12
  end
14
- [ json_keys, json ]
13
+ [json_keys, json]
15
14
  end
16
15
 
17
16
  def as_json(options = {})
18
17
  json_keys, json = as_json_partial(options)
19
18
  Mongoid::CachedJson.materialize_json_references_with_read_multi(json_keys, json)
20
19
  end
21
-
22
20
  end
@@ -12,33 +12,32 @@ module Mongoid
12
12
  end
13
13
 
14
14
  module ClassMethods
15
-
16
15
  # Define JSON fields for a class.
17
16
  #
18
17
  # @param [ hash ] defs JSON field definition.
19
18
  #
20
19
  # @since 1.0
21
20
  def json_fields(defs)
22
- self.hide_as_child_json_when = defs.delete(:hide_as_child_json_when) || lambda { |a| false }
23
- self.all_json_properties = [ :short, :public, :all ]
24
- cached_json_defs = Hash[defs.map { |k,v| [k, { :type => :callable, :properties => :short, :definition => k }.merge(v)] }]
21
+ self.hide_as_child_json_when = defs.delete(:hide_as_child_json_when) || lambda { |_a| false }
22
+ self.all_json_properties = [:short, :public, :all]
23
+ cached_json_defs = Hash[defs.map { |k, v| [k, { type: :callable, properties: :short, definition: k }.merge(v)] }]
25
24
  self.cached_json_field_defs = {}
26
25
  self.cached_json_reference_defs = {}
27
26
  # Collect all versions for clearing cache
28
- self.all_json_versions = cached_json_defs.map do |field, definition|
29
- [ :unspecified, definition[:version], Array(definition[:versions]) ]
27
+ self.all_json_versions = cached_json_defs.map do |_field, definition|
28
+ [:unspecified, definition[:version], Array(definition[:versions])]
30
29
  end.flatten.compact.uniq
31
- self.all_json_properties.each_with_index do |property, i|
32
- self.cached_json_field_defs[property] = Hash[cached_json_defs.find_all do |field, definition|
33
- self.all_json_properties.find_index(definition[:properties]) <= i && definition[:type] == :callable
30
+ all_json_properties.each_with_index do |property, i|
31
+ cached_json_field_defs[property] = Hash[cached_json_defs.find_all do |_field, definition|
32
+ all_json_properties.find_index(definition[:properties]) <= i && definition[:type] == :callable
34
33
  end]
35
- self.cached_json_reference_defs[property] = Hash[cached_json_defs.find_all do |field, definition|
36
- self.all_json_properties.find_index(definition[:properties]) <= i && definition[:type] == :reference
34
+ cached_json_reference_defs[property] = Hash[cached_json_defs.find_all do |_field, definition|
35
+ all_json_properties.find_index(definition[:properties]) <= i && definition[:type] == :reference
37
36
  end]
38
37
  # If the field is a reference and is just specified as a symbol, reflect on it to get metadata
39
- self.cached_json_reference_defs[property].to_a.each do |field, definition|
38
+ cached_json_reference_defs[property].to_a.each do |field, definition|
40
39
  if definition[:definition].is_a?(Symbol)
41
- self.cached_json_reference_defs[property][field][:metadata] = self.reflect_on_association(definition[:definition])
40
+ cached_json_reference_defs[property][field][:metadata] = reflect_on_association(definition[:definition])
42
41
  end
43
42
  end
44
43
  end
@@ -49,20 +48,20 @@ module Mongoid
49
48
  # Materialize a cached JSON within a cache block.
50
49
  def materialize_cached_json(clazz, id, object_reference, options)
51
50
  is_top_level_json = options[:is_top_level_json] || false
52
- object_reference = clazz.where({ :_id => id }).first if !object_reference
51
+ object_reference = clazz.where(_id: id).first unless object_reference
53
52
  if !object_reference || (!is_top_level_json && options[:properties] != :all && clazz.hide_as_child_json_when.call(object_reference))
54
53
  nil
55
54
  else
56
55
  Hash[clazz.cached_json_field_defs[options[:properties]].map do |field, definition|
57
56
  # version match
58
- versions = ([definition[:version] ] | Array(definition[:versions])).compact
59
- next unless versions.empty? or versions.include?(options[:version])
57
+ versions = ([definition[:version]] | Array(definition[:versions])).compact
58
+ next unless versions.empty? || versions.include?(options[:version])
60
59
  json_value = (definition[:definition].is_a?(Symbol) ? object_reference.send(definition[:definition]) : definition[:definition].call(object_reference))
61
60
  Mongoid::CachedJson.config.transform.each do |t|
62
61
  json_value = t.call(field, definition, json_value)
63
62
  end
64
63
  [field, json_value]
65
- end]
64
+ end.compact]
66
65
  end
67
66
  end
68
67
 
@@ -73,7 +72,7 @@ module Mongoid
73
72
  # the JSON by calling resolve_json_reference on each of them (which may, in turn,
74
73
  # call materialize_json)
75
74
  def materialize_json(options, object_def)
76
- return nil if !object_def[:object] and !object_def[:id]
75
+ return nil if !object_def[:object] && !object_def[:id]
77
76
  is_top_level_json = options[:is_top_level_json] || false
78
77
  if object_def[:object]
79
78
  object_reference = object_def[:object]
@@ -82,18 +81,18 @@ module Mongoid
82
81
  object_reference = nil
83
82
  clazz, id = object_def[:clazz], object_def[:id]
84
83
  end
85
- key = self.cached_json_key(options, clazz, id)
86
- json = { :_ref => { :_clazz => self, :_key => key, :_materialize_cached_json => [ clazz, id, object_reference, options ] }}
84
+ key = cached_json_key(options, clazz, id)
85
+ json = { _ref: { _clazz: self, _key: key, _materialize_cached_json: [clazz, id, object_reference, options] } }
87
86
  keys = KeyReferences.new
88
87
  keys.set_and_add(key, json)
89
88
  reference_defs = clazz.cached_json_reference_defs[options[:properties]]
90
- if !reference_defs.empty?
91
- object_reference = clazz.where({ :_id => id }).first if !object_reference
89
+ unless reference_defs.empty?
90
+ object_reference = clazz.where(_id: id).first unless object_reference
92
91
  if object_reference && (is_top_level_json || options[:properties] == :all || !clazz.hide_as_child_json_when.call(object_reference))
93
92
  json.merge!(Hash[reference_defs.map do |field, definition|
94
93
  json_properties_type = definition[:reference_properties] || ((options[:properties] == :all) ? :all : :short)
95
- reference_keys, reference = clazz.resolve_json_reference(options.merge({ :properties => json_properties_type, :is_top_level_json => false}), object_reference, field, definition)
96
- if (reference.is_a?(Hash) && ref = reference[:_ref])
94
+ reference_keys, reference = clazz.resolve_json_reference(options.merge(properties: json_properties_type, is_top_level_json: false), object_reference, field, definition)
95
+ if reference.is_a?(Hash) && ref = reference[:_ref]
97
96
  ref[:_parent] = json
98
97
  ref[:_field] = field
99
98
  end
@@ -102,7 +101,7 @@ module Mongoid
102
101
  end])
103
102
  end
104
103
  end
105
- [ keys, json ]
104
+ [keys, json]
106
105
  end
107
106
 
108
107
  # Cache key.
@@ -115,7 +114,7 @@ module Mongoid
115
114
  # representation by the (class, id) pair definition of the reference. That is, we may
116
115
  # be able to load the as_json representation from the cache without even getting the
117
116
  # model from the database and materializing it through Mongoid. We'll try to do this first.
118
- def resolve_json_reference(options, object, field, reference_def)
117
+ def resolve_json_reference(options, object, _field, reference_def)
119
118
  keys = nil
120
119
  reference_json = nil
121
120
  if reference_def[:metadata]
@@ -127,16 +126,20 @@ module Mongoid
127
126
  end
128
127
  if reference_def[:metadata].relation == Mongoid::Relations::Referenced::ManyToMany
129
128
  object_ids = object.send(key)
130
- reference_json = object_ids ? object_ids.map do |id|
131
- materialize_keys, json = materialize_json(options, { :clazz => clazz, :id => id })
132
- keys = keys ? keys.merge_set(materialize_keys) : materialize_keys
133
- json
134
- end.compact : []
129
+ if object_ids
130
+ reference_json = object_ids.map do |id|
131
+ materialize_keys, json = materialize_json(options, clazz: clazz, id: id)
132
+ keys = keys ? keys.merge_set(materialize_keys) : materialize_keys
133
+ json
134
+ end.compact
135
+ else
136
+ object_ids = []
137
+ end
135
138
  end
136
139
  end
137
140
  # If we get to this point and reference_json is still nil, there's no chance we can
138
141
  # load the JSON from cache so we go ahead and call as_json on the object.
139
- if ! reference_json
142
+ unless reference_json
140
143
  reference_def_definition = reference_def[:definition]
141
144
  reference = reference_def_definition.is_a?(Symbol) ? object.send(reference_def_definition) : reference_def_definition.call(object)
142
145
  reference_json = nil
@@ -149,9 +152,8 @@ module Mongoid
149
152
  end
150
153
  end
151
154
  end
152
- [ keys, reference_json ]
155
+ [keys, reference_json]
153
156
  end
154
-
155
157
  end
156
158
 
157
159
  # Check whether the cache supports :read_multi and prefetch the data if it does.
@@ -169,15 +171,15 @@ module Mongoid
169
171
  refs.each do |ref|
170
172
  _ref = ref.delete(:_ref)
171
173
  key = _ref[:_key]
172
- fetched_json = local_cache[key] if local_cache.has_key?(key)
173
- if ! fetched_json
174
+ fetched_json = local_cache[key] if local_cache.key?(key)
175
+ unless fetched_json
174
176
  if read_multi
175
177
  # no value in cache, materialize and write
176
178
  fetched_json = (local_cache[key] = _ref[:_clazz].materialize_cached_json(* _ref[:_materialize_cached_json]))
177
- Mongoid::CachedJson.config.cache.write(key, fetched_json) unless !! Mongoid::CachedJson.config.disable_caching
179
+ Mongoid::CachedJson.config.cache.write(key, fetched_json) unless Mongoid::CachedJson.config.disable_caching
178
180
  else
179
181
  # fetch/write from cache
180
- fetched_json = (local_cache[key] = Mongoid::CachedJson.config.cache.fetch(key, { :force => !! Mongoid::CachedJson.config.disable_caching }) do
182
+ fetched_json = (local_cache[key] = Mongoid::CachedJson.config.cache.fetch(key, force: !!Mongoid::CachedJson.config.disable_caching) do
181
183
  _ref[:_clazz].materialize_cached_json(* _ref[:_materialize_cached_json])
182
184
  end)
183
185
  end
@@ -195,14 +197,14 @@ module Mongoid
195
197
  # Return a partial JSON without resolved references and all the keys.
196
198
  def as_json_partial(options = {})
197
199
  options ||= {}
198
- if options[:properties] and ! self.all_json_properties.member?(options[:properties])
199
- raise ArgumentError.new("Unknown properties option: #{options[:properties]}")
200
+ if options[:properties] && !all_json_properties.member?(options[:properties])
201
+ fail ArgumentError.new("Unknown properties option: #{options[:properties]}")
200
202
  end
201
203
  # partial, unmaterialized JSON
202
204
  keys, partial_json = self.class.materialize_json({
203
- :properties => :short, :is_top_level_json => true, :version => Mongoid::CachedJson.config.default_version
204
- }.merge(options), { :object => self })
205
- [ keys, partial_json ]
205
+ properties: :short, is_top_level_json: true, version: Mongoid::CachedJson.config.default_version
206
+ }.merge(options), object: self)
207
+ [keys, partial_json]
206
208
  end
207
209
 
208
210
  # Fetch the partial JSON and materialize all JSON references.
@@ -218,19 +220,20 @@ module Mongoid
218
220
 
219
221
  # Expire all JSON entries for this class.
220
222
  def expire_cached_json
221
- self.all_json_properties.each do |properties|
223
+ all_json_properties.each do |properties|
222
224
  [true, false].each do |is_top_level_json|
223
- self.all_json_versions.each do |version|
225
+ all_json_versions.each do |version|
224
226
  Mongoid::CachedJson.config.cache.delete(self.class.cached_json_key({
225
- :properties => properties, :is_top_level_json => is_top_level_json, :version => version
226
- }, self.class, self.id))
227
+ properties: properties,
228
+ is_top_level_json: is_top_level_json,
229
+ version: version
230
+ }, self.class, id))
227
231
  end
228
232
  end
229
233
  end
230
234
  end
231
235
 
232
236
  class << self
233
-
234
237
  # Set the configuration options. Best used by passing a block.
235
238
  #
236
239
  # @example Set up configuration options.
@@ -242,8 +245,7 @@ module Mongoid
242
245
  def configure
243
246
  block_given? ? yield(Mongoid::CachedJson::Config) : Mongoid::CachedJson::Config
244
247
  end
245
- alias :config :configure
248
+ alias_method :config, :configure
246
249
  end
247
-
248
250
  end
249
251
  end
@@ -1,19 +1,19 @@
1
1
  # encoding: utf-8
2
- module Mongoid
3
- module CachedJson
2
+ module Mongoid
3
+ module CachedJson
4
4
  module Config
5
5
  extend self
6
6
  include ActiveSupport::Callbacks
7
-
7
+
8
8
  # Current configuration settings.
9
9
  attr_accessor :settings
10
-
10
+
11
11
  # Default configuration settings.
12
12
  attr_accessor :defaults
13
-
13
+
14
14
  @settings = {}
15
15
  @defaults = {}
16
-
16
+
17
17
  # Define a configuration option with a default.
18
18
  #
19
19
  # @example Define the option.
@@ -25,25 +25,25 @@ module Mongoid
25
25
  # @option options [ Object ] :default The default value.
26
26
  def option(name, options = {})
27
27
  defaults[name] = settings[name] = options[:default]
28
-
28
+
29
29
  class_eval <<-RUBY
30
30
  def #{name}
31
31
  settings[#{name.inspect}]
32
32
  end
33
-
33
+
34
34
  def #{name}=(value)
35
35
  settings[#{name.inspect}] = value
36
36
  end
37
-
37
+
38
38
  def #{name}?
39
39
  #{name}
40
40
  end
41
41
  RUBY
42
42
  end
43
-
43
+
44
44
  # Disable caching.
45
- option :disable_caching, { :default => false }
46
-
45
+ option :disable_caching, default: false
46
+
47
47
  # Returns the default JSON version
48
48
  #
49
49
  # @example Get the default JSON version
@@ -51,7 +51,7 @@ module Mongoid
51
51
  #
52
52
  # @return [ Version ] The default JSON version.
53
53
  def default_version
54
- settings[:default_version] = :unspecified unless settings.has_key?(:default_version)
54
+ settings[:default_version] = :unspecified unless settings.key?(:default_version)
55
55
  settings[:default_version]
56
56
  end
57
57
 
@@ -64,7 +64,7 @@ module Mongoid
64
64
  def default_version=(default_version)
65
65
  settings[:default_version] = default_version
66
66
  end
67
-
67
+
68
68
  # Returns the default cache store, for example Rails cache or an instance of ActiveSupport::Cache::MemoryStore.
69
69
  #
70
70
  # @example Get the default cache store
@@ -74,7 +74,7 @@ module Mongoid
74
74
  def default_cache
75
75
  defined?(Rails) && Rails.respond_to?(:cache) ? Rails.cache : ::ActiveSupport::Cache::MemoryStore.new
76
76
  end
77
-
77
+
78
78
  # Returns the cache, or defaults to Rails cache when running under Rails or ActiveSupport::Cache::MemoryStore.
79
79
  #
80
80
  # @example Get the cache.
@@ -82,10 +82,10 @@ module Mongoid
82
82
  #
83
83
  # @return [ Cache ] The configured cache or a default cache instance.
84
84
  def cache
85
- settings[:cache] = default_cache unless settings.has_key?(:cache)
85
+ settings[:cache] = default_cache unless settings.key?(:cache)
86
86
  settings[:cache]
87
87
  end
88
-
88
+
89
89
  # Sets the cache to use.
90
90
  #
91
91
  # @example Set the cache.
@@ -95,7 +95,7 @@ module Mongoid
95
95
  def cache=(cache)
96
96
  settings[:cache] = cache
97
97
  end
98
-
98
+
99
99
  # Reset the configuration options to the defaults.
100
100
  #
101
101
  # @example Reset the configuration options.
@@ -103,7 +103,7 @@ module Mongoid
103
103
  def reset!
104
104
  settings.replace(defaults)
105
105
  end
106
-
106
+
107
107
  # Define a transformation on JSON data.
108
108
  #
109
109
  # @example Convert every string in materialized JSON to upper-case.
@@ -111,11 +111,10 @@ module Mongoid
111
111
  # value.upcase
112
112
  # end
113
113
  def transform(& block)
114
- settings[:transform] = [] unless settings.has_key?(:transform)
114
+ settings[:transform] = [] unless settings.key?(:transform)
115
115
  settings[:transform] << block if block_given?
116
116
  settings[:transform]
117
117
  end
118
-
119
118
  end
120
119
  end
121
120
  end
@@ -1,5 +1,4 @@
1
1
  class Hash
2
-
3
2
  def as_json_partial(options = {})
4
3
  json_keys = nil
5
4
  json = inject({}) do |h, (k, v)|
@@ -12,12 +11,11 @@ class Hash
12
11
  end
13
12
  h
14
13
  end
15
- [ json_keys, json ]
14
+ [json_keys, json]
16
15
  end
17
16
 
18
17
  def as_json(options = {})
19
18
  json_keys, json = as_json_partial(options)
20
19
  Mongoid::CachedJson.materialize_json_references_with_read_multi(json_keys, json)
21
20
  end
22
-
23
21
  end
@@ -3,7 +3,6 @@
3
3
  module Mongoid
4
4
  module CachedJson
5
5
  class KeyReferences < Hash
6
-
7
6
  def merge_set(keys)
8
7
  if keys
9
8
  keys.each_pair do |k, jsons|
@@ -19,8 +18,6 @@ module Mongoid
19
18
  self[key] << json
20
19
  self
21
20
  end
22
-
23
21
  end
24
22
  end
25
23
  end
26
-