unitsdb 2.1.1 → 2.2.2
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/config.rb +114 -2
- data/lib/unitsdb/database.rb +160 -123
- data/lib/unitsdb/dimension.rb +3 -4
- data/lib/unitsdb/dimension_details.rb +2 -1
- data/lib/unitsdb/dimension_reference.rb +2 -0
- data/lib/unitsdb/dimensions.rb +2 -2
- data/lib/unitsdb/errors.rb +7 -0
- data/lib/unitsdb/external_reference.rb +2 -0
- data/lib/unitsdb/identifier.rb +2 -0
- data/lib/unitsdb/localized_string.rb +2 -0
- data/lib/unitsdb/prefix.rb +2 -4
- data/lib/unitsdb/prefix_reference.rb +2 -2
- data/lib/unitsdb/prefixes.rb +2 -1
- data/lib/unitsdb/quantities.rb +2 -2
- data/lib/unitsdb/quantity.rb +2 -6
- data/lib/unitsdb/quantity_reference.rb +2 -0
- data/lib/unitsdb/qudt.rb +105 -0
- data/lib/unitsdb/root_unit_reference.rb +2 -3
- data/lib/unitsdb/scale.rb +2 -4
- data/lib/unitsdb/scale_properties.rb +2 -0
- data/lib/unitsdb/scale_reference.rb +2 -2
- data/lib/unitsdb/scales.rb +2 -2
- data/lib/unitsdb/si_derived_base.rb +2 -2
- data/lib/unitsdb/symbol_presentations.rb +2 -0
- data/lib/unitsdb/ucum.rb +21 -10
- data/lib/unitsdb/unit.rb +2 -10
- data/lib/unitsdb/unit_reference.rb +2 -2
- data/lib/unitsdb/unit_system.rb +3 -3
- data/lib/unitsdb/unit_system_reference.rb +2 -2
- data/lib/unitsdb/unit_systems.rb +2 -2
- data/lib/unitsdb/units.rb +2 -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
metadata
CHANGED
|
@@ -1,29 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unitsdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-04-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: fuzzy_match
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: lutaml-model
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
16
30
|
requirements:
|
|
17
31
|
- - "~>"
|
|
18
32
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
33
|
+
version: 0.8.0
|
|
20
34
|
type: :runtime
|
|
21
35
|
prerelease: false
|
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
37
|
requirements:
|
|
24
38
|
- - "~>"
|
|
25
39
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
40
|
+
version: 0.8.0
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: rdf
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -67,19 +81,19 @@ dependencies:
|
|
|
67
81
|
- !ruby/object:Gem::Version
|
|
68
82
|
version: '2.3'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
84
|
+
name: table_tennis
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
72
86
|
requirements:
|
|
73
|
-
- - "
|
|
87
|
+
- - "~>"
|
|
74
88
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
89
|
+
version: 0.0.7
|
|
76
90
|
type: :runtime
|
|
77
91
|
prerelease: false
|
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
93
|
requirements:
|
|
80
|
-
- - "
|
|
94
|
+
- - "~>"
|
|
81
95
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
96
|
+
version: 0.0.7
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: thor
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -111,6 +125,7 @@ files:
|
|
|
111
125
|
- ".rspec"
|
|
112
126
|
- ".rubocop.yml"
|
|
113
127
|
- ".rubocop_todo.yml"
|
|
128
|
+
- CLAUDE.md
|
|
114
129
|
- CODE_OF_CONDUCT.md
|
|
115
130
|
- Gemfile
|
|
116
131
|
- LICENSE.txt
|
|
@@ -118,20 +133,40 @@ files:
|
|
|
118
133
|
- Rakefile
|
|
119
134
|
- bin/console
|
|
120
135
|
- bin/setup
|
|
136
|
+
- data/dimensions.yaml
|
|
137
|
+
- data/prefixes.yaml
|
|
138
|
+
- data/quantities.yaml
|
|
139
|
+
- data/scales.yaml
|
|
140
|
+
- data/schemas/dimensions-schema.yaml
|
|
141
|
+
- data/schemas/prefixes-schema.yaml
|
|
142
|
+
- data/schemas/quantities-schema.yaml
|
|
143
|
+
- data/schemas/scales-schema.yaml
|
|
144
|
+
- data/schemas/unit_systems-schema.yaml
|
|
145
|
+
- data/schemas/units-schema.yaml
|
|
146
|
+
- data/unit_systems.yaml
|
|
147
|
+
- data/units.yaml
|
|
121
148
|
- exe/unitsdb
|
|
122
149
|
- lib/unitsdb.rb
|
|
123
150
|
- lib/unitsdb/cli.rb
|
|
151
|
+
- lib/unitsdb/commands.rb
|
|
124
152
|
- lib/unitsdb/commands/_modify.rb
|
|
125
153
|
- lib/unitsdb/commands/base.rb
|
|
126
154
|
- lib/unitsdb/commands/check_si.rb
|
|
155
|
+
- lib/unitsdb/commands/check_si/si_formatter.rb
|
|
156
|
+
- lib/unitsdb/commands/check_si/si_matcher.rb
|
|
157
|
+
- lib/unitsdb/commands/check_si/si_ttl_parser.rb
|
|
158
|
+
- lib/unitsdb/commands/check_si/si_updater.rb
|
|
127
159
|
- lib/unitsdb/commands/get.rb
|
|
128
160
|
- lib/unitsdb/commands/normalize.rb
|
|
161
|
+
- lib/unitsdb/commands/qudt.rb
|
|
162
|
+
- lib/unitsdb/commands/qudt/check.rb
|
|
163
|
+
- lib/unitsdb/commands/qudt/formatter.rb
|
|
164
|
+
- lib/unitsdb/commands/qudt/matcher.rb
|
|
165
|
+
- lib/unitsdb/commands/qudt/ttl_parser.rb
|
|
166
|
+
- lib/unitsdb/commands/qudt/update.rb
|
|
167
|
+
- lib/unitsdb/commands/qudt/updater.rb
|
|
129
168
|
- lib/unitsdb/commands/release.rb
|
|
130
169
|
- lib/unitsdb/commands/search.rb
|
|
131
|
-
- lib/unitsdb/commands/si_formatter.rb
|
|
132
|
-
- lib/unitsdb/commands/si_matcher.rb
|
|
133
|
-
- lib/unitsdb/commands/si_ttl_parser.rb
|
|
134
|
-
- lib/unitsdb/commands/si_updater.rb
|
|
135
170
|
- lib/unitsdb/commands/ucum.rb
|
|
136
171
|
- lib/unitsdb/commands/ucum/check.rb
|
|
137
172
|
- lib/unitsdb/commands/ucum/formatter.rb
|
|
@@ -141,8 +176,10 @@ files:
|
|
|
141
176
|
- lib/unitsdb/commands/ucum/xml_parser.rb
|
|
142
177
|
- lib/unitsdb/commands/validate.rb
|
|
143
178
|
- lib/unitsdb/commands/validate/identifiers.rb
|
|
179
|
+
- lib/unitsdb/commands/validate/qudt_references.rb
|
|
144
180
|
- lib/unitsdb/commands/validate/references.rb
|
|
145
181
|
- lib/unitsdb/commands/validate/si_references.rb
|
|
182
|
+
- lib/unitsdb/commands/validate/ucum_references.rb
|
|
146
183
|
- lib/unitsdb/config.rb
|
|
147
184
|
- lib/unitsdb/database.rb
|
|
148
185
|
- lib/unitsdb/dimension.rb
|
|
@@ -159,6 +196,7 @@ files:
|
|
|
159
196
|
- lib/unitsdb/quantities.rb
|
|
160
197
|
- lib/unitsdb/quantity.rb
|
|
161
198
|
- lib/unitsdb/quantity_reference.rb
|
|
199
|
+
- lib/unitsdb/qudt.rb
|
|
162
200
|
- lib/unitsdb/root_unit_reference.rb
|
|
163
201
|
- lib/unitsdb/scale.rb
|
|
164
202
|
- lib/unitsdb/scale_properties.rb
|
|
@@ -184,6 +222,7 @@ metadata:
|
|
|
184
222
|
homepage_uri: https://github.com/unitsml/unitsdb-ruby
|
|
185
223
|
source_code_uri: https://github.com/unitsml/unitsdb-ruby
|
|
186
224
|
changelog_uri: https://github.com/unitsml/unitsdb-ruby/releases
|
|
225
|
+
rubygems_mfa_required: 'true'
|
|
187
226
|
post_install_message:
|
|
188
227
|
rdoc_options: []
|
|
189
228
|
require_paths:
|
|
@@ -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
|