artirix_data_models 0.5.0

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +17 -0
  5. data/Gemfile +18 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +230 -0
  8. data/Rakefile +6 -0
  9. data/artirix_data_models.gemspec +36 -0
  10. data/lib/artirix_data_models/aggregation.rb +58 -0
  11. data/lib/artirix_data_models/aggregations_factory.rb +45 -0
  12. data/lib/artirix_data_models/cache_service.rb +168 -0
  13. data/lib/artirix_data_models/cached_action_adaptor/get.rb +22 -0
  14. data/lib/artirix_data_models/cached_action_adaptor/get_full.rb +80 -0
  15. data/lib/artirix_data_models/cached_action_adaptor/get_some.rb +22 -0
  16. data/lib/artirix_data_models/cached_action_adaptor.rb +118 -0
  17. data/lib/artirix_data_models/dao.rb +172 -0
  18. data/lib/artirix_data_models/dao_registry.rb +94 -0
  19. data/lib/artirix_data_models/daos/basic_model_dao.rb +132 -0
  20. data/lib/artirix_data_models/daos/model_fields_dao.rb +37 -0
  21. data/lib/artirix_data_models/es_collection.rb +221 -0
  22. data/lib/artirix_data_models/fake_response_factory.rb +88 -0
  23. data/lib/artirix_data_models/gateway_response_adaptors/model_adaptor.rb +68 -0
  24. data/lib/artirix_data_models/gateways/data_gateway.rb +135 -0
  25. data/lib/artirix_data_models/model.rb +414 -0
  26. data/lib/artirix_data_models/spec_support/fake_mode.rb +24 -0
  27. data/lib/artirix_data_models/spec_support/gateway_mock.rb +23 -0
  28. data/lib/artirix_data_models/spec_support/shared_examples/a_readonly_active_model_like_artirix_data_models.rb +20 -0
  29. data/lib/artirix_data_models/spec_support/shared_examples/an_artirix_data_model_dao.rb +97 -0
  30. data/lib/artirix_data_models/spec_support/shared_examples/an_artirix_data_model_model.rb +224 -0
  31. data/lib/artirix_data_models/spec_support/shared_examples/has_attributes.rb +32 -0
  32. data/lib/artirix_data_models/spec_support/shared_examples.rb +4 -0
  33. data/lib/artirix_data_models/spec_support.rb +3 -0
  34. data/lib/artirix_data_models/version.rb +3 -0
  35. data/lib/artirix_data_models.rb +126 -0
  36. data/spec/artirix_data_models/dao_registry_spec.rb +21 -0
  37. data/spec/artirix_data_models/es_collection_spec.rb +45 -0
  38. data/spec/artirix_data_models/gateways/data_gateway_spec.rb +218 -0
  39. data/spec/artirix_data_models/gateways/gateway_response_adaptors/model_adaptor_spec.rb +78 -0
  40. data/spec/artirix_data_models/model_fields_dao_spec.rb +40 -0
  41. data/spec/spec_helper.rb +18 -0
  42. data/spec/support/.keep +0 -0
  43. data/spec/support/a_finder_enabled_ui_model_dao.rb +36 -0
  44. data/spec/support/a_search_enabled_ui_model_dao.rb +40 -0
  45. data/spec/support/artirix_data_models.rb +1 -0
  46. metadata +281 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6a90c9b7956cc31c38374094fd416d8d4e9dd09
