lutaml 0.10.2 → 0.10.4
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/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +40 -35
- data/CHANGELOG.md +108 -0
- data/lib/lutaml/cli/uml_commands.rb +2 -2
- data/lib/lutaml/command_line.rb +1 -1
- data/lib/lutaml/converter/xmi_to_uml.rb +12 -3
- data/lib/lutaml/model_transformations/parsers/base_parser.rb +1 -1
- data/lib/lutaml/model_transformations/transformation_engine.rb +1 -1
- data/lib/lutaml/qea/database.rb +157 -4
- data/lib/lutaml/qea/factory/association_transformer.rb +1 -5
- data/lib/lutaml/qea/factory/attribute_transformer.rb +4 -10
- data/lib/lutaml/qea/factory/base_transformer.rb +1 -5
- data/lib/lutaml/qea/factory/class_transformer.rb +26 -62
- data/lib/lutaml/qea/factory/data_type_transformer.rb +7 -21
- data/lib/lutaml/qea/factory/diagram_transformer.rb +6 -20
- data/lib/lutaml/qea/factory/document_builder.rb +1 -1
- data/lib/lutaml/qea/factory/enum_transformer.rb +3 -5
- data/lib/lutaml/qea/factory/generalization_transformer.rb +2 -7
- data/lib/lutaml/qea/factory/instance_transformer.rb +2 -10
- data/lib/lutaml/qea/factory/operation_transformer.rb +2 -8
- data/lib/lutaml/qea/factory/package_transformer.rb +4 -13
- data/lib/lutaml/qea/repositories/base_repository.rb +6 -6
- data/lib/lutaml/qea/validation/base_validator.rb +2 -3
- data/lib/lutaml/qea/validation/validation_message.rb +2 -2
- data/lib/lutaml/qea/validation/validation_result.rb +2 -2
- data/lib/lutaml/sysml.rb +1 -1
- data/lib/lutaml/uml/has_members.rb +1 -1
- data/lib/lutaml/uml/parsers/dsl.rb +1 -1
- data/lib/lutaml/uml.rb +1 -1
- data/lib/lutaml/uml_repository/index_builder.rb +19 -17
- data/lib/lutaml/uml_repository/queries/class_query.rb +44 -10
- data/lib/lutaml/uml_repository/queries/inheritance_query.rb +0 -1
- data/lib/lutaml/uml_repository/repository.rb +14 -10
- data/lib/lutaml/uml_repository/statistics_calculator.rb +28 -16
- data/lib/lutaml/version.rb +1 -1
- data/lib/lutaml/xmi/parsers/xmi_base.rb +28 -5
- data/lib/lutaml.rb +3 -1
- data/lutaml.gemspec +2 -2
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9db8def51fe994ba67b18e3e2045df78ebc06fab52a471fb95e7421738e10dcc
|
|
4
|
+
data.tar.gz: 1ba2c6caed21e4a4b35b4a117f39327312505ebe2b72f389db3561f568395577
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a529f0ab5096212dc808a5cd21ca2eba20cbc8f1bc940076398755302af766462e66e3984d33ef9349d0510c0d25aa845af4b8b7046b6cdc93317d2d21aba5d
|
|
7
|
+
data.tar.gz: e26992d6162b77054ef39f915d4633a213452a98b6e0057ae4240ad825d7f008f529024ba91b3dfbd7dc77ac40a02e4ee3c01cbbdeabcbe3e77c2d5898ebe468
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,47 +1,32 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-04-
|
|
3
|
+
# on 2026-04-25 02:05:14 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
|
|
12
|
-
Bundler/OrderedGems:
|
|
13
|
-
Exclude:
|
|
14
|
-
- 'Gemfile'
|
|
15
|
-
|
|
16
|
-
# Offense count: 2
|
|
9
|
+
# Offense count: 1
|
|
17
10
|
# This cop supports safe autocorrection (--autocorrect).
|
|
18
|
-
Layout/
|
|
11
|
+
Layout/ElseAlignment:
|
|
19
12
|
Exclude:
|
|
20
|
-
- 'lib/lutaml/qea/
|
|
13
|
+
- 'lib/lutaml/qea/factory/class_transformer.rb'
|
|
21
14
|
|
|
22
|
-
# Offense count:
|
|
15
|
+
# Offense count: 1
|
|
23
16
|
# This cop supports safe autocorrection (--autocorrect).
|
|
24
|
-
# Configuration parameters:
|
|
25
|
-
#
|
|
26
|
-
Layout/
|
|
17
|
+
# Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
|
|
18
|
+
# SupportedStylesAlignWith: start_of_line, relative_to_receiver
|
|
19
|
+
Layout/IndentationWidth:
|
|
27
20
|
Exclude:
|
|
28
|
-
- 'lib/lutaml/qea/
|
|
21
|
+
- 'lib/lutaml/qea/factory/class_transformer.rb'
|
|
29
22
|
|
|
30
|
-
# Offense count:
|
|
23
|
+
# Offense count: 80
|
|
31
24
|
# This cop supports safe autocorrection (--autocorrect).
|
|
32
25
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
33
26
|
# URISchemes: http, https
|
|
34
27
|
Layout/LineLength:
|
|
35
28
|
Enabled: false
|
|
36
29
|
|
|
37
|
-
# Offense count: 2
|
|
38
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
39
|
-
# Configuration parameters: EnforcedStyle.
|
|
40
|
-
# SupportedStyles: symmetrical, new_line, same_line
|
|
41
|
-
Layout/MultilineMethodCallBraceLayout:
|
|
42
|
-
Exclude:
|
|
43
|
-
- 'lib/lutaml/qea/verification/document_verifier.rb'
|
|
44
|
-
|
|
45
30
|
# Offense count: 1
|
|
46
31
|
Lint/BinaryOperatorWithIdenticalOperands:
|
|
47
32
|
Exclude:
|
|
@@ -58,6 +43,11 @@ Lint/ConstantDefinitionInBlock:
|
|
|
58
43
|
- 'spec/lutaml/model_transformations_spec.rb'
|
|
59
44
|
- 'spec/lutaml/uml_repository/presenters/presenter_factory_spec.rb'
|
|
60
45
|
|
|
46
|
+
# Offense count: 1
|
|
47
|
+
Lint/CopDirectiveSyntax:
|
|
48
|
+
Exclude:
|
|
49
|
+
- 'lib/lutaml/uml_repository/repository.rb'
|
|
50
|
+
|
|
61
51
|
# Offense count: 8
|
|
62
52
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
|
63
53
|
Lint/DuplicateBranch:
|
|
@@ -107,13 +97,17 @@ Lint/UnusedMethodArgument:
|
|
|
107
97
|
Exclude:
|
|
108
98
|
- 'lib/lutaml/cli/uml/export_command.rb'
|
|
109
99
|
|
|
110
|
-
# Offense count:
|
|
100
|
+
# Offense count: 8
|
|
111
101
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
112
102
|
Metrics/AbcSize:
|
|
113
103
|
Exclude:
|
|
104
|
+
- 'lib/lutaml/converter/xmi_to_uml.rb'
|
|
114
105
|
- 'lib/lutaml/model_transformations/parsers/base_parser.rb'
|
|
106
|
+
- 'lib/lutaml/qea/database.rb'
|
|
115
107
|
- 'lib/lutaml/uml_repository/index_builder.rb'
|
|
108
|
+
- 'lib/lutaml/uml_repository/queries/class_query.rb'
|
|
116
109
|
- 'lib/lutaml/uml_repository/queries/inheritance_query.rb'
|
|
110
|
+
- 'lib/lutaml/xmi/parsers/xmi_base.rb'
|
|
117
111
|
|
|
118
112
|
# Offense count: 1
|
|
119
113
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
|
@@ -121,26 +115,36 @@ Metrics/AbcSize:
|
|
|
121
115
|
Metrics/BlockLength:
|
|
122
116
|
Max: 28
|
|
123
117
|
|
|
124
|
-
# Offense count:
|
|
118
|
+
# Offense count: 11
|
|
125
119
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
126
120
|
Metrics/CyclomaticComplexity:
|
|
127
121
|
Exclude:
|
|
128
122
|
- 'lib/lutaml/cli/tree_view_formatter.rb'
|
|
129
123
|
- 'lib/lutaml/converter/xmi_to_uml.rb'
|
|
124
|
+
- 'lib/lutaml/qea/database.rb'
|
|
125
|
+
- 'lib/lutaml/qea/factory/enum_transformer.rb'
|
|
126
|
+
- 'lib/lutaml/uml_repository/index_builder.rb'
|
|
127
|
+
- 'lib/lutaml/uml_repository/queries/class_query.rb'
|
|
130
128
|
- 'lib/lutaml/uml_repository/queries/inheritance_query.rb'
|
|
131
129
|
- 'lib/lutaml/uml_repository/queries/search_query.rb'
|
|
130
|
+
- 'lib/lutaml/xmi/parsers/xmi_base.rb'
|
|
132
131
|
|
|
133
|
-
# Offense count:
|
|
132
|
+
# Offense count: 11
|
|
134
133
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
135
134
|
Metrics/MethodLength:
|
|
136
|
-
Max:
|
|
135
|
+
Max: 27
|
|
137
136
|
|
|
138
|
-
# Offense count:
|
|
137
|
+
# Offense count: 8
|
|
139
138
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
140
139
|
Metrics/PerceivedComplexity:
|
|
141
140
|
Exclude:
|
|
141
|
+
- 'lib/lutaml/converter/xmi_to_uml.rb'
|
|
142
|
+
- 'lib/lutaml/qea/database.rb'
|
|
142
143
|
- 'lib/lutaml/qea/factory/enum_transformer.rb'
|
|
144
|
+
- 'lib/lutaml/uml_repository/index_builder.rb'
|
|
145
|
+
- 'lib/lutaml/uml_repository/queries/class_query.rb'
|
|
143
146
|
- 'lib/lutaml/uml_repository/queries/inheritance_query.rb'
|
|
147
|
+
- 'lib/lutaml/xmi/parsers/xmi_base.rb'
|
|
144
148
|
|
|
145
149
|
# Offense count: 2
|
|
146
150
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
|
@@ -158,10 +162,11 @@ Naming/PredicateMethod:
|
|
|
158
162
|
Exclude:
|
|
159
163
|
- 'lib/lutaml/qea/factory/document_builder.rb'
|
|
160
164
|
|
|
161
|
-
# Offense count:
|
|
165
|
+
# Offense count: 5
|
|
162
166
|
# Configuration parameters: MinSize.
|
|
163
167
|
Performance/CollectionLiteralInLoop:
|
|
164
168
|
Exclude:
|
|
169
|
+
- 'lib/lutaml/xmi/parsers/xmi_base.rb'
|
|
165
170
|
- 'spec/lutaml/qea/infrastructure/table_reader_spec.rb'
|
|
166
171
|
- 'spec/lutaml/uml_repository/index_builder_spec.rb'
|
|
167
172
|
- 'spec/lutaml/uml_repository/queries/inheritance_query_spec.rb'
|
|
@@ -206,7 +211,7 @@ RSpec/ContextWording:
|
|
|
206
211
|
RSpec/DescribeClass:
|
|
207
212
|
Enabled: false
|
|
208
213
|
|
|
209
|
-
# Offense count:
|
|
214
|
+
# Offense count: 657
|
|
210
215
|
# Configuration parameters: CountAsOne.
|
|
211
216
|
RSpec/ExampleLength:
|
|
212
217
|
Max: 108
|
|
@@ -236,7 +241,7 @@ RSpec/IndexedLet:
|
|
|
236
241
|
- 'spec/lutaml/qea/repositories/base_repository_spec.rb'
|
|
237
242
|
- 'spec/lutaml/qea/repositories/object_repository_spec.rb'
|
|
238
243
|
|
|
239
|
-
# Offense count:
|
|
244
|
+
# Offense count: 48
|
|
240
245
|
# Configuration parameters: AssignmentOnly.
|
|
241
246
|
RSpec/InstanceVariable:
|
|
242
247
|
Exclude:
|
|
@@ -274,11 +279,11 @@ RSpec/MessageSpies:
|
|
|
274
279
|
- 'spec/lutaml/uml_repository/presenters/diagram_presenter_spec.rb'
|
|
275
280
|
- 'spec/lutaml/uml_repository/repository_spec.rb'
|
|
276
281
|
|
|
277
|
-
# Offense count:
|
|
282
|
+
# Offense count: 946
|
|
278
283
|
RSpec/MultipleExpectations:
|
|
279
284
|
Max: 26
|
|
280
285
|
|
|
281
|
-
# Offense count:
|
|
286
|
+
# Offense count: 130
|
|
282
287
|
# Configuration parameters: AllowSubject.
|
|
283
288
|
RSpec/MultipleMemoizedHelpers:
|
|
284
289
|
Max: 11
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.10.3 (2026-04-25)
|
|
4
|
+
|
|
5
|
+
### Performance
|
|
6
|
+
|
|
7
|
+
- Replace O(n) linear scans with O(1) hash lookups in QEA transformers
|
|
8
|
+
and XMI parsers (connector, diagram, element lookups)
|
|
9
|
+
- Single-pass IndexBuilder replacing 9 separate tree traversals
|
|
10
|
+
- Memoized inheritance depth in StatisticsCalculator
|
|
11
|
+
- Set-based dedup in Repository associations_index
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
- Fix Windows EACCES: replace Tempfile.new with temp_lur_path helper
|
|
16
|
+
to avoid file handle conflicts with rubyzip
|
|
17
|
+
- Fix xml_spec: use include matcher for platform-varying content nodes
|
|
18
|
+
|
|
19
|
+
### Improvements
|
|
20
|
+
|
|
21
|
+
- Consistent error hierarchy: all module error classes now inherit from
|
|
22
|
+
`Lutaml::Error` (single rescue point for consumers)
|
|
23
|
+
- Fix gemspec email typo (mismatched quote)
|
|
24
|
+
- Bump required_ruby_version from >= 2.7 to >= 3.2 (matching CI)
|
|
25
|
+
- Rubocop: 0 offenses remaining
|
|
26
|
+
|
|
27
|
+
## v0.10.2 (2026-04-24)
|
|
28
|
+
|
|
29
|
+
### Bug fixes
|
|
30
|
+
|
|
31
|
+
- Fix Windows Errno::EACCES in PackageExporter: retry on file lock race
|
|
32
|
+
- Remove moxml git override (0.1.15 released)
|
|
33
|
+
|
|
34
|
+
## v0.10.1 (2026-04-23)
|
|
35
|
+
|
|
36
|
+
### Bug fixes
|
|
37
|
+
|
|
38
|
+
- Fix flaky CI tests: benchmark speedup assertion and Windows Tempfile race
|
|
39
|
+
- Fix xmi 0.5.6 compatibility: rename SparxRoot to Sparx::Root
|
|
40
|
+
- Fix nil @xmi_index in liquid drops: auto-init via xmi_index method
|
|
41
|
+
- Fix infinite loop in resolve_package_path with circular package hierarchy
|
|
42
|
+
- Fix stereotype type bugs, diagram package_id overwrite, and
|
|
43
|
+
DataTypeTransformer crash
|
|
44
|
+
- Fix 46 pending/failing spec tests across QEA, verification, and liquid specs
|
|
45
|
+
|
|
46
|
+
## v0.10.0 (2026-04-21)
|
|
47
|
+
|
|
48
|
+
### Breaking changes
|
|
49
|
+
|
|
50
|
+
- Update to lutaml-model 0.8.0, expressir 2.3, and xmi 0.5.x
|
|
51
|
+
- Migrate Lutaml::Uml models to lutaml-model serialization
|
|
52
|
+
- Unify namespace of Sysml module
|
|
53
|
+
|
|
54
|
+
### Features
|
|
55
|
+
|
|
56
|
+
- Complete QEA to UML document migration
|
|
57
|
+
- Add PackagePresenter for structured output
|
|
58
|
+
- Add option to skip queries
|
|
59
|
+
- Add function to get qualified name
|
|
60
|
+
- Add Lutaml::Uml::Fidelity class
|
|
61
|
+
- Add attributes type, weight and status to Lutaml::Uml::Constraint
|
|
62
|
+
- Add generalization into Lutaml::Uml::Class
|
|
63
|
+
- Transform option keys to symbol
|
|
64
|
+
- Output find result based on format option
|
|
65
|
+
- Implement default sorting for diff_with_score comparison
|
|
66
|
+
- find_by_name returns single object instead of array
|
|
67
|
+
|
|
68
|
+
### Bug fixes
|
|
69
|
+
|
|
70
|
+
- Fix Windows EACCES file rename issues (Tempfile handle conflicts)
|
|
71
|
+
- Fix YAML disallowed class loading error
|
|
72
|
+
- Fix attribute parsing values
|
|
73
|
+
- Fix association loading by QEA parser
|
|
74
|
+
- Fix association_generalization parsed by xmi parser
|
|
75
|
+
- Fix certificate CRL error
|
|
76
|
+
|
|
77
|
+
## v0.9.43 (2025-11-20)
|
|
78
|
+
|
|
79
|
+
- Refactor klass_hash to use KlassDrop object in upper_klass
|
|
80
|
+
|
|
81
|
+
## v0.9.42 (2025-11-18)
|
|
82
|
+
|
|
83
|
+
- Directly convert XMI into UML
|
|
84
|
+
|
|
85
|
+
## v0.9.41 (2025-11-12)
|
|
86
|
+
|
|
87
|
+
- Remove unneeded version files
|
|
88
|
+
- Fix error when imports key is nil
|
|
89
|
+
- Unify Sysml namespace
|
|
90
|
+
|
|
91
|
+
## v0.9.40 (2025-11-10)
|
|
92
|
+
|
|
93
|
+
- Convert DSL to UML
|
|
94
|
+
- Change namespace of Formatter and HasAttributes
|
|
95
|
+
- Update GraphViz and related specs
|
|
96
|
+
- Add Lutaml::Uml::Fidelity class
|
|
97
|
+
- Remove duplicated GraphViz code
|
|
98
|
+
- Create Lutaml::Uml models by Xmi hash
|
|
99
|
+
- Migrate Lutaml::Uml models to lutaml-model
|
|
100
|
+
|
|
101
|
+
## v0.9.39 (2025-11-03)
|
|
102
|
+
|
|
103
|
+
- Change selection criteria for dependencies
|
|
104
|
+
|
|
105
|
+
## v0.9.38 (2025-10-31)
|
|
106
|
+
|
|
107
|
+
- Add subtype_of to klass and enum drop models
|
|
108
|
+
- Get stereotype by type idref in owned attribute
|
|
@@ -139,8 +139,8 @@ module Lutaml
|
|
|
139
139
|
|
|
140
140
|
desc "diagram ACTION", "Diagram rendering commands"
|
|
141
141
|
Uml::DiagramCommand.add_options_to(self, :diagram)
|
|
142
|
-
def diagram(action, *
|
|
143
|
-
Uml::DiagramCommand.new(options.to_h).run(action, *
|
|
142
|
+
def diagram(action, *)
|
|
143
|
+
Uml::DiagramCommand.new(options.to_h).run(action, *)
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
# ===================================================================
|
data/lib/lutaml/command_line.rb
CHANGED
|
@@ -126,9 +126,7 @@ module Lutaml
|
|
|
126
126
|
def create_uml_diagrams(node_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
127
127
|
return [] if @xmi_root_model.extension&.diagrams&.diagram.nil?
|
|
128
128
|
|
|
129
|
-
diagrams =
|
|
130
|
-
d.model.package == node_id
|
|
131
|
-
end
|
|
129
|
+
diagrams = diagram_lookup[node_id]
|
|
132
130
|
|
|
133
131
|
diagrams.map do |diagram|
|
|
134
132
|
::Lutaml::Uml::Diagram.new.tap do |dia|
|
|
@@ -145,6 +143,17 @@ module Lutaml
|
|
|
145
143
|
end
|
|
146
144
|
end
|
|
147
145
|
|
|
146
|
+
# Lazy-built hash index for O(1) diagram lookups by package
|
|
147
|
+
# @return [Hash] Mapping of package_id => [diagrams]
|
|
148
|
+
def diagram_lookup
|
|
149
|
+
@diagram_lookup ||= begin
|
|
150
|
+
idx = Hash.new { |h, k| h[k] = [] }
|
|
151
|
+
diagrams = @xmi_root_model.extension&.diagrams&.diagram || []
|
|
152
|
+
diagrams.each { |d| idx[d.model.package] << d if d.model&.package }
|
|
153
|
+
idx
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
148
157
|
def create_uml_class_attributes(klass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
|
149
158
|
return [] if klass.owned_attribute.nil?
|
|
150
159
|
|
|
@@ -421,7 +421,7 @@ module Lutaml
|
|
|
421
421
|
end
|
|
422
422
|
|
|
423
423
|
# Custom error class for parsing failures
|
|
424
|
-
class ParseError <
|
|
424
|
+
class ParseError < Lutaml::Error
|
|
425
425
|
# @return [StandardError] Original error that caused parsing failure
|
|
426
426
|
attr_reader :original_error
|
|
427
427
|
|
|
@@ -392,7 +392,7 @@ module Lutaml
|
|
|
392
392
|
end
|
|
393
393
|
|
|
394
394
|
# Error class for unsupported file formats
|
|
395
|
-
class UnsupportedFormatError <
|
|
395
|
+
class UnsupportedFormatError < Lutaml::Error
|
|
396
396
|
# @return [String] Path to the unsupported file
|
|
397
397
|
attr_reader :file_path
|
|
398
398
|
|
data/lib/lutaml/qea/database.rb
CHANGED
|
@@ -268,7 +268,9 @@ module Lutaml
|
|
|
268
268
|
# @param id [Integer] Package ID
|
|
269
269
|
# @return [Models::EaPackage, nil] The package or nil if not found
|
|
270
270
|
def find_package(id)
|
|
271
|
-
|
|
271
|
+
@packages_by_id ||= build_group_index(packages, :package_id,
|
|
272
|
+
single: true)
|
|
273
|
+
@packages_by_id[id]
|
|
272
274
|
end
|
|
273
275
|
|
|
274
276
|
# Find an attribute by ID
|
|
@@ -276,7 +278,8 @@ module Lutaml
|
|
|
276
278
|
# @param id [Integer] Attribute ID
|
|
277
279
|
# @return [Models::EaAttribute, nil] The attribute or nil if not found
|
|
278
280
|
def find_attribute(id)
|
|
279
|
-
|
|
281
|
+
@attributes_by_id ||= build_group_index(attributes, :id, single: true)
|
|
282
|
+
@attributes_by_id[id]
|
|
280
283
|
end
|
|
281
284
|
|
|
282
285
|
# Find a connector by ID
|
|
@@ -284,7 +287,9 @@ module Lutaml
|
|
|
284
287
|
# @param id [Integer] Connector ID
|
|
285
288
|
# @return [Models::EaConnector, nil] The connector or nil if not found
|
|
286
289
|
def find_connector(id)
|
|
287
|
-
|
|
290
|
+
@connectors_by_id ||= build_group_index(connectors, :connector_id,
|
|
291
|
+
single: true)
|
|
292
|
+
@connectors_by_id[id]
|
|
288
293
|
end
|
|
289
294
|
|
|
290
295
|
# Find a diagram by ID
|
|
@@ -292,7 +297,9 @@ module Lutaml
|
|
|
292
297
|
# @param id [Integer] Diagram ID
|
|
293
298
|
# @return [Models::EaDiagram, nil] The diagram or nil if not found
|
|
294
299
|
def find_diagram(id)
|
|
295
|
-
|
|
300
|
+
@diagrams_by_id ||= build_group_index(diagrams, :diagram_id,
|
|
301
|
+
single: true)
|
|
302
|
+
@diagrams_by_id[id]
|
|
296
303
|
end
|
|
297
304
|
|
|
298
305
|
# Check if database is empty
|
|
@@ -309,6 +316,102 @@ module Lutaml
|
|
|
309
316
|
@collections.keys
|
|
310
317
|
end
|
|
311
318
|
|
|
319
|
+
# Find object by ea_guid
|
|
320
|
+
#
|
|
321
|
+
# @param ea_guid [String] Object GUID
|
|
322
|
+
# @return [Models::EaObject, nil] The object or nil if not found
|
|
323
|
+
def find_object_by_guid(ea_guid)
|
|
324
|
+
@objects_by_guid ||= build_group_index(objects, :ea_guid, single: true)
|
|
325
|
+
@objects_by_guid[ea_guid]
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Get attributes for a specific object
|
|
329
|
+
#
|
|
330
|
+
# @param object_id [Integer] Object ID
|
|
331
|
+
# @return [Array<Models::EaAttribute>] Attributes for the object
|
|
332
|
+
def attributes_for_object(object_id)
|
|
333
|
+
@attributes_by_object_id ||= build_group_index(attributes,
|
|
334
|
+
:ea_object_id)
|
|
335
|
+
@attributes_by_object_id[object_id] || []
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Get operations for a specific object
|
|
339
|
+
#
|
|
340
|
+
# @param object_id [Integer] Object ID
|
|
341
|
+
# @return [Array<Models::EaOperation>] Operations for the object
|
|
342
|
+
def operations_for_object(object_id)
|
|
343
|
+
@operations_by_object_id ||= build_group_index(operations,
|
|
344
|
+
:ea_object_id)
|
|
345
|
+
@operations_by_object_id[object_id] || []
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Get operation parameters for a specific operation
|
|
349
|
+
#
|
|
350
|
+
# @param operation_id [Integer] Operation ID
|
|
351
|
+
# @return [Array<Models::EaOperationParam>] Parameters for the operation
|
|
352
|
+
def operation_params_for(operation_id)
|
|
353
|
+
@operation_params_by_id ||= build_group_index(operation_params,
|
|
354
|
+
:operationid)
|
|
355
|
+
@operation_params_by_id[operation_id] || []
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# Get connectors involving a specific object (start or end)
|
|
359
|
+
#
|
|
360
|
+
# @param object_id [Integer] Object ID
|
|
361
|
+
# @return [Array<Models::EaConnector>] Connectors for the object
|
|
362
|
+
def connectors_for_object(object_id)
|
|
363
|
+
@connectors_by_start ||= build_group_index(connectors, :start_object_id)
|
|
364
|
+
@connectors_by_end ||= build_group_index(connectors, :end_object_id)
|
|
365
|
+
(@connectors_by_start[object_id] || []) +
|
|
366
|
+
(@connectors_by_end[object_id] || [])
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# Get child packages for a parent
|
|
370
|
+
#
|
|
371
|
+
# @param parent_id [Integer] Parent package ID
|
|
372
|
+
# @return [Array<Models::EaPackage>] Child packages
|
|
373
|
+
def child_packages_for(parent_id)
|
|
374
|
+
@packages_by_parent ||= build_group_index(packages, :parent_id)
|
|
375
|
+
@packages_by_parent[parent_id] || []
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# Get objects in a specific package
|
|
379
|
+
#
|
|
380
|
+
# @param package_id [Integer] Package ID
|
|
381
|
+
# @return [Array<Models::EaObject>] Objects in the package
|
|
382
|
+
def objects_in_package(package_id)
|
|
383
|
+
@objects_by_package_id ||= build_group_index(objects, :package_id)
|
|
384
|
+
@objects_by_package_id[package_id] || []
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Get diagrams in a specific package
|
|
388
|
+
#
|
|
389
|
+
# @param package_id [Integer] Package ID
|
|
390
|
+
# @return [Array<Models::EaDiagram>] Diagrams in the package
|
|
391
|
+
def diagrams_in_package(package_id)
|
|
392
|
+
@diagrams_by_package_id ||= build_group_index(diagrams, :package_id)
|
|
393
|
+
@diagrams_by_package_id[package_id] || []
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Get diagram objects for a specific diagram
|
|
397
|
+
#
|
|
398
|
+
# @param diagram_id [Integer] Diagram ID
|
|
399
|
+
# @return [Array<Models::EaDiagramObject>] Diagram objects
|
|
400
|
+
def diagram_objects_for(diagram_id)
|
|
401
|
+
@diagram_objects_by_id ||= build_group_index(diagram_objects,
|
|
402
|
+
:diagram_id)
|
|
403
|
+
@diagram_objects_by_id[diagram_id] || []
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Get diagram links for a specific diagram
|
|
407
|
+
#
|
|
408
|
+
# @param diagram_id [Integer] Diagram ID
|
|
409
|
+
# @return [Array<Models::EaDiagramLink>] Diagram links
|
|
410
|
+
def diagram_links_for(diagram_id)
|
|
411
|
+
@diagram_links_by_id ||= build_group_index(diagram_links, :diagramid)
|
|
412
|
+
@diagram_links_by_id[diagram_id] || []
|
|
413
|
+
end
|
|
414
|
+
|
|
312
415
|
# Freeze all collections to make database immutable
|
|
313
416
|
#
|
|
314
417
|
# @return [self]
|
|
@@ -316,9 +419,59 @@ module Lutaml
|
|
|
316
419
|
# Memoize repositories before freezing
|
|
317
420
|
objects
|
|
318
421
|
|
|
422
|
+
# Eagerly build all lookup indexes before freezing
|
|
423
|
+
build_lookup_indexes
|
|
424
|
+
|
|
319
425
|
@collections.freeze
|
|
320
426
|
super
|
|
321
427
|
end
|
|
428
|
+
|
|
429
|
+
private
|
|
430
|
+
|
|
431
|
+
# Build a group index from a collection by a given attribute.
|
|
432
|
+
# BaseRepository overrides group_by to take a symbol (not a block),
|
|
433
|
+
# so we use each_with_object instead.
|
|
434
|
+
#
|
|
435
|
+
# @param collection [Array] Collection to index
|
|
436
|
+
# @param method [Symbol] Attribute method to group by
|
|
437
|
+
# @param single [Boolean] If true, return single object (last match)
|
|
438
|
+
# instead of array
|
|
439
|
+
# @return [Hash] Group index
|
|
440
|
+
def build_group_index(collection, method, single: false)
|
|
441
|
+
if single
|
|
442
|
+
collection.each_with_object({}) do |item, hash|
|
|
443
|
+
key = item.send(method)
|
|
444
|
+
hash[key] = item if key
|
|
445
|
+
end
|
|
446
|
+
else
|
|
447
|
+
collection.each_with_object({}) do |item, hash|
|
|
448
|
+
key = item.send(method)
|
|
449
|
+
(hash[key] ||= []) << item if key
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# Eagerly build all lazy lookup indexes before freezing
|
|
455
|
+
def build_lookup_indexes
|
|
456
|
+
@objects_by_guid = build_group_index(objects, :ea_guid, single: true)
|
|
457
|
+
@attributes_by_object_id = build_group_index(attributes, :ea_object_id)
|
|
458
|
+
@operations_by_object_id = build_group_index(operations, :ea_object_id)
|
|
459
|
+
@operation_params_by_id = build_group_index(operation_params,
|
|
460
|
+
:operationid)
|
|
461
|
+
@connectors_by_start = build_group_index(connectors, :start_object_id)
|
|
462
|
+
@connectors_by_end = build_group_index(connectors, :end_object_id)
|
|
463
|
+
@packages_by_parent = build_group_index(packages, :parent_id)
|
|
464
|
+
@objects_by_package_id = build_group_index(objects, :package_id)
|
|
465
|
+
@diagrams_by_package_id = build_group_index(diagrams, :package_id)
|
|
466
|
+
@diagram_objects_by_id = build_group_index(diagram_objects, :diagram_id)
|
|
467
|
+
@diagram_links_by_id = build_group_index(diagram_links, :diagramid)
|
|
468
|
+
# Also build hash indexes for find_* methods
|
|
469
|
+
@packages_by_id = build_group_index(packages, :package_id, single: true)
|
|
470
|
+
@connectors_by_id = build_group_index(connectors, :connector_id,
|
|
471
|
+
single: true)
|
|
472
|
+
@diagrams_by_id = build_group_index(diagrams, :diagram_id, single: true)
|
|
473
|
+
@attributes_by_id = build_group_index(attributes, :id, single: true)
|
|
474
|
+
end
|
|
322
475
|
end
|
|
323
476
|
end
|
|
324
477
|
end
|
|
@@ -71,11 +71,7 @@ module Lutaml
|
|
|
71
71
|
def find_object(object_id)
|
|
72
72
|
return nil if object_id.nil?
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
rows = database.connection.execute(query, object_id)
|
|
76
|
-
return nil if rows.empty?
|
|
77
|
-
|
|
78
|
-
Models::EaObject.from_db_row(rows.first)
|
|
74
|
+
database.find_object(object_id)
|
|
79
75
|
end
|
|
80
76
|
|
|
81
77
|
# Build cardinality from string
|
|
@@ -55,16 +55,10 @@ module Lutaml
|
|
|
55
55
|
def lookup_type_xmi_id(classifier_id) # rubocop:disable Metrics/AbcSize
|
|
56
56
|
return nil if classifier_id.nil? || classifier_id.to_i.zero?
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
ea_guid = if rows.first.is_a?(Hash)
|
|
63
|
-
rows.first["ea_guid"] || rows.first[:ea_guid]
|
|
64
|
-
else
|
|
65
|
-
rows.first[0]
|
|
66
|
-
end
|
|
67
|
-
normalize_guid_to_xmi_format(ea_guid, "EAID")
|
|
58
|
+
obj = database.find_object(classifier_id.to_i)
|
|
59
|
+
return nil unless obj
|
|
60
|
+
|
|
61
|
+
normalize_guid_to_xmi_format(obj.ea_guid, "EAID")
|
|
68
62
|
end
|
|
69
63
|
|
|
70
64
|
# Build cardinality from lower and upper bounds
|
|
@@ -120,11 +120,7 @@ module Lutaml
|
|
|
120
120
|
def find_object_by_id(object_id)
|
|
121
121
|
return nil if object_id.nil?
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
rows = database.connection.execute(query, object_id)
|
|
125
|
-
return nil if rows.empty?
|
|
126
|
-
|
|
127
|
-
Models::EaObject.from_db_row(rows.first)
|
|
123
|
+
database.find_object(object_id)
|
|
128
124
|
end
|
|
129
125
|
end
|
|
130
126
|
end
|