unitsdb 2.2.1 → 2.2.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/opal.yml +36 -0
  3. data/.gitignore +3 -0
  4. data/Gemfile +1 -0
  5. data/Rakefile +3 -1
  6. data/lib/unitsdb/cli.rb +5 -41
  7. data/lib/unitsdb/commands/_modify.rb +1 -34
  8. data/lib/unitsdb/commands/check_si/si_formatter.rb +6 -6
  9. data/lib/unitsdb/commands/check_si/si_matcher.rb +202 -292
  10. data/lib/unitsdb/commands/check_si/si_updater.rb +16 -36
  11. data/lib/unitsdb/commands/entity_presenter.rb +98 -0
  12. data/lib/unitsdb/commands/get.rb +16 -113
  13. data/lib/unitsdb/commands/qudt/formatter.rb +16 -27
  14. data/lib/unitsdb/commands/qudt/matcher.rb +18 -28
  15. data/lib/unitsdb/commands/qudt/updater.rb +8 -11
  16. data/lib/unitsdb/commands/qudt.rb +1 -34
  17. data/lib/unitsdb/commands/search.rb +33 -188
  18. data/lib/unitsdb/commands/thor.rb +41 -0
  19. data/lib/unitsdb/commands/ucum/formatter.rb +9 -18
  20. data/lib/unitsdb/commands/ucum/matcher.rb +4 -4
  21. data/lib/unitsdb/commands/ucum/updater.rb +3 -5
  22. data/lib/unitsdb/commands/ucum.rb +1 -34
  23. data/lib/unitsdb/commands/validate/qudt_references.rb +29 -70
  24. data/lib/unitsdb/commands/validate/references.rb +5 -303
  25. data/lib/unitsdb/commands/validate/si_references.rb +30 -66
  26. data/lib/unitsdb/commands/validate/ucum_references.rb +30 -64
  27. data/lib/unitsdb/commands/validate.rb +1 -36
  28. data/lib/unitsdb/commands.rb +2 -0
  29. data/lib/unitsdb/config.rb +170 -4
  30. data/lib/unitsdb/database/loader.rb +135 -0
  31. data/lib/unitsdb/database/reference_validator.rb +227 -0
  32. data/lib/unitsdb/database/uniqueness_validator.rb +80 -0
  33. data/lib/unitsdb/database.rb +127 -588
  34. data/lib/unitsdb/dimension.rb +2 -27
  35. data/lib/unitsdb/dimension_details.rb +2 -0
  36. data/lib/unitsdb/dimension_reference.rb +2 -0
  37. data/lib/unitsdb/dimensions.rb +2 -2
  38. data/lib/unitsdb/external_reference.rb +2 -0
  39. data/lib/unitsdb/identifier.rb +2 -0
  40. data/lib/unitsdb/localized_string.rb +2 -0
  41. data/lib/unitsdb/opal.rb +43 -0
  42. data/lib/unitsdb/prefix.rb +2 -13
  43. data/lib/unitsdb/prefix_reference.rb +2 -0
  44. data/lib/unitsdb/prefixes.rb +2 -2
  45. data/lib/unitsdb/quantities.rb +2 -1
  46. data/lib/unitsdb/quantity.rb +2 -2
  47. data/lib/unitsdb/quantity_reference.rb +2 -2
  48. data/lib/unitsdb/qudt.rb +5 -0
  49. data/lib/unitsdb/root_unit_reference.rb +2 -2
  50. data/lib/unitsdb/scale.rb +2 -2
  51. data/lib/unitsdb/scale_properties.rb +2 -1
  52. data/lib/unitsdb/scale_reference.rb +2 -0
  53. data/lib/unitsdb/scales.rb +2 -1
  54. data/lib/unitsdb/si_derived_base.rb +2 -1
  55. data/lib/unitsdb/symbol_presentations.rb +2 -2
  56. data/lib/unitsdb/ucum.rb +7 -0
  57. data/lib/unitsdb/unit.rb +2 -34
  58. data/lib/unitsdb/unit_reference.rb +2 -0
  59. data/lib/unitsdb/unit_system.rb +2 -2
  60. data/lib/unitsdb/unit_system_reference.rb +2 -0
  61. data/lib/unitsdb/unit_systems.rb +2 -2
  62. data/lib/unitsdb/units.rb +2 -2
  63. data/lib/unitsdb/version.rb +1 -1
  64. data/lib/unitsdb.rb +134 -27
  65. data/unitsdb.gemspec +1 -0
  66. metadata +23 -2