4
+ data.tar.gz: 3cf3edcbf15f24b14b7beb57943b9f93bb12dbaa
5
+ SHA512:
6
+ metadata.gz: 568c1f293797134592df3bd5bca0ba3daacf0ede0aff7770004b5a3aae4821f9ae8eb2df8a668607bff2bfcb4f31bc6ea1a8c334b213084c19763ddebe578714
7
+ data.tar.gz: 5e27b33a022ccb060b174fb4466fb62bea449cc8c6ff8a5b3b405482b20f0f7c14eba73eeeddd4f62b31d447b0f2999d0afa8cf2485f095eda3ff3d425dea8bc
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_install: gem install bundler -v 1.10.3
5
+
6
+ addons:
7
+ code_climate:
8
+ repo_token: 84e47c3e41ba9fbc2d639c167be45aa3f6c077374015309dac005ab51f713d83
9
+
10
+ script: 'bundle exec rake spec'
11
+
12
+ notifications:
13
+ email:
14
+ recipients:
15
+ - eturino@eturino.com
16
+ on_failure: change
17
+ on_success: never
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in artirix_data_models.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry'
8
+ gem 'pry-nav'
9
+ gem 'pry-stack_explorer'
10
+ gem 'pry-doc'
11
+ gem 'pry-rescue'
12
+ end
13
+
14
+ group :test do
15
+ gem 'fakeredis', require: "fakeredis/rspec"
16
+ end
17
+
18
+ gem 'codeclimate-test-reporter', :group => :test, :require => nil
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eduardo Turiño
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,230 @@
1
+ # ArtirixDataModels
2
+
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/artirix_data_models.svg)](http://badge.fury.io/rb/artirix_data_models)
5
+ [![Build Status](https://travis-ci.org/artirix/artirix_data_models.svg?branch=master)](https://travis-ci.org/artirix/artirix_data_models)
6
+ [![Code Climate](https://codeclimate.com/github/artirix/artirix_data_models.png)](https://codeclimate.com/github/artirix/artirix_data_models)
7
+ [![Code Climate Coverage](https://codeclimate.com/github/artirix/artirix_data_models/coverage.png)](https://codeclimate.com/github/artirix/artirix_data_models)
8
+
9
+
10
+ This gem provides the tools for building Data Models (ActiveModel compliant objects that only receive attributes on initialisation),
11
+ with their DAOs (Data Access Objects, the ones responsible for loading them up), the EsCollection objects (collection of
12
+ objects, paginatable and with extra features), and tools that allow them to work.
13
+
14
+ Its goal is to provide a set of Read Only model objects that receive their data from some sort of Data API.
15
+
16
+ It's designed to work assuming JSON APIs and ElasticSearch responses.
17
+
18
+ # TODO:
19
+ - usage doc
20
+ - change Cache to use [artirix_cache_service](https://github.com/artirix/artirix_cache_service)
21
+
22
+
23
+ ## Usage
24
+
25
+ ### Model
26
+
27
+ TODO:
28
+
29
+ ### DAO
30
+
31
+ TODO:
32
+
33
+ ### EsCollection
34
+
35
+ TODO:
36
+
37
+ #### Pagination
38
+
39
+ TODO:
40
+
41
+ ### The Registry
42
+
43
+ Your app should extend the `ArtirixDataModels::DAORegistry`. We can override the `setup_config` method to add extra loaders.
44
+
45
+ **important: do not forget to call `super` on `setup_config`.**
46
+
47
+ Also, the Registry class that you want to use in your app should have in its definition a call to `self.mark_as_main_registry`. This call must be **after the override of `setup_config`.**
48
+
49
+ ```ruby
50
+ class DAORegistry < ArtirixDataModels::DAORegistry
51
+ def setup_config
52
+ super
53
+
54
+ set_loader(:aggregations_factory) { AggregationsFactory.new }
55
+
56
+ set_loader(:yacht) { YachtDAO.new gateway: get(:gateway) }
57
+ set_loader(:article) { ArticleDAO.new gateway: get(:gateway) }
58
+ set_loader(:broker) { BrokerDAO.new gateway: get(:gateway) }
59
+
60
+ set_loader(:artirix_hub_api_gateway) { ArtirixDataModels::DataGateway.new connection: ArtirixHubApiService::ConnectionLoader.connection }
61
+ set_loader(:lead) { LeadDAO.new gateway: get(:artirix_hub_api_gateway) }
62
+ end
63
+
64
+
65
+ # AFTER defining setup_config
66
+ self.mark_as_main_registry
67
+
68
+ end
69
+ ```
70
+
71
+ ### initializer
72
+
73
+ An initializer should be added for extra configuration.
74
+
75
+ We can enable pagination with either `will_paginate` or `kaminari`.
76
+
77
+ We can also disable cache at a lib level.
78
+
79
+ ```ruby
80
+ require 'artirix_data_models'
81
+
82
+ # pagination
83
+ ArtirixDataModels::EsCollection.work_with_kaminari
84
+ # or ArtirixDataModels::EsCollection.work_with_will_paginate
85
+
86
+ #cache
87
+ ArtirixDataModels.disable_cache unless Rails.configuration.dao_cache_enabled
88
+ ```
89
+
90
+
91
+ ### Cache
92
+
93
+ By default all `get`, `get_full` and `get_some` calls to on a normal DAO will be cached. The response body and status of the Gateway is cached (if it is successful or a 404 error).
94
+
95
+ The cache key and the options will be determined by the cache adaptor, set by the DAO. The options are loaded from SimpleConfig, merging `default_options` with the first most specific option hash.
96
+
97
+ For example, a DAO `get` call will try to load the first options hash defined from the following list:
98
+ - "dao_#{dao_name}_get_options"
99
+ - "dao_#{dao_name}_options"
100
+ - 'dao_get_options'
101
+
102
+
103
+ example of config options (using SimpleConfig)
104
+
105
+ ```
106
+ SimpleConfig.for(:site) do
107
+ set :cache_app_prefix, 'ui'
108
+
109
+ group :cache_options do
110
+ group :default_options do
111
+ set :expires_in, 15.minutes
112
+ end
113
+
114
+ group :dao_get_full_options do
115
+ set :expires_in, 1.hour
116
+ end
117
+
118
+ group :dao_get_full_no_time_options do
119
+ set :expires_in, 5.minutes
120
+ end
121
+
122
+ group :dao_yacht_get_full_options do
123
+ set :expires_in, 15.minutes
124
+ end
125
+ end
126
+ end
127
+ ```
128
+
129
+ Cache can be disabled at lib level with `ArtirixDataModels.disable_cache`
130
+
131
+ ### Rails integration
132
+
133
+ if Rails is defined when the lib is first used, then the `logger` will be assigned to `Rails.logger` by default, and
134
+ `cache` will be `Rails.cache` by default.
135
+
136
+ ### Fake Mode
137
+
138
+ TODO:
139
+
140
+ fake mode will be enabled if:
141
+
142
+ ```ruby
143
+ SimpleConfig.for(:site) do
144
+ group :data_fake_mode do
145
+ set :article, false # NO FAKE MODE
146
+ set :broker, false # WITH FAKE MODE
147
+ end
148
+ end
149
+ ```
150
+
151
+ ### Use with RSpec
152
+
153
+ #### Custom DAO Registry
154
+
155
+ For the use of a custom DAO Registry, it is recomended to actually require it on the test helper:
156
+
157
+
158
+ in spec/rails_helper.rb:
159
+
160
+ ```ruby
161
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
162
+ ENV["RAILS_ENV"] ||= 'test'
163
+ require 'rspec/given'
164
+ require 'spec_helper'
165
+ require File.expand_path("../../config/environment", __FILE__)
166
+ require 'rspec/rails'
167
+ # Add additional requires below this line. Rails is not loaded until this point!
168
+
169
+ # force the use of the custom DAORegistry
170
+ require 'dao_registry'
171
+ ```
172
+
173
+ #### Spec Support
174
+
175
+ add the spec support in your support files or rails_helper file:
176
+
177
+
178
+ ```ruby
179
+ require 'artirix_data_models/spec_support'
180
+ ```
181
+
182
+ This depends on SimpleConfig!
183
+
184
+ ```ruby
185
+ SimpleConfig.for(:site) do
186
+ group :data_gateway do
187
+ set :url, c
188
+ end
189
+ end
190
+ ```
191
+
192
+ ### FactoryGirl
193
+
194
+ In order to use FactoryGirl with these Models, we need to specify:
195
+
196
+ 1. the objects cannot be saved, so we need to specify `skip_create` to avoid it.
197
+ 2. the setting of the data is only to be done on the model's initialisation, not with public setters.
198
+ For that, we need to specify: `initialize_with { new(attributes) }`
199
+
200
+ ```ruby
201
+
202
+ FactoryGirl.define do
203
+ factory :article do
204
+ # no save call
205
+ skip_create
206
+
207
+ # in our models we have private setters -> we need the attributes to be
208
+ # passed on object initialisation
209
+ initialize_with { new(attributes) }
210
+
211
+ sequence(:id)
212
+ title { Faker::Lorem.sentence }
213
+ end
214
+ end
215
+ ```
216
+
217
+ ## TODO
218
+
219
+ 1. Documentation
220
+ 2. clean `basic_dao` (probably not backwards compatible, so we'll do it in a new major release)
221
+ 3. use [artirix_cache_service](https://github.com/artirix/artirix_cache_service) instead of this implementation (might be not backwards compatible. If so: new major release)
222
+
223
+
224
+
225
+ ## Changes
226
+
227
+ ### v.0.5.0
228
+
229
+ - opening gem as is to the public.
230
+ - still a lot of TODOs in the documentation
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'artirix_data_models/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'artirix_data_models'
8
+ spec.version = ArtirixDataModels::VERSION
9
+ spec.authors = ['Eduardo Turiño']
10
+ spec.email = ['eturino@artirix.com']
11
+ spec.summary = 'Data Models (read only model) and Data Layer connection lib'
12
+ spec.description = %q{used in Boat International UI and Admin apps}
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_dependency 'activesupport'
22
+ spec.add_dependency 'simpleconfig'
23
+ spec.add_dependency 'oj'
24
+ spec.add_dependency 'faraday'
25
+ spec.add_dependency 'keyword_init', '~> 1.3'
26
+ spec.add_dependency 'naught'
27
+
28
+ spec.add_development_dependency 'kaminari', '~> 0.16'
29
+ spec.add_development_dependency 'will_paginate', '~> 3.0'
30
+
31
+ spec.add_development_dependency 'bundler', '~> 1.10'
32
+ spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'rspec'
34
+ spec.add_development_dependency 'rspec-given'
35
+ spec.add_development_dependency 'faker'
36
+ end
@@ -0,0 +1,58 @@
1
+ module ArtirixDataModels
2
+ class Aggregation < Struct.new(:name, :buckets)
3
+
4
+ include Enumerable
5
+
6
+ delegate :each, :empty?, to: :buckets
7
+
8
+ def self.from_json(definition, value_class = Value)
9
+ buckets = definition[:buckets].map do |bucket|
10
+ value_class.new definition[:name].to_sym, bucket[:name], bucket[:count]
11
+ end
12
+
13
+ new definition[:name].to_sym, buckets
14
+ end
15
+
16
+ def pretty_name
17
+ I18n.t("aggregations.#{name.to_s.gsub('.', '_')}.name", default: default_pretty_name)
18
+ end
19
+
20
+ def default_pretty_name
21
+ name
22
+ end
23
+
24
+ def non_empty_buckets
25
+ buckets.reject { |x| x.empty? }
26
+ end
27
+
28
+ def data_hash
29
+ {
30
+ name: name,
31
+ buckets: buckets.map(&:data_hash)
32
+ }
33
+ end
34
+
35
+ class Value < Struct.new(:aggregation_name, :name, :count)
36
+
37
+ def pretty_name
38
+ tranlsation_key = "aggregations.#{aggregation_name.to_s.gsub('.', '_')}.buckets.#{name.to_s.gsub('.', '_')}"
39
+ I18n.t(tranlsation_key, default: default_pretty_name)
40
+ end
41
+
42
+ def default_pretty_name
43
+ name
44
+ end
45
+
46
+ def empty?
47
+ count == 0
48
+ end
49
+
50
+ def data_hash
51
+ {
52
+ name: name,
53
+ count: count
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,45 @@
1
+ module ArtirixDataModels
2
+ class AggregationsFactory
3
+ DEFAULT_FACTORY = ->(aggregation) { Aggregation.from_json aggregation }
4
+ DEFAULT_COLLECTION_CLASS_NAME = ''.freeze
5
+
6
+ # singleton instance
7
+ def initialize
8
+ @_loaders = Hash.new { |h, k| h[k] = {} }
9
+ setup_config
10
+ end
11
+
12
+ def setup_config
13
+ # To be Extended
14
+ end
15
+
16
+ def build_from_json(aggregation, collection_class = nil)
17
+ get_loader(aggregation[:name], collection_class).call aggregation
18
+ end
19
+
20
+ def get_loader(aggregation_name, collection_class)
21
+ @_loaders[collection_class.to_s][aggregation_name.to_s] ||
22
+ @_loaders[DEFAULT_COLLECTION_CLASS_NAME][aggregation_name.to_s] ||
23
+ DEFAULT_FACTORY
24
+ end
25
+
26
+ def set_loader(aggregation_name, collection_class = nil, loader = nil, &block)
27
+ if block
28
+ @_loaders[collection_class.to_s][aggregation_name.to_s] = block
29
+ elsif loader.respond_to? :call
30
+ @_loaders[collection_class.to_s][aggregation_name.to_s] = loader
31
+ else
32
+ raise ArgumentError, "no block and no loader given for key #{key}"
33
+ end
34
+ end
35
+
36
+ # static methods
37
+ def self.set_loader(aggregation_name, collection_class, loader = nil, &block)
38
+ instance.set_loader aggregation_name, collection_class, loader, &block
39
+ end
40
+
41
+ def self.build_from_json(aggregation_name, collection_class)
42
+ instance.build_from_json aggregation_name, collection_class
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,168 @@
1
+ module ArtirixDataModels::CacheService
2
+
3
+ def self.digest_element(element)
4
+ Digest::SHA1.hexdigest element.to_s
5
+ end
6
+
7
+ def self.first_options(*options, return_if_none: :default)
8
+ key = options.detect { |x| OptionsStore.has? x }
9
+ return OptionsStore.get(key) if key.present?
10
+
11
+ case return_if_none
12
+ when NilClass
13
+ nil
14
+ when :default
15
+ OptionsStore.default.dup
16
+ else
17
+ {}
18
+ end
19
+ end
20
+
21
+ def self.method_missing(m, *args, &block)
22
+ method = m.to_s
23
+
24
+ if KeyCleaner.valid_method method
25
+ KeyCleaner.final_key(m, *args)
26
+
27
+ elsif OptionsStore.valid_method method
28
+ OptionsStore.send m, *args, &block
29
+
30
+ elsif Expirer.valid_method method
31
+ Expirer.send m, *args, &block
32
+
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def self.respond_to_missing?(m, include_all = false)
39
+ method = m.to_s
40
+
41
+ if KeyCleaner.valid_method method
42
+ true
43
+
44
+ elsif OptionsStore.valid_method method
45
+ OptionsStore.respond_to? m, include_all
46
+
47
+ elsif Expirer.valid_method method
48
+ Expirer.respond_to? m, include_all
49
+
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ module KeyCleaner
58
+ def self.valid_method(method_name)
59
+ method_name.end_with? '_key'
60
+ end
61
+
62
+ def self.final_key(m, *args)
63
+ cleaned = clean_key_section(m, *args)
64
+ CacheStoreHelper.final_key cleaned
65
+ end
66
+
67
+ private
68
+ def self.clean_key_section(key, *args)
69
+ key_name = clean_key_name key
70
+ a = clean_key_args args
71
+ suffix = a.present? ? "/#{a}" : ''
72
+ "#{key_name}#{suffix}"
73
+ end
74
+
75
+ def self.clean_key_name(key)
76
+ key.to_s.gsub(/_key$/, '').to_sym
77
+ end
78
+
79
+ def self.clean_key_args(args)
80
+ args.map { |x| x.try(:cache_key) || x.to_s }.join '/'
81
+ end
82
+ end
83
+
84
+ module OptionsStore
85
+ def self.valid_method(method_name)
86
+ method_name.end_with? '_options'
87
+ end
88
+
89
+ def self.method_missing(m, *args, &block)
90
+ if has?(m)
91
+ get(m)
92
+ else
93
+ super
94
+ end
95
+ end
96
+
97
+ def self.respond_to_missing?(m, include_all = false)
98
+ has?(m) || super
99
+ end
100
+
101
+ private
102
+ def self.has?(name)
103
+ option_store.respond_to?(name)
104
+ end
105
+
106
+ def self.get(name)
107
+ default.merge(get_particular(name))
108
+ end
109
+
110
+ def self.get_particular(name)
111
+ Hash(option_store.send(name))
112
+ end
113
+
114
+ def self.default
115
+ @default ||= Hash(option_store.default_options)
116
+ end
117
+
118
+ def self.option_store
119
+ @option_store ||= SimpleConfig.for(:site).try(:cache_options) || disabled_options_store
120
+ end
121
+
122
+ def self.disabled_options_store
123
+ DisabledOptionsStore.new
124
+ end
125
+
126
+ class DisabledOptionsStore
127
+ def method_missing(m, *args, &block)
128
+ {}
129
+ end
130
+
131
+ def respond_to_missing?(m, include_all = false)
132
+ true
133
+ end
134
+ end
135
+ end
136
+
137
+ module Expirer
138
+ def self.valid_method(method_name)
139
+ method_name.start_with? 'expire_'
140
+ end
141
+
142
+ def self.expire_cache(pattern = nil)
143
+ CacheStoreHelper.delete_matched(pattern)
144
+ end
145
+ end
146
+
147
+ # we use `delete_matched` method -> it will work fine with Redis but it seems that it won't with Memcached
148
+ module CacheStoreHelper
149
+ def self.final_key(key_value)
150
+ "#{prefix}__#{key_value}"
151
+ end
152
+
153
+ def self.final_pattern(pattern)
154
+ suf = pattern.present? ? "#{pattern}*" : ''
155
+ "*#{prefix}*#{suf}"
156
+ end
157
+
158
+ def self.delete_matched(pattern = nil)
159
+ return false unless ArtirixDataModels.cache.present?
160
+ ArtirixDataModels.cache.delete_matched final_pattern(pattern)
161
+ end
162
+
163
+ def self.prefix
164
+ SimpleConfig.for(:site).try(:cache_app_prefix)
165
+ end
166
+ end
167
+
168
+ end
@@ -0,0 +1,22 @@
1
+ class ArtirixDataModels::CachedActionAdaptor::Get < ArtirixDataModels::CachedActionAdaptor
2
+
3
+ attr_reader :dao_name, :model_pk
4
+
5
+ def initialize(dao_name:, model_pk:, **extra_options)
6
+ @dao_name = dao_name
7
+ @model_pk = model_pk
8
+
9
+ super(**extra_options)
10
+ end
11
+
12
+ def load_cache_key
13
+ ArtirixDataModels::CacheService.dao_get_key(dao_name, model_pk)
14
+ end
15
+
16
+ def load_cache_options
17
+ ArtirixDataModels::CacheService.first_options "dao_#{dao_name}_get_options",
18
+ "dao_#{dao_name}_options",
19
+ 'dao_get_options',
20
+ return_if_none: :default
21
+ end
22
+ end