unitsdb 2.1.1 → 2.2.1
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/.github/workflows/release.yml +8 -1
- data/.gitignore +2 -0
- data/.gitmodules +4 -3
- data/.rubocop.yml +13 -8
- data/.rubocop_todo.yml +217 -100
- data/CLAUDE.md +55 -0
- data/Gemfile +4 -1
- data/README.adoc +283 -16
- data/data/dimensions.yaml +1864 -0
- data/data/prefixes.yaml +874 -0
- data/data/quantities.yaml +3715 -0
- data/data/scales.yaml +97 -0
- data/data/schemas/dimensions-schema.yaml +153 -0
- data/data/schemas/prefixes-schema.yaml +155 -0
- data/data/schemas/quantities-schema.yaml +117 -0
- data/data/schemas/scales-schema.yaml +106 -0
- data/data/schemas/unit_systems-schema.yaml +116 -0
- data/data/schemas/units-schema.yaml +215 -0
- data/data/unit_systems.yaml +78 -0
- data/data/units.yaml +14052 -0
- data/exe/unitsdb +7 -1
- data/lib/unitsdb/cli.rb +42 -15
- data/lib/unitsdb/commands/_modify.rb +40 -4
- data/lib/unitsdb/commands/base.rb +6 -2
- data/lib/unitsdb/commands/check_si/si_formatter.rb +488 -0
- data/lib/unitsdb/commands/check_si/si_matcher.rb +487 -0
- data/lib/unitsdb/commands/check_si/si_ttl_parser.rb +103 -0
- data/lib/unitsdb/commands/check_si/si_updater.rb +254 -0
- data/lib/unitsdb/commands/check_si.rb +54 -35
- data/lib/unitsdb/commands/get.rb +11 -10
- data/lib/unitsdb/commands/normalize.rb +21 -7
- data/lib/unitsdb/commands/qudt/check.rb +150 -0
- data/lib/unitsdb/commands/qudt/formatter.rb +194 -0
- data/lib/unitsdb/commands/qudt/matcher.rb +746 -0
- data/lib/unitsdb/commands/qudt/ttl_parser.rb +403 -0
- data/lib/unitsdb/commands/qudt/update.rb +126 -0
- data/lib/unitsdb/commands/qudt/updater.rb +189 -0
- data/lib/unitsdb/commands/qudt.rb +82 -0
- data/lib/unitsdb/commands/release.rb +12 -9
- data/lib/unitsdb/commands/search.rb +12 -11
- data/lib/unitsdb/commands/ucum/check.rb +42 -29
- data/lib/unitsdb/commands/ucum/formatter.rb +2 -1
- data/lib/unitsdb/commands/ucum/matcher.rb +23 -9
- data/lib/unitsdb/commands/ucum/update.rb +14 -13
- data/lib/unitsdb/commands/ucum/updater.rb +40 -6
- data/lib/unitsdb/commands/ucum/xml_parser.rb +0 -2
- data/lib/unitsdb/commands/ucum.rb +44 -4
- data/lib/unitsdb/commands/validate/identifiers.rb +2 -4
- data/lib/unitsdb/commands/validate/qudt_references.rb +111 -0
- data/lib/unitsdb/commands/validate/references.rb +36 -19
- data/lib/unitsdb/commands/validate/si_references.rb +3 -5
- data/lib/unitsdb/commands/validate/ucum_references.rb +105 -0
- data/lib/unitsdb/commands/validate.rb +67 -11
- data/lib/unitsdb/commands.rb +20 -0
- data/lib/unitsdb/database.rb +90 -52
- data/lib/unitsdb/dimension.rb +1 -4
- data/lib/unitsdb/dimension_details.rb +0 -1
- data/lib/unitsdb/dimensions.rb +0 -2
- data/lib/unitsdb/errors.rb +7 -0
- data/lib/unitsdb/prefix.rb +0 -4
- data/lib/unitsdb/prefix_reference.rb +0 -2
- data/lib/unitsdb/prefixes.rb +0 -1
- data/lib/unitsdb/quantities.rb +0 -2
- data/lib/unitsdb/quantity.rb +0 -6
- data/lib/unitsdb/qudt.rb +100 -0
- data/lib/unitsdb/root_unit_reference.rb +0 -3
- data/lib/unitsdb/scale.rb +0 -4
- data/lib/unitsdb/scale_reference.rb +0 -2
- data/lib/unitsdb/scales.rb +0 -2
- data/lib/unitsdb/si_derived_base.rb +0 -2
- data/lib/unitsdb/ucum.rb +14 -10
- data/lib/unitsdb/unit.rb +0 -10
- data/lib/unitsdb/unit_reference.rb +0 -2
- data/lib/unitsdb/unit_system.rb +1 -3
- data/lib/unitsdb/unit_system_reference.rb +0 -2
- data/lib/unitsdb/unit_systems.rb +0 -2
- data/lib/unitsdb/units.rb +0 -2
- data/lib/unitsdb/utils.rb +32 -21
- data/lib/unitsdb/version.rb +5 -1
- data/lib/unitsdb.rb +62 -14
- data/unitsdb.gemspec +6 -3
- metadata +52 -13
- data/lib/unitsdb/commands/si_formatter.rb +0 -485
- data/lib/unitsdb/commands/si_matcher.rb +0 -470
- data/lib/unitsdb/commands/si_ttl_parser.rb +0 -100
- data/lib/unitsdb/commands/si_updater.rb +0 -212
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "terminal-table"
|
|
4
|
-
require_relative "si_ttl_parser"
|
|
5
|
-
|
|
6
|
-
module Unitsdb
|
|
7
|
-
module Commands
|
|
8
|
-
# Formatter for SI check results
|
|
9
|
-
module SiFormatter
|
|
10
|
-
module_function
|
|
11
|
-
|
|
12
|
-
# Display TTL → DB results
|
|
13
|
-
def display_si_results(entity_type, matches, missing_matches, unmatched_ttl)
|
|
14
|
-
puts "\n=== #{entity_type.capitalize} with matching SI references ==="
|
|
15
|
-
if matches.empty?
|
|
16
|
-
puts "None"
|
|
17
|
-
else
|
|
18
|
-
rows = []
|
|
19
|
-
matches.each do |match|
|
|
20
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(match[:si_uri])
|
|
21
|
-
rows << [
|
|
22
|
-
"UnitsDB: #{match[:entity_id]}",
|
|
23
|
-
"(#{match[:entity_name] || "unnamed"})"
|
|
24
|
-
]
|
|
25
|
-
rows << [
|
|
26
|
-
"SI TTL: #{si_suffix}",
|
|
27
|
-
"(#{match[:si_label] || match[:si_name] || "unnamed"})"
|
|
28
|
-
]
|
|
29
|
-
rows << :separator unless match == matches.last
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
table = Terminal::Table.new(
|
|
33
|
-
title: "Valid SI Reference Mappings",
|
|
34
|
-
rows: rows
|
|
35
|
-
)
|
|
36
|
-
puts table
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
puts "\n=== #{entity_type.capitalize} without SI references ==="
|
|
40
|
-
if missing_matches.empty?
|
|
41
|
-
puts "None"
|
|
42
|
-
else
|
|
43
|
-
# Split matches into exact and potential
|
|
44
|
-
exact_matches = []
|
|
45
|
-
potential_matches = []
|
|
46
|
-
|
|
47
|
-
missing_matches.each do |match|
|
|
48
|
-
# Get match details
|
|
49
|
-
match_details = match[:match_details]
|
|
50
|
-
match_desc = match_details&.dig(:match_desc) || ""
|
|
51
|
-
|
|
52
|
-
# Symbol matches and partial matches should always be potential matches
|
|
53
|
-
if %w[symbol_match partial_match].include?(match_desc)
|
|
54
|
-
potential_matches << match
|
|
55
|
-
elsif match_details&.dig(:exact) == false
|
|
56
|
-
potential_matches << match
|
|
57
|
-
else
|
|
58
|
-
exact_matches << match
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Display exact matches
|
|
63
|
-
puts "\n=== Exact Matches (#{exact_matches.size}) ==="
|
|
64
|
-
if exact_matches.empty?
|
|
65
|
-
puts "None"
|
|
66
|
-
else
|
|
67
|
-
rows = []
|
|
68
|
-
exact_matches.each do |match|
|
|
69
|
-
# First row: UnitsDB entity
|
|
70
|
-
rows << [
|
|
71
|
-
"UnitsDB: #{match[:entity_id]}",
|
|
72
|
-
"(#{match[:entity_name] || "unnamed"})"
|
|
73
|
-
]
|
|
74
|
-
|
|
75
|
-
# Handle multiple SI matches in a single cell if present
|
|
76
|
-
if match[:multiple_si]
|
|
77
|
-
# Ensure no duplicate URIs
|
|
78
|
-
si_text_parts = []
|
|
79
|
-
si_label_parts = []
|
|
80
|
-
seen_uris = {}
|
|
81
|
-
|
|
82
|
-
match[:multiple_si].each do |si_data|
|
|
83
|
-
uri = si_data[:uri]
|
|
84
|
-
next if seen_uris[uri] # Skip if we've already seen this URI
|
|
85
|
-
|
|
86
|
-
seen_uris[uri] = true
|
|
87
|
-
|
|
88
|
-
suffix = SiTtlParser.extract_identifying_suffix(uri)
|
|
89
|
-
si_text_parts << suffix
|
|
90
|
-
si_label_parts << (si_data[:label] || si_data[:name])
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
rows << [
|
|
94
|
-
"SI TTL: #{si_text_parts.join(", ")}",
|
|
95
|
-
"(#{si_label_parts.join(", ")})"
|
|
96
|
-
]
|
|
97
|
-
else
|
|
98
|
-
# Second row: SI TTL suffix and label/name
|
|
99
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(match[:si_uri])
|
|
100
|
-
rows << [
|
|
101
|
-
"SI TTL: #{si_suffix}",
|
|
102
|
-
"(#{match[:si_label] || match[:si_name] || "unnamed"})"
|
|
103
|
-
]
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Status line with match type
|
|
107
|
-
match_details = match[:match_details]
|
|
108
|
-
match_desc = match_details&.dig(:match_desc) || ""
|
|
109
|
-
match_info = format_match_info(match_desc)
|
|
110
|
-
status_text = match_info.empty? ? "Missing reference" : "Missing reference (#{match_info})"
|
|
111
|
-
|
|
112
|
-
rows << [
|
|
113
|
-
"Status: #{status_text}",
|
|
114
|
-
"✗"
|
|
115
|
-
]
|
|
116
|
-
rows << :separator unless match == exact_matches.last
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
table = Terminal::Table.new(
|
|
120
|
-
title: "Exact Match Missing SI References",
|
|
121
|
-
rows: rows
|
|
122
|
-
)
|
|
123
|
-
puts table
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Display potential matches
|
|
127
|
-
puts "\n=== Potential Matches (#{potential_matches.size}) ==="
|
|
128
|
-
if potential_matches.empty?
|
|
129
|
-
puts "None"
|
|
130
|
-
else
|
|
131
|
-
rows = []
|
|
132
|
-
potential_matches.each do |match|
|
|
133
|
-
# First row: UnitsDB entity
|
|
134
|
-
rows << [
|
|
135
|
-
"UnitsDB: #{match[:entity_id]}",
|
|
136
|
-
"(#{match[:entity_name] || "unnamed"})"
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
# Handle multiple SI matches in a single cell if present
|
|
140
|
-
if match[:multiple_si]
|
|
141
|
-
# Ensure no duplicate URIs
|
|
142
|
-
si_text_parts = []
|
|
143
|
-
seen_uris = {}
|
|
144
|
-
|
|
145
|
-
match[:multiple_si].each do |si_data|
|
|
146
|
-
uri = si_data[:uri]
|
|
147
|
-
next if seen_uris[uri] # Skip if we've already seen this URI
|
|
148
|
-
|
|
149
|
-
seen_uris[uri] = true
|
|
150
|
-
|
|
151
|
-
suffix = SiTtlParser.extract_identifying_suffix(uri)
|
|
152
|
-
si_text_parts << "#{suffix} (#{si_data[:label] || si_data[:name]})"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
rows << [
|
|
156
|
-
"SI TTL: #{si_text_parts.join(", ")}",
|
|
157
|
-
""
|
|
158
|
-
]
|
|
159
|
-
else
|
|
160
|
-
# Single TTL entity
|
|
161
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(match[:si_uri])
|
|
162
|
-
rows << [
|
|
163
|
-
"SI TTL: #{si_suffix}",
|
|
164
|
-
"(#{match[:si_label] || match[:si_name] || "unnamed"})"
|
|
165
|
-
]
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Status line
|
|
169
|
-
match_details = match[:match_details]
|
|
170
|
-
match_desc = match_details&.dig(:match_desc) || ""
|
|
171
|
-
match_info = format_match_info(match_desc)
|
|
172
|
-
status_text = match_info.empty? ? "Missing reference" : "Missing reference"
|
|
173
|
-
|
|
174
|
-
rows << [
|
|
175
|
-
"Status: #{status_text}",
|
|
176
|
-
"✗"
|
|
177
|
-
]
|
|
178
|
-
rows << :separator unless match == potential_matches.last
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
table = Terminal::Table.new(
|
|
182
|
-
title: "Potential Match Missing SI References",
|
|
183
|
-
rows: rows
|
|
184
|
-
)
|
|
185
|
-
puts table
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
puts "\n=== SI #{entity_type.capitalize} not mapped to our database ==="
|
|
190
|
-
if unmatched_ttl.empty?
|
|
191
|
-
puts "None (All TTL entities are referenced - Good job!)"
|
|
192
|
-
else
|
|
193
|
-
# Group unmatched ttl entities by their URI to avoid duplicates
|
|
194
|
-
grouped_unmatched = {}
|
|
195
|
-
|
|
196
|
-
unmatched_ttl.each do |entity|
|
|
197
|
-
uri = entity[:uri]
|
|
198
|
-
grouped_unmatched[uri] = entity unless grouped_unmatched.key?(uri)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
rows = []
|
|
202
|
-
unique_entities = grouped_unmatched.values
|
|
203
|
-
|
|
204
|
-
unique_entities.each do |entity|
|
|
205
|
-
# Create the SI TTL row
|
|
206
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(entity[:uri])
|
|
207
|
-
ttl_row = ["SI TTL: #{si_suffix}", "(#{entity[:label] || entity[:name] || "unnamed"})"]
|
|
208
|
-
|
|
209
|
-
rows << ttl_row
|
|
210
|
-
rows << [
|
|
211
|
-
"Status: No matching UnitsDB entity",
|
|
212
|
-
"?"
|
|
213
|
-
]
|
|
214
|
-
rows << :separator unless entity == unique_entities.last
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
table = Terminal::Table.new(
|
|
218
|
-
title: "Unmapped SI Entities",
|
|
219
|
-
rows: rows
|
|
220
|
-
)
|
|
221
|
-
puts table
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# Display DB → TTL results
|
|
226
|
-
def display_db_results(entity_type, matches, missing_refs, unmatched_db)
|
|
227
|
-
puts "\n=== Summary of database entities referencing SI ==="
|
|
228
|
-
puts "#{entity_type.capitalize} with SI references: #{matches.size}"
|
|
229
|
-
puts "#{entity_type.capitalize} missing SI references: #{missing_refs.size}"
|
|
230
|
-
puts "Database #{entity_type} not matching any SI entity: #{unmatched_db.size}"
|
|
231
|
-
|
|
232
|
-
# Show entities with valid references
|
|
233
|
-
unless matches.empty?
|
|
234
|
-
puts "\n=== #{entity_type.capitalize} with SI references ==="
|
|
235
|
-
rows = []
|
|
236
|
-
matches.each do |match|
|
|
237
|
-
db_entity = match[:db_entity]
|
|
238
|
-
entity_id = match[:entity_id] || db_entity.short
|
|
239
|
-
entity_name = db_entity.respond_to?(:names) ? db_entity.names&.first : "unnamed"
|
|
240
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(match[:ttl_uri])
|
|
241
|
-
|
|
242
|
-
ttl_label = match[:ttl_entity] ? (match[:ttl_entity][:label] || match[:ttl_entity][:name]) : "Unknown"
|
|
243
|
-
|
|
244
|
-
rows << [
|
|
245
|
-
"UnitsDB: #{entity_id}",
|
|
246
|
-
"(#{entity_name})"
|
|
247
|
-
]
|
|
248
|
-
rows << [
|
|
249
|
-
"SI TTL: #{si_suffix}",
|
|
250
|
-
"(#{ttl_label})"
|
|
251
|
-
]
|
|
252
|
-
rows << :separator unless match == matches.last
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
table = Terminal::Table.new(
|
|
256
|
-
title: "Valid SI References",
|
|
257
|
-
rows: rows
|
|
258
|
-
)
|
|
259
|
-
puts table
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
puts "\n=== #{entity_type.capitalize} that should reference SI ==="
|
|
263
|
-
if missing_refs.empty?
|
|
264
|
-
puts "None"
|
|
265
|
-
else
|
|
266
|
-
# Split missing_refs into exact and potential matches
|
|
267
|
-
exact_matches = []
|
|
268
|
-
potential_matches = []
|
|
269
|
-
|
|
270
|
-
missing_refs.each do |match|
|
|
271
|
-
# Determine match type
|
|
272
|
-
ttl_entities = match[:ttl_entities]
|
|
273
|
-
uri = ttl_entities.first[:uri]
|
|
274
|
-
match_type = "Exact match" # Default
|
|
275
|
-
match_type = match[:match_types][uri] if match[:match_types] && match[:match_types][uri]
|
|
276
|
-
|
|
277
|
-
# Get match description if available
|
|
278
|
-
entity_id = match[:db_entity].short
|
|
279
|
-
match_pair_key = "#{entity_id}:#{ttl_entities.first[:uri]}"
|
|
280
|
-
match_details = Unitsdb::Commands::SiMatcher.instance_variable_get(:@match_details)&.dig(match_pair_key)
|
|
281
|
-
match_desc = match_details[:match_desc] if match_details && match_details[:match_desc]
|
|
282
|
-
|
|
283
|
-
# Symbol matches and partial matches should always be potential matches
|
|
284
|
-
if %w[symbol_match partial_match].include?(match_desc)
|
|
285
|
-
potential_matches << match
|
|
286
|
-
elsif match_type == "Exact match"
|
|
287
|
-
exact_matches << match
|
|
288
|
-
else
|
|
289
|
-
potential_matches << match
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
# Display exact matches
|
|
294
|
-
puts "\n=== Exact Matches (#{exact_matches.size}) ==="
|
|
295
|
-
if exact_matches.empty?
|
|
296
|
-
puts "None"
|
|
297
|
-
else
|
|
298
|
-
rows = []
|
|
299
|
-
exact_matches.each do |match|
|
|
300
|
-
db_entity = match[:db_entity]
|
|
301
|
-
entity_id = match[:entity_id] || db_entity.short
|
|
302
|
-
entity_name = db_entity.respond_to?(:names) ? db_entity.names&.first : "unnamed"
|
|
303
|
-
|
|
304
|
-
# Handle multiple TTL entities in a single row
|
|
305
|
-
ttl_entities = match[:ttl_entities]
|
|
306
|
-
if ttl_entities.size == 1
|
|
307
|
-
# Single TTL entity
|
|
308
|
-
ttl_entity = ttl_entities.first
|
|
309
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(ttl_entity[:uri])
|
|
310
|
-
|
|
311
|
-
rows << [
|
|
312
|
-
"UnitsDB: #{entity_id}",
|
|
313
|
-
"(#{entity_name})"
|
|
314
|
-
]
|
|
315
|
-
rows << [
|
|
316
|
-
"SI TTL: #{si_suffix}",
|
|
317
|
-
"(#{ttl_entity[:label] || ttl_entity[:name] || "unnamed"})"
|
|
318
|
-
]
|
|
319
|
-
else
|
|
320
|
-
# Multiple TTL entities, combine them - ensure no duplicates
|
|
321
|
-
si_text_parts = []
|
|
322
|
-
seen_uris = {}
|
|
323
|
-
|
|
324
|
-
ttl_entities.each do |ttl_entity|
|
|
325
|
-
uri = ttl_entity[:uri]
|
|
326
|
-
next if seen_uris[uri] # Skip if we've already seen this URI
|
|
327
|
-
|
|
328
|
-
seen_uris[uri] = true
|
|
329
|
-
|
|
330
|
-
suffix = SiTtlParser.extract_identifying_suffix(uri)
|
|
331
|
-
si_text_parts << "#{suffix} (#{ttl_entity[:label] || ttl_entity[:name] || "unnamed"})"
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
si_text = si_text_parts.join(", ")
|
|
335
|
-
|
|
336
|
-
rows << [
|
|
337
|
-
"UnitsDB: #{entity_id}",
|
|
338
|
-
"(#{entity_name})"
|
|
339
|
-
]
|
|
340
|
-
rows << [
|
|
341
|
-
"SI TTL: #{si_text}",
|
|
342
|
-
""
|
|
343
|
-
]
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
# Get match details for this match
|
|
347
|
-
match_pair_key = "#{db_entity.short}:#{ttl_entities.first[:uri]}"
|
|
348
|
-
match_details = Unitsdb::Commands::SiMatcher.instance_variable_get(:@match_details)&.dig(match_pair_key)
|
|
349
|
-
|
|
350
|
-
# Format match info
|
|
351
|
-
match_info = ""
|
|
352
|
-
match_info = format_match_info(match_details[:match_desc]) if match_details
|
|
353
|
-
|
|
354
|
-
status_text = match_info.empty? ? "Missing reference" : "Missing reference (#{match_info})"
|
|
355
|
-
rows << [
|
|
356
|
-
"Status: #{status_text}",
|
|
357
|
-
"✗"
|
|
358
|
-
]
|
|
359
|
-
rows << :separator unless match == exact_matches.last
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
table = Terminal::Table.new(
|
|
363
|
-
title: "Exact Match Missing SI References",
|
|
364
|
-
rows: rows
|
|
365
|
-
)
|
|
366
|
-
puts table
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
# Display potential matches
|
|
370
|
-
puts "\n=== Potential Matches (#{potential_matches.size}) ==="
|
|
371
|
-
if potential_matches.empty?
|
|
372
|
-
puts "None"
|
|
373
|
-
else
|
|
374
|
-
rows = []
|
|
375
|
-
potential_matches.each do |match|
|
|
376
|
-
db_entity = match[:db_entity]
|
|
377
|
-
entity_id = match[:entity_id] || db_entity.short
|
|
378
|
-
entity_name = db_entity.respond_to?(:names) ? db_entity.names&.first : "unnamed"
|
|
379
|
-
|
|
380
|
-
# Handle multiple TTL entities in a single row
|
|
381
|
-
ttl_entities = match[:ttl_entities]
|
|
382
|
-
if ttl_entities.size == 1
|
|
383
|
-
# Single TTL entity
|
|
384
|
-
ttl_entity = ttl_entities.first
|
|
385
|
-
si_suffix = SiTtlParser.extract_identifying_suffix(ttl_entity[:uri])
|
|
386
|
-
|
|
387
|
-
rows << [
|
|
388
|
-
"UnitsDB: #{entity_id}",
|
|
389
|
-
"(#{entity_name})"
|
|
390
|
-
]
|
|
391
|
-
rows << [
|
|
392
|
-
"SI TTL: #{si_suffix}",
|
|
393
|
-
"(#{ttl_entity[:label] || ttl_entity[:name] || "unnamed"})"
|
|
394
|
-
]
|
|
395
|
-
else
|
|
396
|
-
# Multiple TTL entities, combine them - ensure no duplicates
|
|
397
|
-
si_text_parts = []
|
|
398
|
-
seen_uris = {}
|
|
399
|
-
|
|
400
|
-
ttl_entities.each do |ttl_entity|
|
|
401
|
-
uri = ttl_entity[:uri]
|
|
402
|
-
next if seen_uris[uri] # Skip if we've already seen this URI
|
|
403
|
-
|
|
404
|
-
seen_uris[uri] = true
|
|
405
|
-
|
|
406
|
-
suffix = SiTtlParser.extract_identifying_suffix(uri)
|
|
407
|
-
si_text_parts << "#{suffix} (#{ttl_entity[:label] || ttl_entity[:name] || "unnamed"})"
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
si_text = si_text_parts.join(", ")
|
|
411
|
-
|
|
412
|
-
rows << [
|
|
413
|
-
"UnitsDB: #{entity_id}",
|
|
414
|
-
"(#{entity_name})"
|
|
415
|
-
]
|
|
416
|
-
rows << [
|
|
417
|
-
"SI TTL: #{si_text}",
|
|
418
|
-
""
|
|
419
|
-
]
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
# Get match details
|
|
423
|
-
match_pair_key = "#{db_entity.short}:#{ttl_entities.first[:uri]}"
|
|
424
|
-
match_details = Unitsdb::Commands::SiMatcher.instance_variable_get(:@match_details)&.dig(match_pair_key)
|
|
425
|
-
|
|
426
|
-
# Format match info
|
|
427
|
-
match_info = ""
|
|
428
|
-
match_info = format_match_info(match_details[:match_desc]) if match_details
|
|
429
|
-
|
|
430
|
-
status_text = match_info.empty? ? "Missing reference" : "Missing reference (#{match_info})"
|
|
431
|
-
rows << [
|
|
432
|
-
"Status: #{status_text}",
|
|
433
|
-
"✗"
|
|
434
|
-
]
|
|
435
|
-
rows << :separator unless match == potential_matches.last
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
table = Terminal::Table.new(
|
|
439
|
-
title: "Potential Match Missing SI References",
|
|
440
|
-
rows: rows
|
|
441
|
-
)
|
|
442
|
-
puts table
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
# Print direction header
|
|
448
|
-
def print_direction_header(direction)
|
|
449
|
-
case direction
|
|
450
|
-
when "SI → UnitsDB"
|
|
451
|
-
puts "\n=== Checking SI → UnitsDB (TTL entities referenced by database) ==="
|
|
452
|
-
when "UnitsDB → SI"
|
|
453
|
-
puts "\n=== Checking UnitsDB → SI (database entities referencing TTL) ==="
|
|
454
|
-
end
|
|
455
|
-
|
|
456
|
-
puts "\n=== Instructions for #{direction} direction ==="
|
|
457
|
-
case direction
|
|
458
|
-
when "SI → UnitsDB"
|
|
459
|
-
puts "If you are the UnitsDB Register Manager, please ensure that all SI entities have proper references in the UnitsDB database."
|
|
460
|
-
puts "For each missing reference, add a reference with the appropriate URI and 'authority: \"si-digital-framework\"'."
|
|
461
|
-
when "UnitsDB → SI"
|
|
462
|
-
puts "If you are the UnitsDB Register Manager, please add SI references to UnitsDB entities that should have them."
|
|
463
|
-
puts "For each entity that should reference SI, add a reference with 'authority: \"si-digital-framework\"' and the SI TTL URI."
|
|
464
|
-
end
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
def set_match_details(details)
|
|
468
|
-
@match_details = details
|
|
469
|
-
end
|
|
470
|
-
|
|
471
|
-
# Format match info for display
|
|
472
|
-
def format_match_info(match_desc)
|
|
473
|
-
{
|
|
474
|
-
"short_to_name" => "short → name",
|
|
475
|
-
"short_to_label" => "short → label",
|
|
476
|
-
"name_to_name" => "name → name",
|
|
477
|
-
"name_to_label" => "name → label",
|
|
478
|
-
"name_to_alt_label" => "name → alt_label",
|
|
479
|
-
"symbol_match" => "symbol → symbol",
|
|
480
|
-
"partial_match" => "partial match"
|
|
481
|
-
}[match_desc] || ""
|
|
482
|
-
end
|
|
483
|
-
end
|
|
484
|
-
end
|
|
485
|
-
end
|