data/lib/unitsdb.rb CHANGED
@@ -3,51 +3,122 @@
3
3
  require "lutaml/model"
4
4
 
5
5
  module Unitsdb
6
- autoload :Cli, "unitsdb/cli"
6
+ # All model constants are autoloaded from their respective files.
7
+ # Config.build_registry triggers `eager_load_models!` so the type
8
+ # registry is complete before iteration — otherwise autoload would
9
+ # leave unreferenced models (Scale, Qudt*, Ucum*) unregistered.
10
+
7
11
  autoload :Config, "unitsdb/config"
8
- autoload :Commands, "unitsdb/commands"
9
- autoload :Database, "unitsdb/database"
10
- autoload :Dimension, "unitsdb/dimension"
11
- autoload :DimensionDetails, "unitsdb/dimension_details"
12
- autoload :DimensionReference, "unitsdb/dimension_reference"
13
- autoload :Dimensions, "unitsdb/dimensions"
14
12
  autoload :Errors, "unitsdb/errors"
15
- autoload :ExternalReference, "unitsdb/external_reference"
13
+ autoload :Utils, "unitsdb/utils"
14
+ autoload :Database, "unitsdb/database"
15
+
16
+ # Leaf models
16
17
  autoload :Identifier, "unitsdb/identifier"
17
18
  autoload :LocalizedString, "unitsdb/localized_string"
18
- autoload :Prefix, "unitsdb/prefix"
19
+ autoload :SymbolPresentations, "unitsdb/symbol_presentations"
20
+ autoload :ScaleProperties, "unitsdb/scale_properties"
21
+
22
+ # Reference models
23
+ autoload :UnitReference, "unitsdb/unit_reference"
19
24
  autoload :PrefixReference, "unitsdb/prefix_reference"
25
+ autoload :QuantityReference, "unitsdb/quantity_reference"
26
+ autoload :DimensionReference, "unitsdb/dimension_reference"
27
+ autoload :UnitSystemReference, "unitsdb/unit_system_reference"
28
+ autoload :ScaleReference, "unitsdb/scale_reference"
29
+ autoload :ExternalReference, "unitsdb/external_reference"
30
+ autoload :RootUnitReference, "unitsdb/root_unit_reference"
31
+ autoload :SiDerivedBase, "unitsdb/si_derived_base"
32
+ autoload :DimensionDetails, "unitsdb/dimension_details"
33
+
34
+ # Entity models
35
+ autoload :Dimension, "unitsdb/dimension"
36
+ autoload :Prefix, "unitsdb/prefix"
37
+ autoload :UnitSystem, "unitsdb/unit_system"
38
+ autoload :Quantity, "unitsdb/quantity"
39
+ autoload :Scale, "unitsdb/scale"
40
+ autoload :Unit, "unitsdb/unit"
41
+
42
+ # Collection container models
43
+ autoload :Dimensions, "unitsdb/dimensions"
20
44
  autoload :Prefixes, "unitsdb/prefixes"
21
45
  autoload :Quantities, "unitsdb/quantities"
22
- autoload :Quantity, "unitsdb/quantity"
23
- autoload :QuantityReference, "unitsdb/quantity_reference"
46
+ autoload :Scales, "unitsdb/scales"
47
+ autoload :UnitSystems, "unitsdb/unit_systems"
48
+ autoload :Units, "unitsdb/units"
49
+
50
+ # QUDT vocabulary models — all defined in unitsdb/qudt.rb
24
51
  autoload :QudtUnit, "unitsdb/qudt"
25
52
  autoload :QudtQuantityKind, "unitsdb/qudt"
26
53
  autoload :QudtDimensionVector, "unitsdb/qudt"
27
54
  autoload :QudtSystemOfUnits, "unitsdb/qudt"
28
55
  autoload :QudtPrefix, "unitsdb/qudt"
29
56
  autoload :QudtVocabularies, "unitsdb/qudt"
