ecoportal-api-v2 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -1
- data/README.md +5 -0
- data/lib/ecoportal/api/common/concerns/benchmarkable.rb +160 -0
- data/lib/ecoportal/api/common/concerns.rb +10 -0
- data/lib/ecoportal/api/common/content/array_model.rb +1 -1
- data/lib/ecoportal/api/common/content/collection_model.rb +64 -33
- data/lib/ecoportal/api/common/content/double_model.rb +32 -7
- data/lib/ecoportal/api/common.v2.rb +1 -0
- data/lib/ecoportal/api/v2/registers/page_result/membrane_droplet.rb +15 -0
- data/lib/ecoportal/api/v2/registers/page_result.rb +6 -2
- data/lib/ecoportal/api/v2_version.rb +1 -1
- metadata +5 -3
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 65194be30f026aa431874543d6905b5704ea081c6a3c9ef0bf9741142c4c4253
|
|
4
|
+
data.tar.gz: 398eaeb83ea38386670715c0fa83144004abdbd8c7edfd8581ecb7b157c8d205
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0761f2079d2493f6fef928f846daf4b6b0413838c4f1252c8cf31742284fc5bcfc0e8d6dbd635f2659b37a34a6b90c09ed42f7db781c868a635188354dbe4bbd
|
|
7
|
+
data.tar.gz: c979ae5a583898d47c1b8501d19ea651f31013a78461008c4ed6eff69c6b1a271c2c812dbbc2a52bc82d90b7caf67e9a286e8d488639eb8bd5a8fd6678c91659
|
data/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
-
## [1.1.
|
|
4
|
+
## [1.1.8] - 2024-03-xx
|
|
5
5
|
|
|
6
6
|
### Added
|
|
7
7
|
### Changed
|
|
8
8
|
### Fixed
|
|
9
9
|
|
|
10
|
+
## [1.1.7] - 2024-03-xx
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Ecoportal::API::Common::Concerns::Benchmarkable`
|
|
14
|
+
- `Ecoportal::API::Common::Conent::CollectionModel`
|
|
15
|
+
- added ability to define **default** value for `read_only`
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- `Ecoportal::API::Common::Content::CollectionModel` tidied up item `klass` scoping
|
|
19
|
+
- **added** some benchmarking too
|
|
20
|
+
- memoize `@_items`
|
|
21
|
+
|
|
22
|
+
## [1.1.6] - 2024-02-29
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- A bit of **specs** on object retrieval for `Ecoportal::API::Common::Conent::CollectionModel`
|
|
26
|
+
- `Ecoportal::API::Registers::PageResult` exposed `membranes`
|
|
27
|
+
- with new object `Ecoportal::API::Registers::PageResult::MembraneDroplet`
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- `Ecoportal::API::Common::Conent::CollectionModel`
|
|
31
|
+
|
|
10
32
|
## [1.1.5] - 2024-02-03
|
|
11
33
|
|
|
12
34
|
### Changed
|
data/README.md
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
module Common
|
|
4
|
+
module Concerns
|
|
5
|
+
# @note While benchmarking with multi-thread gives correct results
|
|
6
|
+
# for top unique block, will calculate the real time of each individual
|
|
7
|
+
# thread, which is way higher than a single thread. However, as they
|
|
8
|
+
# run in parallel, the total time would be the valid reference.
|
|
9
|
+
module Benchmarkable
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def benchmark_enabled?
|
|
13
|
+
@benchmark_enabled = true if @benchmark_enabled.nil?
|
|
14
|
+
@benchmark_enabled
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def benchmarking(ref = nil, print: false)
|
|
18
|
+
return yield unless benchmark_enabled?
|
|
19
|
+
benchmark_mem(ref, print: false) do
|
|
20
|
+
benchmark_time(ref, print: false) do
|
|
21
|
+
yield
|
|
22
|
+
end
|
|
23
|
+
end.tap do
|
|
24
|
+
puts "\n#{bench_summary_ref(ref)}" if print
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def benchmark_mem(ref = nil, print: false)
|
|
29
|
+
return yield unless benchmark_enabled?
|
|
30
|
+
memory_before = memory_usage
|
|
31
|
+
yield.tap do
|
|
32
|
+
memory_after = memory_usage
|
|
33
|
+
mb_footprint = ((memory_after - memory_before) / 1024.0).round(2)
|
|
34
|
+
bench_add_mem(ref, mb_footprint)
|
|
35
|
+
puts bench_str_mem(mb, ref: ref, reffix: true) if print
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def benchmark_time(ref = nil, print: false)
|
|
40
|
+
return yield unless benchmark_enabled?
|
|
41
|
+
result = nil
|
|
42
|
+
time = benchmark.realtime do
|
|
43
|
+
result = yield
|
|
44
|
+
end.round(2)
|
|
45
|
+
result.tap do
|
|
46
|
+
bench_add_time(ref, time)
|
|
47
|
+
puts bench_str_time(time, ref: ref, reffix: true) if print
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def benchmark_summary(ref = nil)
|
|
52
|
+
return '' unless benchmark_enabled?
|
|
53
|
+
return bench_summary_ref(ref) unless ref == :all
|
|
54
|
+
|
|
55
|
+
bench.keys.each_with_object([]) do |ref, out|
|
|
56
|
+
out << bench_summary_ref(ref)
|
|
57
|
+
end.join("\n")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def bench_summary_ref(ref = nil)
|
|
61
|
+
ref_lines = bench_summary_ref_lines(ref)
|
|
62
|
+
"- #{ref}\n" + " • " + ref_lines.join("\n • ")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def bench_summary_ref_lines(ref = nil)
|
|
66
|
+
ref_bench = bench_get(ref)
|
|
67
|
+
[
|
|
68
|
+
bench_str_time(*ref_bench[:time].values_at(:avg, :cnt), ref: ref),
|
|
69
|
+
bench_str_mem(*ref_bench[:mem].values_at(:avg, :cnt), ref: ref)
|
|
70
|
+
]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def benchmark
|
|
74
|
+
require 'benchmark'
|
|
75
|
+
Benchmark
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def bench
|
|
79
|
+
@bench ||= {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def bench_add_mem(ref, mem)
|
|
83
|
+
bench_data_push(bench_get(ref)[:mem], mem)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def bench_add_time(ref, time)
|
|
87
|
+
bench_data_push(bench_get(ref)[:time], time)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def bench_get(ref)
|
|
91
|
+
bench[ref] ||= {
|
|
92
|
+
time: bench_data,
|
|
93
|
+
mem: bench_data
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def bench_data
|
|
98
|
+
{
|
|
99
|
+
avg: nil,
|
|
100
|
+
cnt: 0
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def bench_data_push(data, value)
|
|
105
|
+
total = value + ( (data[:avg] || 0) * data[:cnt])
|
|
106
|
+
data[:cnt] += 1
|
|
107
|
+
data[:avg] = (total / data[:cnt]).round(3)
|
|
108
|
+
data
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def bench_str_mem(mem, count = nil, ref: nil, reffix: false)
|
|
112
|
+
ref = reffix ? ref : nil
|
|
113
|
+
msg = [ref, 'Memory'].compact.join(' -- ')
|
|
114
|
+
cnt = count ? " (cnt: #{count})" : ''
|
|
115
|
+
"#{msg}: #{mem} MB#{cnt}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def active_support_duration?
|
|
119
|
+
return false unless Kernel.const_defined?(:ActiveSupport)
|
|
120
|
+
ActiveSupport.const_defined?(:Duration, false)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def bench_str_time(time, count = nil, ref: nil, reffix: false)
|
|
124
|
+
ref = reffix ? ref : nil
|
|
125
|
+
msg = [ref, 'Time'].compact.join(' -- ')
|
|
126
|
+
total = (time * count).round(2)
|
|
127
|
+
str_desc = ''
|
|
128
|
+
if active_support_duration? && total >= 60
|
|
129
|
+
duration = ActiveSupport::Duration.build(total.round)
|
|
130
|
+
str_desc = ": #{duration_to_s(duration)}"
|
|
131
|
+
end
|
|
132
|
+
cnt = count ? " (cnt: #{count}; sum: #{total} s#{str_desc})" : ''
|
|
133
|
+
"#{msg}: #{time} s#{cnt}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def duration_to_s(value)
|
|
137
|
+
return "" unless active_support_duration?
|
|
138
|
+
return "" if value.nil?
|
|
139
|
+
|
|
140
|
+
raise ArgumentError, "Expecint ActiveSupport::Duration. Given: #{value.class}" unless value.is_a?(ActiveSupport::Duration)
|
|
141
|
+
parts = value.parts.map {|pair| pair.reverse.join(" ")}
|
|
142
|
+
return parts.first if parts.length == 1
|
|
143
|
+
[parts[..-2].join(", "), parts.last].join(" and ")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# @return [Integer] total memory used by this process in KB
|
|
147
|
+
def memory_usage
|
|
148
|
+
if Gem.win_platform?
|
|
149
|
+
wmem = `wmic process where processid=#{Process.pid} get WorkingSetSize | findstr "[0-9]"`
|
|
150
|
+
return 0 unless wmem
|
|
151
|
+
wmem.lines.first.chop.strip.to_i / 1024.0
|
|
152
|
+
else
|
|
153
|
+
`ps -o rss= -p #{Process.pid}`.to_i
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -34,7 +34,7 @@ module Ecoportal
|
|
|
34
34
|
|
|
35
35
|
inheritable_class_vars :order_matteres, :uniq
|
|
36
36
|
|
|
37
|
-
def initialize(doc = [], parent: self, key: nil, read_only:
|
|
37
|
+
def initialize(doc = [], parent: self, key: nil, read_only: self.class.read_only?)
|
|
38
38
|
super(doc, parent: parent, key: key, read_only: read_only)
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -6,11 +6,12 @@ module Ecoportal
|
|
|
6
6
|
# @note to be able to refer to the correct element of the Collection,
|
|
7
7
|
# it is required that those elements have a unique `key` that allows to identify them
|
|
8
8
|
class CollectionModel < Content::DoubleModel
|
|
9
|
-
|
|
10
9
|
class << self
|
|
11
10
|
attr_writer :klass
|
|
12
11
|
attr_accessor :order_matters, :order_key
|
|
13
12
|
|
|
13
|
+
# The attr that has been defined as `passkey`
|
|
14
|
+
# in the item class
|
|
14
15
|
def items_key
|
|
15
16
|
@items_key ||= "id"
|
|
16
17
|
end
|
|
@@ -22,26 +23,46 @@ module Ecoportal
|
|
|
22
23
|
# Resolves to the nuclear `Class` of the elements
|
|
23
24
|
# @note
|
|
24
25
|
# - use block to define `klass` callback
|
|
26
|
+
# @note When `klass` is resolved, if the items are of type
|
|
27
|
+
# `DoubleModel`, it sets on the collection class the `items_key`
|
|
28
|
+
# @note when `klass` is directly resolved (not via doc) only once
|
|
29
|
+
# it will set @klass as resolved and will use this class from now on.
|
|
30
|
+
# This is an optimization to cut class lookups
|
|
25
31
|
# @param value [Hash] base `doc` (raw object) to create the object with
|
|
26
32
|
# @yield [doc] identifies the target `class` of the raw object
|
|
27
33
|
# @yieldparam doc [Hash]
|
|
28
34
|
# @yieldreturn [Klass] the target `class`
|
|
29
35
|
# @return [Klass] the target `class`
|
|
30
36
|
def klass(value = NOT_USED, &block)
|
|
31
|
-
if
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
resolve_class(@klass, exception: false)
|
|
39
|
-
end
|
|
37
|
+
@klass = block if block_given?
|
|
38
|
+
|
|
39
|
+
if @klass && !@class.is_a?(Proc)
|
|
40
|
+
@klass = resolve_class(@klass, exception: false) unless @klass.is_a?(Class)
|
|
41
|
+
@klass
|
|
42
|
+
elsif @klass.is_a?(Proc) && used_param?(value)
|
|
43
|
+
@klass.call(value)
|
|
40
44
|
else
|
|
41
|
-
|
|
45
|
+
@klass
|
|
46
|
+
end.tap do |result|
|
|
47
|
+
next unless result.is_a?(Class)
|
|
48
|
+
next unless result < Ecoportal::API::Common::Content::DoubleModel
|
|
49
|
+
self.items_key = result.key
|
|
42
50
|
end
|
|
43
51
|
end
|
|
44
52
|
|
|
53
|
+
# @return [Boolean] are there the factory logics to build item objects defined?
|
|
54
|
+
def klass?
|
|
55
|
+
@klass || @new_item
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Optimization
|
|
59
|
+
def new_item_class_based?
|
|
60
|
+
return false if @new_item.is_a?(Proc)
|
|
61
|
+
return false if @klass.is_a?(Proc)
|
|
62
|
+
return true if klass.is_a?(Class)
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
45
66
|
# Generates a new object of the target class
|
|
46
67
|
# @note
|
|
47
68
|
# - use block to define `new_item` callback, which will prevail over `klass`
|
|
@@ -51,29 +72,24 @@ module Ecoportal
|
|
|
51
72
|
# @yield [doc, parent, key] creates an object instance of the target `klass`
|
|
52
73
|
# @yieldparam doc [Hash]
|
|
53
74
|
# @yieldreturn [Klass] instance object of the target `klass`
|
|
75
|
+
# @parent [CollectionModel] the parent of the new item
|
|
76
|
+
# @key [Symbol, String] the key value to access the item within collection
|
|
77
|
+
# Please observe that items in a CollectionModel are identified via their key attr.
|
|
78
|
+
# Meaning that there is actually no need to define this argument.
|
|
54
79
|
# @return [Klass] instance object of the target `klass`
|
|
55
80
|
def new_item(doc = NOT_USED, parent: nil, key: nil, read_only: false, &block)
|
|
56
|
-
if
|
|
57
|
-
@new_item = block
|
|
58
|
-
elsif used_param?(doc)
|
|
59
|
-
raise "You should define either a 'klass' or a 'new_item' callback first" unless klass?
|
|
60
|
-
if @new_item
|
|
61
|
-
@new_item.call(doc, parent, key)
|
|
62
|
-
else
|
|
63
|
-
if target_class = self.klass(doc)
|
|
64
|
-
doc.is_a?(target_class) ? doc : target_class.new(doc, parent: parent, key: key, read_only: read_only)
|
|
65
|
-
else
|
|
66
|
-
raise "Could not find a class for: #{doc}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
else
|
|
70
|
-
raise "To define the 'new_item' callback (factory), you need to use a block"
|
|
71
|
-
end
|
|
72
|
-
end
|
|
81
|
+
return (@new_item = block; nil) if block_given
|
|
73
82
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
msg = "To define the 'new_item' callback (factory), you need to use a block"
|
|
84
|
+
raise msg unless used_param?(doc)
|
|
85
|
+
msg = "You should define either a 'klass' or a 'new_item' callback first"
|
|
86
|
+
raise msg unless klass?
|
|
87
|
+
return @new_item.call(doc, parent, key) if @new_item.is_a?(Proc)
|
|
88
|
+
|
|
89
|
+
raise "Could not find a class for: #{doc}" unless target_class = klass(doc)
|
|
90
|
+
return doc if doc.is_a?(target_class)
|
|
91
|
+
|
|
92
|
+
target_class.new(doc, parent: parent, key: key, read_only: read_only)
|
|
77
93
|
end
|
|
78
94
|
|
|
79
95
|
def doc_class(name)
|
|
@@ -127,7 +143,17 @@ module Ecoportal
|
|
|
127
143
|
#print "{{#{p}}}"
|
|
128
144
|
end
|
|
129
145
|
else
|
|
130
|
-
|
|
146
|
+
show_str = \
|
|
147
|
+
case value
|
|
148
|
+
when Hash
|
|
149
|
+
value.pretty_inspect
|
|
150
|
+
when Content::DoubleModel
|
|
151
|
+
"#{value} with key: #{value.class.key} (items_key: #{self.class.items_key})"
|
|
152
|
+
else
|
|
153
|
+
value
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
raise UnlinkedModel, "Can't find child: #{show_str}"
|
|
131
157
|
end
|
|
132
158
|
end
|
|
133
159
|
|
|
@@ -147,6 +173,7 @@ module Ecoportal
|
|
|
147
173
|
_doc_items.each do |item_doc|
|
|
148
174
|
elements << new_item(item_doc)
|
|
149
175
|
end
|
|
176
|
+
@_items = elements if read_only?
|
|
150
177
|
end
|
|
151
178
|
end
|
|
152
179
|
|
|
@@ -256,7 +283,11 @@ module Ecoportal
|
|
|
256
283
|
private
|
|
257
284
|
|
|
258
285
|
def new_item(value)
|
|
259
|
-
self.class.
|
|
286
|
+
if self.class.new_item_class_based?
|
|
287
|
+
self.class.klass.new(value, parent: self, read_only: self._read_only)
|
|
288
|
+
else
|
|
289
|
+
self.class.new_item(value, parent: self, read_only: self._read_only)
|
|
290
|
+
end
|
|
260
291
|
end
|
|
261
292
|
|
|
262
293
|
# Helper to remove tracked down instance variables
|
|
@@ -28,6 +28,8 @@ module Ecoportal
|
|
|
28
28
|
!!key
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# key property (and method) of this model
|
|
32
|
+
# @note this is auto-set when `passkey` is used
|
|
31
33
|
def key=(value)
|
|
32
34
|
@key = value.to_s.freeze
|
|
33
35
|
end
|
|
@@ -36,6 +38,16 @@ module Ecoportal
|
|
|
36
38
|
uid(length)
|
|
37
39
|
end
|
|
38
40
|
|
|
41
|
+
def read_only?
|
|
42
|
+
@read_only = false if @read_only.nil?
|
|
43
|
+
@read_only
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Be able to define if a class should be read-only
|
|
47
|
+
def read_only!
|
|
48
|
+
@read_only = true
|
|
49
|
+
end
|
|
50
|
+
|
|
39
51
|
# Same as `attr_reader` but links to a subjacent `Hash` model property
|
|
40
52
|
# @note it does **not** create an _instance variable_
|
|
41
53
|
# @param methods [Array<Symbol>] the method that exposes the value
|
|
@@ -72,7 +84,7 @@ module Ecoportal
|
|
|
72
84
|
# This method is essential to give stability to the model
|
|
73
85
|
# @note `Content::CollectionModel` needs to find elements in the doc `Array`.
|
|
74
86
|
# The only way to do it is via the access key (i.e. `id`). However, there is
|
|
75
|
-
# no chance you can avoid
|
|
87
|
+
# no chance you can avoid infinite loop for `get_key` without setting an
|
|
76
88
|
# instance variable key at the moment of the object creation, when the
|
|
77
89
|
# `doc` is firstly received
|
|
78
90
|
# @param method [Symbol] the method that exposes the value
|
|
@@ -174,7 +186,7 @@ module Ecoportal
|
|
|
174
186
|
|
|
175
187
|
define_method method do
|
|
176
188
|
return instance_variable_get(var) if instance_variable_defined?(var)
|
|
177
|
-
new_obj = dim_class.new(parent: self, key: method, read_only: self.
|
|
189
|
+
new_obj = dim_class.new(parent: self, key: method, read_only: self.read_only?)
|
|
178
190
|
variable_set(var, new_obj)
|
|
179
191
|
end
|
|
180
192
|
end
|
|
@@ -200,7 +212,7 @@ module Ecoportal
|
|
|
200
212
|
# @param read_only [Boolean] whether or not should try to **work around** items `klass` missing a `key`
|
|
201
213
|
# - If set to `true` this is meant only for read purposes (won't be able to successufully insert)
|
|
202
214
|
def embeds_many(method, key: method, klass: nil, enum_class: nil,
|
|
203
|
-
order_matters: false, order_key: nil, read_only:
|
|
215
|
+
order_matters: false, order_key: nil, read_only: self.read_only?)
|
|
204
216
|
if enum_class
|
|
205
217
|
eclass = enum_class
|
|
206
218
|
elsif klass
|
|
@@ -208,6 +220,7 @@ module Ecoportal
|
|
|
208
220
|
dim_class.klass = klass
|
|
209
221
|
dim_class.order_matters = order_matters
|
|
210
222
|
dim_class.order_key = order_key
|
|
223
|
+
dim_class.read_only! if read_only
|
|
211
224
|
end
|
|
212
225
|
else
|
|
213
226
|
raise "You should either specify the 'klass' of the elements or the 'enum_class'"
|
|
@@ -222,7 +235,7 @@ module Ecoportal
|
|
|
222
235
|
|
|
223
236
|
private
|
|
224
237
|
|
|
225
|
-
def embed(method, key: method, nullable: false, multiple: false, klass:, read_only:
|
|
238
|
+
def embed(method, key: method, nullable: false, multiple: false, klass:, read_only: self.read_only?, &block)
|
|
226
239
|
method = method.to_s.freeze
|
|
227
240
|
var = instance_variable_name(method).freeze
|
|
228
241
|
k = key.to_s.freeze
|
|
@@ -249,7 +262,7 @@ module Ecoportal
|
|
|
249
262
|
end
|
|
250
263
|
end
|
|
251
264
|
|
|
252
|
-
embedded_class.new(doc[k], parent: self, key: k, read_only: self.
|
|
265
|
+
embedded_class.new(doc[k], parent: self, key: k, read_only: self.read_only? || read_only).tap do |obj|
|
|
253
266
|
variable_set(var, obj)
|
|
254
267
|
end
|
|
255
268
|
end
|
|
@@ -261,11 +274,12 @@ module Ecoportal
|
|
|
261
274
|
end
|
|
262
275
|
end
|
|
263
276
|
|
|
264
|
-
inheritable_class_vars :forced_model_keys, :key
|
|
277
|
+
inheritable_class_vars :forced_model_keys, :key, :read_only
|
|
265
278
|
|
|
279
|
+
# `_key` refers to the parent's property that links to this model
|
|
266
280
|
attr_reader :_parent, :_key, :_read_only
|
|
267
281
|
|
|
268
|
-
def initialize(doc = {}, parent: self, key: nil, read_only:
|
|
282
|
+
def initialize(doc = {}, parent: self, key: nil, read_only: self.class.read_only?)
|
|
269
283
|
@_dim_vars = []
|
|
270
284
|
@_parent = parent || self
|
|
271
285
|
@_key = key || self
|
|
@@ -284,6 +298,12 @@ module Ecoportal
|
|
|
284
298
|
end
|
|
285
299
|
end
|
|
286
300
|
|
|
301
|
+
# @note `read_only` allows for some optimizations, such as storing values
|
|
302
|
+
# in instance variables, for optimization purposes
|
|
303
|
+
def read_only?
|
|
304
|
+
@_read_only
|
|
305
|
+
end
|
|
306
|
+
|
|
287
307
|
def root
|
|
288
308
|
return self if is_root?
|
|
289
309
|
_parent.root
|
|
@@ -321,6 +341,8 @@ module Ecoportal
|
|
|
321
341
|
if is_root?
|
|
322
342
|
@doc
|
|
323
343
|
else
|
|
344
|
+
# transform parent's `_key` to this object into a
|
|
345
|
+
# path key that can rerieve from the parents's doc
|
|
324
346
|
_parent.doc.dig(*[_doc_key(_key)].flatten)
|
|
325
347
|
end
|
|
326
348
|
end
|
|
@@ -403,6 +425,9 @@ module Ecoportal
|
|
|
403
425
|
!!defined?(@doc)
|
|
404
426
|
end
|
|
405
427
|
|
|
428
|
+
# Both requisites
|
|
429
|
+
# @note that for optimization purposes, `@doc` var may be used when
|
|
430
|
+
# the object is `read_only?`
|
|
406
431
|
def is_root?
|
|
407
432
|
_parent == self && doc_var?
|
|
408
433
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class V2
|
|
4
|
+
class Registers
|
|
5
|
+
class PageResult
|
|
6
|
+
class MembraneDroplet < Common::Content::DoubleModel
|
|
7
|
+
passkey :ref
|
|
8
|
+
passthrough :label, :type, :value
|
|
9
|
+
passthrough :field_configuration_id
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -12,10 +12,14 @@ module Ecoportal
|
|
|
12
12
|
passthrough :mould_counter
|
|
13
13
|
|
|
14
14
|
class_resolver :stages_class, "Ecoportal::API::V2::Registers::StagesResult"
|
|
15
|
-
embeds_many :stages, enum_class: :stages_class
|
|
16
|
-
end
|
|
15
|
+
embeds_many :stages, enum_class: :stages_class, read_only: true
|
|
17
16
|
|
|
17
|
+
class_resolver :mem_droplet, "Ecoportal::API::V2::Registers::PageResult::MembraneDroplet"
|
|
18
|
+
embeds_many :membranes, klass: :mem_droplet, read_only: true
|
|
19
|
+
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
24
|
+
|
|
25
|
+
require_relative 'page_result/membrane_droplet'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ecoportal-api-v2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oscar Segura
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-03-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -156,7 +156,6 @@ files:
|
|
|
156
156
|
- ".gitignore"
|
|
157
157
|
- ".rspec"
|
|
158
158
|
- ".rubocop.yml"
|
|
159
|
-
- ".travis.yml"
|
|
160
159
|
- ".yardopts"
|
|
161
160
|
- CHANGELOG.md
|
|
162
161
|
- Gemfile
|
|
@@ -168,6 +167,8 @@ files:
|
|
|
168
167
|
- ecoportal-api-v2.gemspec
|
|
169
168
|
- lib/ecoportal/api-v2.rb
|
|
170
169
|
- lib/ecoportal/api/common.v2.rb
|
|
170
|
+
- lib/ecoportal/api/common/concerns.rb
|
|
171
|
+
- lib/ecoportal/api/common/concerns/benchmarkable.rb
|
|
171
172
|
- lib/ecoportal/api/common/content.rb
|
|
172
173
|
- lib/ecoportal/api/common/content/array_model.rb
|
|
173
174
|
- lib/ecoportal/api/common/content/class_helpers.rb
|
|
@@ -242,6 +243,7 @@ files:
|
|
|
242
243
|
- lib/ecoportal/api/v2/people.rb
|
|
243
244
|
- lib/ecoportal/api/v2/registers.rb
|
|
244
245
|
- lib/ecoportal/api/v2/registers/page_result.rb
|
|
246
|
+
- lib/ecoportal/api/v2/registers/page_result/membrane_droplet.rb
|
|
245
247
|
- lib/ecoportal/api/v2/registers/register.rb
|
|
246
248
|
- lib/ecoportal/api/v2/registers/search_results.rb
|
|
247
249
|
- lib/ecoportal/api/v2/registers/stage_result.rb
|