artirix_data_models 0.22.1 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -5
- data/bin/rake +16 -0
- data/lib/artirix_data_models.rb +1 -0
- data/lib/artirix_data_models/aggregation.rb +7 -2
- data/lib/artirix_data_models/aggregations_factory.rb +8 -1
- data/lib/artirix_data_models/dao.rb +94 -18
- data/lib/artirix_data_models/dao_concerns/with_response_adaptors.rb +1 -1
- data/lib/artirix_data_models/dao_registry.rb +175 -15
- data/lib/artirix_data_models/daos/basic_model_dao.rb +32 -9
- data/lib/artirix_data_models/daos/model_fields_dao.rb +8 -3
- data/lib/artirix_data_models/es_collection.rb +34 -14
- data/lib/artirix_data_models/gateway_response_adaptors/model_adaptor.rb +8 -2
- data/lib/artirix_data_models/model.rb +11 -2
- data/lib/artirix_data_models/version.rb +1 -1
- data/lib/artirix_data_models/with_dao_registry.rb +73 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bfb65d885ba816daff5dafaf4f725cbacf35a6e
|
4
|
+
data.tar.gz: 84baf5c1431d2b39438ae646e85c450183227f35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04d9eb00b920c981e36cda90369f200df8c7449c5d9178a8bcd9f59d5c593ce3c6d3178ea2e7fb9954585e5a55ed323a7e02fafdf54141e605e6882a73c8e07b
|
7
|
+
data.tar.gz: 55772da2c303dd510e28956f13cebbad4e475b08c6a243813e3f373c08a73d2328ddfaca8c632829f6099f6732573d9ad1159afa673ac32aa36be2b6e77eacea
|
data/README.md
CHANGED
@@ -137,19 +137,21 @@ Your app should extend the `ArtirixDataModels::DAORegistry`. We can override the
|
|
137
137
|
|
138
138
|
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`.**
|
139
139
|
|
140
|
+
You can add loaders that will be called only and memoized with `set_persistent_loader` and loaders that will cbe called every time with `set_transient_loader`. `se_loader` is an alias of `set_persistent_loader`.
|
141
|
+
|
140
142
|
```ruby
|
141
143
|
class DAORegistry < ArtirixDataModels::DAORegistry
|
142
144
|
def setup_config
|
143
145
|
super
|
144
146
|
|
145
|
-
|
147
|
+
set_persistent_loader(:aggregations_factory) { AggregationsFactory.new }
|
146
148
|
|
147
|
-
|
148
|
-
|
149
|
-
|
149
|
+
set_transient_loader(:yacht) { YachtDAO.new gateway: get(:gateway) }
|
150
|
+
set_transient_loader(:article) { ArticleDAO.new gateway: get(:gateway) }
|
151
|
+
set_transient_loader(:broker) { BrokerDAO.new gateway: get(:gateway) }
|
150
152
|
|
151
153
|
set_loader(:artirix_hub_api_gateway) { ArtirixDataModels::DataGateway.new connection: ArtirixHubApiService::ConnectionLoader.connection }
|
152
|
-
|
154
|
+
set_transient_loader(:lead) { LeadDAO.new gateway: get(:artirix_hub_api_gateway) }
|
153
155
|
end
|
154
156
|
|
155
157
|
|
@@ -159,6 +161,16 @@ class DAORegistry < ArtirixDataModels::DAORegistry
|
|
159
161
|
end
|
160
162
|
```
|
161
163
|
|
164
|
+
You can use the DAORegistry by invoking it directly (or calling its instance) `DAORegistry.get(:name)` or `DAORegistry.instance.get(:name)`.
|
165
|
+
|
166
|
+
You can also use an identity map mode (see bellow)
|
167
|
+
|
168
|
+
### Identity Map
|
169
|
+
|
170
|
+
You can use `dao_registry = DAORegistry.with_identity_map`. Then, the DAO's default methods `get`, `find` and `get_some` will register the loaded models into the DAO, acting as an identity map, and will also use that identity map to check for the existence of models with those PKs, returning them if they are found.
|
171
|
+
|
172
|
+
The Identity Map does not have a TTL, so use it only with transient DAOs -> you don't want the identity map to live between requests, since that will mean that the models will never be forgotten, not being able to see new fresh versions, with the extra problem of memory leak.
|
173
|
+
|
162
174
|
### initializer
|
163
175
|
|
164
176
|
An initializer should be added for extra configuration.
|
@@ -315,6 +327,11 @@ end
|
|
315
327
|
|
316
328
|
## Changes
|
317
329
|
|
330
|
+
### 0.23.0
|
331
|
+
- DAORegistry now DI'ed into the DAOs and models, by adding `dao_registry_loader` or a direct `dao_registry`.
|
332
|
+
- DAORegistry with support for Identity Map
|
333
|
+
- deprecated the use of `Aggregation.from_json`, please use the factory.
|
334
|
+
|
318
335
|
### 0.22.1
|
319
336
|
|
320
337
|
added message support for DataGateway exceptions
|
data/bin/rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require "pathname"
|
10
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require "rubygems"
|
14
|
+
require "bundler/setup"
|
15
|
+
|
16
|
+
load Gem.bin_path("rake", "rake")
|
data/lib/artirix_data_models.rb
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
module ArtirixDataModels
|
2
2
|
class CommonAggregation
|
3
3
|
include Inspectable
|
4
|
+
include ArtirixDataModels::WithDAORegistry
|
5
|
+
|
4
6
|
attr_accessor :name
|
5
7
|
|
6
8
|
def initialize(name)
|
7
9
|
@name = name
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
# DEPRECATED
|
13
|
+
def self.from_json(definition, value_class = Aggregation::Value, aggregations_factory: nil)
|
14
|
+
ActiveSupport::Deprecation.new('1.0', 'ArtirixDataModels').warn('`Aggregation.from_json` is deprecated in favour of `AggregationsFactory#aggregation_from_json`')
|
15
|
+
aggregations_factory ||= DAORegistry.get(:aggregations_factory)
|
16
|
+
aggregations_factory.aggregation_from_json(definition, value_class: value_class, aggregation_class: self)
|
12
17
|
end
|
13
18
|
|
14
19
|
def pretty_name
|
@@ -2,6 +2,8 @@ module ArtirixDataModels
|
|
2
2
|
class AggregationsFactory
|
3
3
|
DEFAULT_COLLECTION_CLASS_NAME = ''.freeze
|
4
4
|
|
5
|
+
include ArtirixDataModels::WithDAORegistry
|
6
|
+
|
5
7
|
# AGGREGATION CLASS BUILDING
|
6
8
|
|
7
9
|
def self.sorted_aggregation_class_based_on_index_on(index_array)
|
@@ -32,7 +34,12 @@ module ArtirixDataModels
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def default_loader
|
35
|
-
|
37
|
+
aggregations_factory = self
|
38
|
+
proc { |definition|
|
39
|
+
aggregations_factory.aggregation_from_json definition,
|
40
|
+
value_class: Aggregation::Value,
|
41
|
+
aggregation_class: Aggregation
|
42
|
+
}
|
36
43
|
end
|
37
44
|
|
38
45
|
def get_loader(aggregation_name, collection_class)
|
@@ -4,48 +4,76 @@ module ArtirixDataModels
|
|
4
4
|
|
5
5
|
DELEGATED_METHODS = [
|
6
6
|
:partial_mode_fields,
|
7
|
+
|
7
8
|
:model_name,
|
8
9
|
:model_class,
|
10
|
+
|
9
11
|
:paths_factory,
|
10
12
|
:fake_mode_factory,
|
13
|
+
|
11
14
|
:gateway,
|
15
|
+
|
12
16
|
:force_fake_enabled,
|
13
17
|
:force_fake_disabled,
|
14
18
|
:remove_force_fake,
|
15
19
|
:fake?,
|
16
20
|
:forced_fake_enabled?,
|
17
21
|
:forced_fake_disabled?,
|
22
|
+
|
18
23
|
:empty_collection,
|
19
24
|
:empty_collection_for,
|
25
|
+
|
20
26
|
:perform_get,
|
21
27
|
:perform_post,
|
22
28
|
:perform_put,
|
23
29
|
:perform_delete,
|
30
|
+
|
31
|
+
:dao_registry,
|
32
|
+
:dao_registry=,
|
33
|
+
:set_dao_registry,
|
34
|
+
:dao_registry_loader,
|
35
|
+
:dao_registry_loader=,
|
36
|
+
:set_dao_registry_loader,
|
37
|
+
:set_default_dao_registry_loader,
|
38
|
+
:set_default_dao_registry,
|
24
39
|
]
|
25
40
|
|
26
41
|
included do
|
27
42
|
include ArtirixDataModels::DAOConcerns::WithResponseAdaptors
|
43
|
+
include ArtirixDataModels::WithDAORegistry
|
28
44
|
|
29
45
|
attr_reader :basic_model_dao
|
30
46
|
delegate *DELEGATED_METHODS, to: :basic_model_dao
|
31
47
|
end
|
32
48
|
|
33
49
|
|
34
|
-
def initialize(
|
35
|
-
|
36
|
-
|
37
|
-
|
50
|
+
def initialize(dao_registry: nil,
|
51
|
+
dao_registry_loader: nil,
|
52
|
+
gateway: nil,
|
53
|
+
gateway_factory: nil,
|
54
|
+
ignore_default_gateway: false,
|
55
|
+
model_name: nil,
|
56
|
+
model_class: nil,
|
57
|
+
paths_factory: nil,
|
58
|
+
fake_mode_factory: nil)
|
38
59
|
|
39
60
|
model_name ||= default_model_name
|
40
61
|
model_class ||= default_model_class
|
41
62
|
paths_factory ||= default_path_factory
|
42
63
|
fake_mode_factory ||= default_fake_mode_factory
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
64
|
+
|
65
|
+
# temporary dao registry to load basic_class only
|
66
|
+
dr = ArtirixDataModels::WithDAORegistry.loader_or_registry_or_default(dao_registry_loader: dao_registry_loader, dao_registry: dao_registry)
|
67
|
+
@basic_model_dao = dr.get(:basic_class).new model_name: model_name,
|
68
|
+
model_class: model_class,
|
69
|
+
fake_mode_factory: fake_mode_factory,
|
70
|
+
paths_factory: paths_factory,
|
71
|
+
gateway: gateway,
|
72
|
+
gateway_factory: gateway_factory,
|
73
|
+
dao_registry: dao_registry,
|
74
|
+
dao_registry_loader: dao_registry_loader,
|
75
|
+
ignore_default_gateway: ignore_default_gateway
|
76
|
+
|
49
77
|
end
|
50
78
|
|
51
79
|
def default_model_name
|
@@ -88,24 +116,63 @@ module ArtirixDataModels
|
|
88
116
|
end
|
89
117
|
|
90
118
|
def get_full(model_pk, model_to_reload: nil, cache_adaptor: nil, **extra_options)
|
119
|
+
# we do not check in the registry, since it could be a reload
|
91
120
|
model_to_reload ||= new_model_with_pk(model_pk)
|
92
121
|
cache_adaptor ||= cache_model_adaptor_for_get_full(model_pk, model_to_reload: model_to_reload, **extra_options)
|
93
|
-
|
122
|
+
|
123
|
+
model = basic_model_dao.get_full(model_pk, model_to_reload: model_to_reload, cache_adaptor: cache_adaptor, **extra_options)
|
124
|
+
|
125
|
+
complete_model model
|
94
126
|
end
|
95
127
|
|
96
128
|
def get(model_pk, cache_adaptor: nil, **extra_options)
|
129
|
+
model = dao_registry.get_model model_name, model_pk
|
130
|
+
return model if model.present?
|
131
|
+
|
97
132
|
cache_adaptor ||= cache_model_adaptor_for_get(model_pk, **extra_options)
|
98
|
-
|
133
|
+
|
134
|
+
model = basic_model_dao.get(model_pk, cache_adaptor: cache_adaptor, **extra_options)
|
135
|
+
|
136
|
+
complete_model model
|
99
137
|
end
|
100
138
|
|
101
139
|
def find(model_pk, cache_adaptor: nil, **extra_options)
|
140
|
+
model = dao_registry.get_model model_name, model_pk
|
141
|
+
return model if model.present?
|
142
|
+
|
102
143
|
cache_adaptor ||= cache_model_adaptor_for_find(model_pk, **extra_options)
|
103
|
-
|
144
|
+
|
145
|
+
model = basic_model_dao.find(model_pk, cache_adaptor: cache_adaptor, **extra_options)
|
146
|
+
|
147
|
+
complete_model model
|
104
148
|
end
|
105
149
|
|
106
150
|
def get_some(model_pks, cache_adaptor: nil, **extra_options)
|
107
|
-
|
108
|
-
|
151
|
+
registered = Array(model_pks).map do |model_pk|
|
152
|
+
[
|
153
|
+
model_pk,
|
154
|
+
dao_registry.get_model(model_name, model_pk)
|
155
|
+
]
|
156
|
+
end.to_h
|
157
|
+
|
158
|
+
return registered.values if registered.values.all?(&:present?)
|
159
|
+
|
160
|
+
# load only the missing
|
161
|
+
missing_pks = registered.select { |_k, v| v.blank? }.keys
|
162
|
+
|
163
|
+
cache_adaptor ||= cache_model_adaptor_for_get_some(missing_pks, **extra_options)
|
164
|
+
|
165
|
+
models = basic_model_dao.get_some(missing_pks, cache_adaptor: cache_adaptor, **extra_options)
|
166
|
+
|
167
|
+
Array(models).each do |model|
|
168
|
+
complete_model model
|
169
|
+
end
|
170
|
+
|
171
|
+
list = registered.values.compact.concat(models)
|
172
|
+
|
173
|
+
# reorder with the same order of the model_pks
|
174
|
+
# (if for any reason it does not have a primary key or if it is not in the list, then use -1 so they are at the start)
|
175
|
+
list.sort_by { |m| pk = m.try :primary_key; model_pks.index(pk) || -1 }
|
109
176
|
end
|
110
177
|
|
111
178
|
private
|
@@ -134,6 +201,15 @@ module ArtirixDataModels
|
|
134
201
|
ArtirixDataModels::CachedActionAdaptor::GetSome.new(dao_name: model_name, model_pks: model_pks, **extra_options)
|
135
202
|
end
|
136
203
|
|
204
|
+
def complete_model(model)
|
205
|
+
if model
|
206
|
+
dao_registry.register_model model
|
207
|
+
model.try :set_dao_registry_loader, dao_registry_loader
|
208
|
+
end
|
209
|
+
|
210
|
+
model
|
211
|
+
end
|
212
|
+
|
137
213
|
module FakeModes
|
138
214
|
module Factory
|
139
215
|
|
@@ -145,15 +221,15 @@ module ArtirixDataModels
|
|
145
221
|
raise NotImplementedError
|
146
222
|
end
|
147
223
|
|
148
|
-
def get(
|
224
|
+
def get(_model_pk)
|
149
225
|
raise NotImplementedError
|
150
226
|
end
|
151
227
|
|
152
|
-
def get_full(
|
228
|
+
def get_full(_model_pk, given_model_to_reload = nil)
|
153
229
|
raise NotImplementedError
|
154
230
|
end
|
155
231
|
|
156
|
-
def get_some(
|
232
|
+
def get_some(_model_pks)
|
157
233
|
raise NotImplementedError
|
158
234
|
end
|
159
235
|
|
@@ -25,7 +25,7 @@ module ArtirixDataModels
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def response_adaptor_for_collection(from, size, collection_element_model_class = model_class)
|
28
|
-
model_adaptor_factory.collection collection_element_model_class, from, size
|
28
|
+
model_adaptor_factory.collection collection_element_model_class, from, size, dao_registry_loader
|
29
29
|
end
|
30
30
|
|
31
31
|
def response_adaptor_for_block(&block)
|
@@ -14,17 +14,18 @@ class ArtirixDataModels::DAORegistry
|
|
14
14
|
|
15
15
|
# singleton instance
|
16
16
|
def initialize
|
17
|
-
@_repository
|
18
|
-
@
|
17
|
+
@_repository = {}
|
18
|
+
@_persistent_loaders = {}
|
19
|
+
@_transient_loaders = {}
|
19
20
|
|
20
21
|
setup_config
|
21
22
|
end
|
22
23
|
|
23
24
|
def setup_config
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
set_persistent_loader(:aggregations_factory) { ArtirixDataModels::AggregationsFactory.new }
|
26
|
+
set_persistent_loader(:basic_class) { ArtirixDataModels::BasicModelDAO }
|
27
|
+
set_persistent_loader(:gateway) { ArtirixDataModels::DataGateway.new }
|
28
|
+
set_persistent_loader(:model_fields) { ArtirixDataModels::ModelFieldsDAO.new gateway: get(:gateway) }
|
28
29
|
end
|
29
30
|
|
30
31
|
def aggregations_factory
|
@@ -45,36 +46,95 @@ class ArtirixDataModels::DAORegistry
|
|
45
46
|
|
46
47
|
def exist?(key)
|
47
48
|
key = key.to_sym
|
48
|
-
@_repository.key?(key) || @
|
49
|
+
@_repository.key?(key) || @_persistent_loaders.key?(key) || @_transient_loaders.key?(key)
|
49
50
|
end
|
50
51
|
|
51
|
-
def get(key)
|
52
|
-
@_repository[key.to_sym] || call_loader(key)
|
52
|
+
def get(key, override_dao_registry: nil)
|
53
|
+
x = @_repository[key.to_sym] || call_loader(key)
|
54
|
+
if x.present? && override_dao_registry.present? && x.respond_to?(:set_dao_registry)
|
55
|
+
x.set_dao_registry override_dao_registry
|
56
|
+
end
|
57
|
+
|
58
|
+
x
|
53
59
|
end
|
54
60
|
|
55
|
-
def
|
56
|
-
key
|
57
|
-
|
61
|
+
def set_transient_loader(key, loader = nil, &block)
|
62
|
+
key = key.to_sym
|
63
|
+
|
64
|
+
if block
|
65
|
+
@_transient_loaders[key] = block
|
66
|
+
elsif loader.respond_to? :call
|
67
|
+
@_transient_loaders[key] = loader
|
68
|
+
else
|
69
|
+
raise ArgumentError, "no block and no loader given for key #{key}"
|
70
|
+
end
|
58
71
|
end
|
59
72
|
|
60
|
-
def
|
73
|
+
def set_persistent_loader(key, loader = nil, &block)
|
61
74
|
key = key.to_sym
|
62
75
|
|
63
76
|
if block
|
64
|
-
@
|
77
|
+
@_persistent_loaders[key] = block
|
65
78
|
elsif loader.respond_to? :call
|
66
|
-
@
|
79
|
+
@_persistent_loaders[key] = loader
|
67
80
|
else
|
68
81
|
raise ArgumentError, "no block and no loader given for key #{key}"
|
69
82
|
end
|
70
83
|
end
|
71
84
|
|
85
|
+
alias_method :set_loader, :set_persistent_loader
|
86
|
+
|
87
|
+
################
|
88
|
+
# IDENTITY MAP #
|
89
|
+
################
|
90
|
+
|
91
|
+
def with_identity_map
|
92
|
+
IdentityMap.new dao_registry: self
|
93
|
+
end
|
94
|
+
|
95
|
+
# IDENTITY MAP compatible
|
96
|
+
def register_model(_model)
|
97
|
+
# DO NOTHING
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def unload_model(_model)
|
102
|
+
# DO NOTHING
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_model(_model_dao_name, _primary_key)
|
107
|
+
# DO NOTHING
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def call_loader(key)
|
113
|
+
key = key.to_sym
|
114
|
+
if @_persistent_loaders[key]
|
115
|
+
@_repository[key] = @_persistent_loaders[key].call
|
116
|
+
elsif @_transient_loaders[key]
|
117
|
+
@_transient_loaders[key].call
|
118
|
+
else
|
119
|
+
raise LoaderNotFound, "no loader or transient found for #{key}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
72
124
|
# static methods
|
73
125
|
|
74
126
|
def self.set_loader(key, loader = nil, &block)
|
75
127
|
instance.set_loader key, loader, &block
|
76
128
|
end
|
77
129
|
|
130
|
+
def self.set_persistent_loader(key, loader = nil, &block)
|
131
|
+
instance.set_persistent_loader key, loader, &block
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.set_transient_loader(key, loader = nil, &block)
|
135
|
+
instance.set_transient_loader key, loader, &block
|
136
|
+
end
|
137
|
+
|
78
138
|
def self.get(key)
|
79
139
|
instance.get key
|
80
140
|
end
|
@@ -83,6 +143,10 @@ class ArtirixDataModels::DAORegistry
|
|
83
143
|
instance.exist? key
|
84
144
|
end
|
85
145
|
|
146
|
+
def self.with_identity_map
|
147
|
+
instance.with_identity_map
|
148
|
+
end
|
149
|
+
|
86
150
|
def self.method_missing(method, *args, &block)
|
87
151
|
if exist?(method)
|
88
152
|
get(method)
|
@@ -95,4 +159,100 @@ class ArtirixDataModels::DAORegistry
|
|
95
159
|
exist?(method) || super
|
96
160
|
end
|
97
161
|
|
162
|
+
class LoaderNotFound < StandardError
|
163
|
+
end
|
164
|
+
|
165
|
+
class IdentityMap
|
166
|
+
include ArtirixDataModels::WithDAORegistry
|
167
|
+
|
168
|
+
def initialize(dao_registry_loader: nil, dao_registry: nil)
|
169
|
+
set_dao_registry_and_loader dao_registry_loader, dao_registry
|
170
|
+
@identity_map = {}
|
171
|
+
end
|
172
|
+
|
173
|
+
##############################
|
174
|
+
# DELEGATING TO DAO REGISTRY #
|
175
|
+
##############################
|
176
|
+
|
177
|
+
delegate :exist?, :aggregations_factory, to: :dao_registry
|
178
|
+
|
179
|
+
def respond_to_missing?(method_name, include_private = false)
|
180
|
+
dao_registry.respond_to? method_name, include_private
|
181
|
+
end
|
182
|
+
|
183
|
+
def method_missing(method_name, *arguments, &block)
|
184
|
+
dao_registry.send method_name, *arguments, &block
|
185
|
+
end
|
186
|
+
|
187
|
+
def get(key, override_dao_registry: nil)
|
188
|
+
override_dao_registry ||= self
|
189
|
+
dao_registry.get key, override_dao_registry: override_dao_registry
|
190
|
+
end
|
191
|
+
|
192
|
+
###########################
|
193
|
+
# IDENTITY MAP FOR MODELS #
|
194
|
+
###########################
|
195
|
+
|
196
|
+
def register_model(model)
|
197
|
+
model_dao_name, primary_key = keys_from_model(model, action: :register)
|
198
|
+
return self unless model_dao_name.present? && primary_key.present?
|
199
|
+
|
200
|
+
log "register model #{model_dao_name}:#{primary_key}"
|
201
|
+
|
202
|
+
@identity_map[model_dao_name] ||= {}
|
203
|
+
@identity_map[model_dao_name][primary_key] = model
|
204
|
+
|
205
|
+
self
|
206
|
+
end
|
207
|
+
|
208
|
+
def unload_model(model)
|
209
|
+
model_dao_name, primary_key = keys_from_model(model, action: :unload)
|
210
|
+
return self unless model_dao_name.present? && primary_key.present?
|
211
|
+
|
212
|
+
log "unload model #{model_dao_name}:#{primary_key}"
|
213
|
+
|
214
|
+
@identity_map[model_dao_name] ||= {}
|
215
|
+
@identity_map[model_dao_name].delete primary_key
|
216
|
+
|
217
|
+
self
|
218
|
+
end
|
219
|
+
|
220
|
+
def get_model(model_dao_name, primary_key)
|
221
|
+
model_dao_name = model_dao_name.to_s
|
222
|
+
primary_key = primary_key.to_s
|
223
|
+
return nil unless model_dao_name.present? && primary_key.present?
|
224
|
+
|
225
|
+
@identity_map[model_dao_name] ||= {}
|
226
|
+
val = @identity_map[model_dao_name][primary_key]
|
227
|
+
|
228
|
+
if val.nil?
|
229
|
+
log "get model #{model_dao_name}:#{primary_key} NOT PRESENT"
|
230
|
+
else
|
231
|
+
log "get model #{model_dao_name}:#{primary_key} PRESENT!!!!!"
|
232
|
+
end
|
233
|
+
|
234
|
+
val
|
235
|
+
end
|
236
|
+
|
237
|
+
private
|
238
|
+
def log(msg)
|
239
|
+
ArtirixDataModels.logger.debug "DAO-REGISTRY-IDENTITY-MAP #{object_id} => #{msg}"
|
240
|
+
end
|
241
|
+
|
242
|
+
def keys_from_model(model, action: :use)
|
243
|
+
model_dao_name = model.try :model_dao_name
|
244
|
+
primary_key = model.try :primary_key
|
245
|
+
|
246
|
+
if model_dao_name.blank?
|
247
|
+
ArtirixDataModels.logger.error("model does not have a `model_dao_name` #{model}: we cannot #{action} it")
|
248
|
+
end
|
249
|
+
|
250
|
+
if primary_key.blank?
|
251
|
+
ArtirixDataModels.logger.error("model does not have a `primary_key` #{model}: we cannot #{action} it")
|
252
|
+
end
|
253
|
+
|
254
|
+
[model_dao_name.to_s, primary_key.to_s]
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
98
258
|
end
|
@@ -1,15 +1,38 @@
|
|
1
1
|
class ArtirixDataModels::BasicModelDAO
|
2
2
|
include ArtirixDataModels::DAOConcerns::WithResponseAdaptors
|
3
|
+
include ArtirixDataModels::WithDAORegistry
|
3
4
|
|
4
|
-
attr_reader :model_name, :model_class, :paths_factory, :fake_mode_factory, :gateway_factory
|
5
|
+
attr_reader :model_name, :model_class, :paths_factory, :fake_mode_factory, :gateway_factory
|
5
6
|
|
6
|
-
def initialize(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
def initialize(dao_registry: nil,
|
8
|
+
dao_registry_loader: nil,
|
9
|
+
model_name:,
|
10
|
+
model_class:,
|
11
|
+
paths_factory:,
|
12
|
+
gateway:,
|
13
|
+
fake_mode_factory:,
|
14
|
+
gateway_factory:,
|
15
|
+
ignore_default_gateway: false)
|
16
|
+
|
17
|
+
set_dao_registry_and_loader dao_registry_loader, dao_registry
|
18
|
+
|
19
|
+
@model_name = model_name
|
20
|
+
@model_class = model_class
|
21
|
+
@paths_factory = paths_factory
|
22
|
+
@loaded_gateway = gateway
|
23
|
+
@gateway_factory = gateway_factory
|
24
|
+
@fake_mode_factory = fake_mode_factory
|
25
|
+
@ignore_default_gateway = ignore_default_gateway
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_gateway_available?
|
29
|
+
!@ignore_default_gateway
|
30
|
+
end
|
31
|
+
|
32
|
+
def loaded_gateway
|
33
|
+
@loaded_gateway ||= if gateway_factory.blank? && default_gateway_available?
|
34
|
+
dao_registry.get(:gateway)
|
35
|
+
end
|
13
36
|
end
|
14
37
|
|
15
38
|
###########
|
@@ -62,7 +85,7 @@ class ArtirixDataModels::BasicModelDAO
|
|
62
85
|
if fake?
|
63
86
|
fake_mode_factory.partial_mode_fields
|
64
87
|
else
|
65
|
-
|
88
|
+
dao_registry.get(:model_fields).partial_mode_fields_for model_name
|
66
89
|
end
|
67
90
|
end
|
68
91
|
|
@@ -7,10 +7,15 @@
|
|
7
7
|
class ArtirixDataModels::ModelFieldsDAO
|
8
8
|
PARTIAL_FIELDS = {}
|
9
9
|
|
10
|
-
|
10
|
+
include ArtirixDataModels::WithDAORegistry
|
11
11
|
|
12
|
-
def initialize(gateway: nil)
|
13
|
-
|
12
|
+
def initialize(dao_registry: nil, dao_registry_loader: nil, gateway: nil)
|
13
|
+
set_dao_registry_and_loader dao_registry_loader, dao_registry
|
14
|
+
@gateway = gateway
|
15
|
+
end
|
16
|
+
|
17
|
+
def gateway
|
18
|
+
@gateway ||= dao_registry.gateway
|
14
19
|
end
|
15
20
|
|
16
21
|
def partial_mode_fields_for(model_name)
|
@@ -3,9 +3,9 @@ require 'oj'
|
|
3
3
|
module ArtirixDataModels
|
4
4
|
class EsCollection
|
5
5
|
|
6
|
-
DEFAULT_SIZE
|
6
|
+
DEFAULT_SIZE = 10
|
7
7
|
CACHE_KEY_SECTION_SEPARATOR = '/'.freeze
|
8
|
-
CACHE_KEY_RESULT_SEPARATOR
|
8
|
+
CACHE_KEY_RESULT_SEPARATOR = '\\'.freeze
|
9
9
|
|
10
10
|
def self.work_with_kaminari
|
11
11
|
require 'kaminari'
|
@@ -66,16 +66,26 @@ module ArtirixDataModels
|
|
66
66
|
end
|
67
67
|
|
68
68
|
include Enumerable
|
69
|
+
include ArtirixDataModels::WithDAORegistry
|
69
70
|
|
70
71
|
attr_reader :klass_or_factory, :response, :from, :size
|
71
72
|
|
72
|
-
# @param klass_or_factory
|
73
|
-
# @param response
|
74
|
-
# @param from
|
75
|
-
# @param size
|
73
|
+
# @param klass_or_factory [A Model Class|Callable] The model class or the Factory (callable object) to build the model
|
74
|
+
# @param response [Hash] The full response returned from the DataLayer
|
75
|
+
# @param from [Int] requested offset (0 by default)
|
76
|
+
# @param size [Int] requested amount of hits (10 by default)
|
76
77
|
# @param aggregations_factory [Int] requested amount of hits (10 by default)
|
77
78
|
#
|
78
|
-
def initialize(klass_or_factory,
|
79
|
+
def initialize(klass_or_factory,
|
80
|
+
response:,
|
81
|
+
from: 0,
|
82
|
+
size: DEFAULT_SIZE,
|
83
|
+
dao_registry: nil,
|
84
|
+
dao_registry_loader: nil,
|
85
|
+
aggregations_factory: nil)
|
86
|
+
|
87
|
+
set_dao_registry_and_loader dao_registry_loader, dao_registry
|
88
|
+
|
79
89
|
@klass_or_factory = klass_or_factory
|
80
90
|
@response = response
|
81
91
|
@from = from
|
@@ -84,7 +94,7 @@ module ArtirixDataModels
|
|
84
94
|
end
|
85
95
|
|
86
96
|
def aggregations_factory
|
87
|
-
@aggregations_factory ||
|
97
|
+
@aggregations_factory || dao_registry.get(:aggregations_factory)
|
88
98
|
end
|
89
99
|
|
90
100
|
# The number of total hits for a query
|
@@ -170,13 +180,23 @@ module ArtirixDataModels
|
|
170
180
|
def deserialize_document(document)
|
171
181
|
info = info_from_document(document)
|
172
182
|
|
173
|
-
if model_factory
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
183
|
+
model = if model_factory
|
184
|
+
model_factory.call info
|
185
|
+
elsif model_class
|
186
|
+
model_class.new info
|
187
|
+
else
|
188
|
+
raise 'no model class, nor model factory'
|
189
|
+
end
|
190
|
+
complete_model model
|
191
|
+
end
|
192
|
+
|
193
|
+
def complete_model(model)
|
194
|
+
if model
|
195
|
+
dao_registry.register_model model
|
196
|
+
model.try :set_dao_registry_loader, dao_registry_loader
|
179
197
|
end
|
198
|
+
|
199
|
+
model
|
180
200
|
end
|
181
201
|
|
182
202
|
def model_factory
|
@@ -52,9 +52,15 @@ module ArtirixDataModels::GatewayResponseAdaptors
|
|
52
52
|
new ->(data_list) { Array(data_list).map { |data_hash| model_class.new data_hash } }
|
53
53
|
end
|
54
54
|
|
55
|
-
def self.collection(object_class_or_factory, from = 0, size = nil)
|
55
|
+
def self.collection(object_class_or_factory, from = 0, size = nil, dao_registry_loader = nil)
|
56
56
|
size ||= ArtirixDataModels.configuration.try(:search_page_size).try(:default) || 10
|
57
|
-
new ->(data_collection) {
|
57
|
+
new ->(data_collection) {
|
58
|
+
ArtirixDataModels::EsCollection.new object_class_or_factory,
|
59
|
+
response: data_collection,
|
60
|
+
from: from,
|
61
|
+
size: size,
|
62
|
+
dao_registry_loader: dao_registry_loader
|
63
|
+
}
|
58
64
|
end
|
59
65
|
|
60
66
|
def self.with_block(&block)
|
@@ -324,6 +324,15 @@ module ArtirixDataModels
|
|
324
324
|
module WithDAO
|
325
325
|
extend ActiveSupport::Concern
|
326
326
|
|
327
|
+
included do
|
328
|
+
include ArtirixDataModels::WithDAORegistry
|
329
|
+
end
|
330
|
+
|
331
|
+
def initialize(dao_registry: nil, dao_registry_loader: nil, **properties)
|
332
|
+
set_dao_registry_and_loader dao_registry_loader, dao_registry
|
333
|
+
_set_properties properties
|
334
|
+
end
|
335
|
+
|
327
336
|
def model_dao_name
|
328
337
|
dao.model_name
|
329
338
|
end
|
@@ -339,8 +348,8 @@ module ArtirixDataModels
|
|
339
348
|
|
340
349
|
def load_dao
|
341
350
|
key = self.class.dao_name
|
342
|
-
raise UndefinedDAOError unless key.present?
|
343
|
-
|
351
|
+
raise UndefinedDAOError, "`dao_name` not defined for #{self.class}" unless key.present?
|
352
|
+
dao_registry.get(key)
|
344
353
|
end
|
345
354
|
|
346
355
|
module ClassMethods
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ArtirixDataModels::WithDAORegistry
|
2
|
+
DEFAULT_DAO_REGISTRY_LOADER = ->() { ArtirixDataModels::DAORegistry.instance }
|
3
|
+
|
4
|
+
def self.loader_or_registry_or_default(dao_registry: nil, dao_registry_loader: nil)
|
5
|
+
raise ArgumentError, 'loader has to respond to :call' if dao_registry_loader.present? && !dao_registry_loader.respond_to?(:call)
|
6
|
+
|
7
|
+
if dao_registry_loader.respond_to? :call
|
8
|
+
dao_registry_loader.call
|
9
|
+
elsif dao_registry
|
10
|
+
dao_registry
|
11
|
+
else
|
12
|
+
DEFAULT_DAO_REGISTRY_LOADER.call
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# set_xxx* methods can be chained (return self)
|
17
|
+
# xxx= methods return the value set
|
18
|
+
|
19
|
+
def dao_registry
|
20
|
+
dao_registry_loader.call
|
21
|
+
end
|
22
|
+
|
23
|
+
def dao_registry_loader
|
24
|
+
@dao_registry_loader || DEFAULT_DAO_REGISTRY_LOADER
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_writer :dao_registry_loader
|
28
|
+
|
29
|
+
def set_dao_registry_loader(dao_registry_loader)
|
30
|
+
self.dao_registry_loader = dao_registry_loader
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def dao_registry=(dao_registry)
|
35
|
+
if dao_registry
|
36
|
+
set_dao_registry_loader ->() { dao_registry }
|
37
|
+
else
|
38
|
+
set_default_dao_registry_loader
|
39
|
+
end
|
40
|
+
|
41
|
+
dao_registry
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_dao_registry(dao_registry)
|
45
|
+
self.dao_registry = dao_registry
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_dao_registry
|
50
|
+
DEFAULT_DAO_REGISTRY_LOADER.call
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_default_dao_registry_loader
|
54
|
+
@dao_registry_loader = nil
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
alias_method :set_default_dao_registry, :set_default_dao_registry_loader
|
59
|
+
|
60
|
+
# will use the loader if present, if not it will use the registry, if not present it will do nothing.
|
61
|
+
def set_dao_registry_and_loader(dao_registry_loader, dao_registry)
|
62
|
+
raise ArgumentError, 'loader has to respond to :call' if dao_registry_loader.present? && !dao_registry_loader.respond_to?(:call)
|
63
|
+
|
64
|
+
if dao_registry_loader.respond_to? :call
|
65
|
+
set_dao_registry_loader dao_registry_loader
|
66
|
+
elsif dao_registry
|
67
|
+
set_dao_registry dao_registry
|
68
|
+
end
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: artirix_data_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Turiño
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -239,6 +239,7 @@ email:
|
|
239
239
|
- eturino@artirix.com
|
240
240
|
executables:
|
241
241
|
- console
|
242
|
+
- rake
|
242
243
|
- setup
|
243
244
|
extensions: []
|
244
245
|
extra_rdoc_files: []
|
@@ -252,6 +253,7 @@ files:
|
|
252
253
|
- Rakefile
|
253
254
|
- artirix_data_models.gemspec
|
254
255
|
- bin/console
|
256
|
+
- bin/rake
|
255
257
|
- bin/setup
|
256
258
|
- lib/artirix_data_models.rb
|
257
259
|
- lib/artirix_data_models/active_null.rb
|
@@ -284,6 +286,7 @@ files:
|
|
284
286
|
- lib/artirix_data_models/spec_support/shared_examples/an_artirix_data_model_model.rb
|
285
287
|
- lib/artirix_data_models/spec_support/shared_examples/has_attributes.rb
|
286
288
|
- lib/artirix_data_models/version.rb
|
289
|
+
- lib/artirix_data_models/with_dao_registry.rb
|
287
290
|
- spec/artirix_data_models/dao_registry_spec.rb
|
288
291
|
- spec/artirix_data_models/es_collection_spec.rb
|
289
292
|
- spec/artirix_data_models/gateways/data_gateway_spec.rb
|