artirix_data_models 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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