30
- autoload :RootUnitReference, "unitsdb/root_unit_reference"
31
- autoload :Scale, "unitsdb/scale"
32
- autoload :ScaleProperties, "unitsdb/scale_properties"
33
- autoload :ScaleReference, "unitsdb/scale_reference"
34
- autoload :Scales, "unitsdb/scales"
35
- autoload :SiDerivedBase, "unitsdb/si_derived_base"
36
- autoload :SymbolPresentations, "unitsdb/symbol_presentations"
57
+
58
+ # UCUM XML models — all defined in unitsdb/ucum.rb
37
59
  autoload :UcumBaseUnit, "unitsdb/ucum"
38
60
  autoload :UcumPrefixValue, "unitsdb/ucum"
39
61
  autoload :UcumPrefix, "unitsdb/ucum"
40
62
  autoload :UcumUnitValueFunction, "unitsdb/ucum"
41
63
  autoload :UcumUnitValue, "unitsdb/ucum"
42
64
  autoload :UcumUnit, "unitsdb/ucum"
65
+ autoload :UcumNamespace, "unitsdb/ucum"
43
66
  autoload :UcumFile, "unitsdb/ucum"
44
- autoload :Unit, "unitsdb/unit"
45
- autoload :UnitReference, "unitsdb/unit_reference"
46
- autoload :UnitSystem, "unitsdb/unit_system"
47
- autoload :UnitSystemReference, "unitsdb/unit_system_reference"
48
- autoload :UnitSystems, "unitsdb/unit_systems"
49
- autoload :Units, "unitsdb/units"
50
- autoload :Utils, "unitsdb/utils"
67
+
68
+ # CLI and Commands pull in Thor, which doesn't run under Opal.
69
+ unless RUBY_ENGINE == "opal"
70
+ autoload :Cli, "unitsdb/cli"
71
+ autoload :Commands, "unitsdb/commands"
72
+ end
73
+
74
+ # Constants eagerly loaded so Lutaml::Model type registrations are
75
+ # complete before Config.build_registry iterates them. Listed
76
+ # explicitly so unreferenced models (Scale, Qudt*, Ucum*) still
77
+ # register themselves via their file-bottom `Config.register_model`
78
+ # calls.
79
+ MODELS = %i[
80
+ Identifier
81
+ LocalizedString
82
+ SymbolPresentations
83
+ ScaleProperties
84
+ UnitReference
85
+ PrefixReference
86
+ QuantityReference
87
+ DimensionReference
88
+ UnitSystemReference
89
+ ScaleReference
90
+ ExternalReference
91
+ RootUnitReference
92
+ SiDerivedBase
93
+ DimensionDetails
94
+ Dimension
95
+ Prefix
96
+ UnitSystem
97
+ Quantity
98
+ Scale
99
+ Unit
100
+ Dimensions
101
+ Prefixes
102
+ Quantities
103
+ Scales
104
+ UnitSystems
105
+ Units
106
+ Database
107
+ QudtUnit
108
+ QudtQuantityKind
109
+ QudtDimensionVector
110
+ QudtSystemOfUnits
111
+ QudtPrefix
112
+ QudtVocabularies
113
+ UcumBaseUnit
114
+ UcumPrefixValue
115
+ UcumPrefix
116
+ UcumUnitValueFunction
117
+ UcumUnitValue
118
+ UcumUnit
119
+ UcumNamespace
120
+ UcumFile
121
+ ].freeze
51
122
 
52
123
  class << self
53
124
  # Returns the path to the bundled data directory containing YAML files
@@ -56,12 +127,48 @@ module Unitsdb
56
127
  end
57
128
 
58
129
  # Returns a pre-loaded Database instance from the bundled data
59
- def database
60
- @database ||= Database.from_db(data_dir)
130
+ def database(context: Config.context_id)
131
+ context_id = context.to_sym
132
+ Config.ensure_default_context! if context_id == Config.context_id
133
+ klass = Config.resolve_type(:database, context: context_id)
134
+ databases[context_id] ||= klass.from_db(data_dir, context: context_id)
135
+ end
136
+
137
+ # Drop the memoized Database instances so the next `database` call
138
+ # reloads from disk. Specs use this between examples.
139
+ def reset_database_cache!
140
+ @databases = nil
141
+ end
142
+
143
+ # Force every autoloaded model to load AND register itself with
144
+ # Config. The per-file `Config.register_model(Class, id: :foo)`
145
+ # calls at file-bottom run the first time a model loads, but
146
+ # `Config.capture_state` / `restore_state` can wipe those entries
147
+ # between tests. Re-registering here makes the registry
148
+ # self-healing across snapshot/restore cycles.
149
+ def eager_load_models!
150
+ MODELS.each do |sym|
151
+ klass = const_get(sym)
152
+ next unless klass.is_a?(Class) && klass < ::Lutaml::Model::Serializable
153
+
154
+ Config.register_model(klass, id: model_id_for(klass))
155
+ end
61
156
  end
62
157
 
63
158
  private
64
159
 
160
+ def model_id_for(klass)
161
+ klass.name.split("::").last
162
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
163
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
164
+ .downcase
165
+ .to_sym
166
+ end
167
+
168
+ def databases
169
+ @databases ||= {}
170
+ end
171
+
65
172
  def gem_dir
66
173
  @gem_dir ||= File.dirname(__dir__)
67
174
  end
data/unitsdb.gemspec CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.require_paths = ["lib"]
35
35
 
36
36
  spec.add_dependency "fuzzy_match"
37
+ spec.add_dependency "logger"
37
38
  spec.add_dependency "lutaml-model", "~> 0.8.0"
38
39
  spec.add_dependency "rdf", "~> 3.1"
39
40
  spec.add_dependency "rdf-turtle", "~> 3.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unitsdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-03 00:00:00.000000000 Z
11
+ date: 2026-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fuzzy_match
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: lutaml-model
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +132,7 @@ extra_rdoc_files: []
118
132
  files:
119
133
  - ".github/workflows/dependent-repos.json"
120
134
  - ".github/workflows/depenedent-gems.yml"
135
+ - ".github/workflows/opal.yml"
121
136
  - ".github/workflows/rake.yml"
122
137
  - ".github/workflows/release.yml"
123
138
  - ".gitignore"
@@ -156,6 +171,7 @@ files:
156
171
  - lib/unitsdb/commands/check_si/si_matcher.rb
157
172
  - lib/unitsdb/commands/check_si/si_ttl_parser.rb
158
173
  - lib/unitsdb/commands/check_si/si_updater.rb
174
+ - lib/unitsdb/commands/entity_presenter.rb
159
175
  - lib/unitsdb/commands/get.rb
160
176
  - lib/unitsdb/commands/normalize.rb
161
177
  - lib/unitsdb/commands/qudt.rb
@@ -167,6 +183,7 @@ files:
167
183
  - lib/unitsdb/commands/qudt/updater.rb
168
184
  - lib/unitsdb/commands/release.rb
169
185
  - lib/unitsdb/commands/search.rb
186
+ - lib/unitsdb/commands/thor.rb
170
187
  - lib/unitsdb/commands/ucum.rb
171
188
  - lib/unitsdb/commands/ucum/check.rb
172
189
  - lib/unitsdb/commands/ucum/formatter.rb
@@ -182,6 +199,9 @@ files:
182
199
  - lib/unitsdb/commands/validate/ucum_references.rb
183
200
  - lib/unitsdb/config.rb
184
201
  - lib/unitsdb/database.rb
202
+ - lib/unitsdb/database/loader.rb
203
+ - lib/unitsdb/database/reference_validator.rb
204
+ - lib/unitsdb/database/uniqueness_validator.rb
185
205
  - lib/unitsdb/dimension.rb
186
206
  - lib/unitsdb/dimension_details.rb
187
207
  - lib/unitsdb/dimension_reference.rb
@@ -190,6 +210,7 @@ files:
190
210
  - lib/unitsdb/external_reference.rb
191
211
  - lib/unitsdb/identifier.rb
192
212
  - lib/unitsdb/localized_string.rb
213
+ - lib/unitsdb/opal.rb
193
214
  - lib/unitsdb/prefix.rb
194
215
  - lib/unitsdb/prefix_reference.rb
195
216
  - lib/unitsdb/prefixes.rb