Class: Unitsdb::Database
- Inherits:
-
Lutaml::Model::Serializable
- Object
- Lutaml::Model::Serializable
- Unitsdb::Database
- Defined in:
- lib/unitsdb/database.rb,
lib/unitsdb/database/loader.rb,
lib/unitsdb/database/reference_validator.rb,
lib/unitsdb/database/uniqueness_validator.rb
Defined Under Namespace
Modules: LookupStrategies, Reference Classes: IdRegistry, Loader, ReferenceChecker, ReferencePair, ReferenceValidator, UniquenessValidator
Constant Summary collapse
- COLLECTIONS =
Loader::DATABASE_FILES.keys.map(&:to_sym).freeze
- SYMBOL_COLLECTIONS =
Collections whose entities carry a
symbolsattribute. Used by symbol-based search/match to narrow iteration. i[units prefixes].freeze
- DATABASE_FILES =
Backwards-compat aliases — external callers (and the spec) read these constants off Database directly.
Loader::DATABASE_FILES
- SUPPORTED_SCHEMA_VERSION =
Loader::SUPPORTED_SCHEMA_VERSION
Class Method Summary collapse
-
.empty_for_results(entities) ⇒ Object
Build an empty Database with
entitiespartitioned into their typed collections. -
.from_db(dir_path, context: Unitsdb::Config.context_id) ⇒ Object
Load every YAML file under
dir_pathand deserialize into a Database instance scoped tocontext.
Instance Method Summary collapse
-
#collection(name) ⇒ Object
Resolve a collection name (String or Symbol) to its typed Array.
-
#find_by_symbol(symbol, entity_type = nil) ⇒ Array
Find entities by symbol.
-
#find_by_type(id:, type:) ⇒ Object?
Find an entity by its specific identifier and type.
-
#get_by_id(id:, type: nil) ⇒ Object?
Find an entity by its identifier id across all entity types.
-
#match_entities(params = {}) ⇒ Hash
Match entities by name, short, or symbol with different match types.
-
#search(params = {}) ⇒ Array
Search for entities containing the given text in identifiers, names, or short description.
-
#validate_references ⇒ Object
Validates references between entities.
-
#validate_uniqueness ⇒ Object
Checks for uniqueness of identifiers and short names.
Class Method Details
.empty_for_results(entities) ⇒ Object
Build an empty Database with entities partitioned into their
typed collections. Used by CLI commands that need to serialize
a subset of search results.
38 39 40 41 42 43 44 45 |
# File 'lib/unitsdb/database.rb', line 38 def self.empty_for_results(entities) Database.new.tap do |db| COLLECTIONS.each do |name| klass = collection_element_class(name) db.public_send("#{name}=", entities.grep(klass)) end end end |
.from_db(dir_path, context: Unitsdb::Config.context_id) ⇒ Object
Load every YAML file under dir_path and deserialize into a
Database instance scoped to context. The default context is
auto-created via Config.ensure_default_context!; custom
contexts must be created by the caller first.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/unitsdb/database.rb', line 221 def from_db(dir_path, context: Unitsdb::Config.context_id) context_id = context.to_sym Unitsdb::Config.ensure_default_context! if context_id == Unitsdb::Config.context_id combined_hash = Loader.load(dir_path) Lutaml::Model::GlobalContext.with_context(context_id) do if Unitsdb::Config.register_id_for(context_id) from_hash(combined_hash, register: context_id) else from_hash(combined_hash) end end end |
Instance Method Details
#collection(name) ⇒ Object
Resolve a collection name (String or Symbol) to its typed Array.
Validates against COLLECTIONS so caller-supplied names can never
dispatch to arbitrary methods (e.g. schema_version, to_yaml).
26 27 28 29 30 31 32 33 |
# File 'lib/unitsdb/database.rb', line 26 def collection(name) sym = name.to_sym unless COLLECTIONS.include?(sym) raise ArgumentError, "unknown collection: #{name.inspect}" end public_send(sym) end |
#find_by_symbol(symbol, entity_type = nil) ⇒ Array
Find entities by symbol
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/unitsdb/database.rb', line 108 def find_by_symbol(symbol, entity_type = nil) return [] unless symbol needle = symbol.downcase scope = scope_for(entity_type, SYMBOL_COLLECTIONS) scope.each_with_object([]) do |name, results| collection(name).each do |entity| results << entity if entity.symbols.any? do |sym| sym.ascii.to_s.downcase == needle end end end end |
#find_by_type(id:, type:) ⇒ Object?
Find an entity by its specific identifier and type
61 62 63 64 65 |
# File 'lib/unitsdb/database.rb', line 61 def find_by_type(id:, type:) collection(type).find do |entity| entity.identifiers.any? { |identifier| identifier.id == id } end end |
#get_by_id(id:, type: nil) ⇒ Object?
Find an entity by its identifier id across all entity types
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/unitsdb/database.rb', line 71 def get_by_id(id:, type: nil) COLLECTIONS.each do |name| entity = collection(name).find do |e| e.identifiers.any? do |identifier| identifier.id == id && (type.nil? || identifier.type == type) end end return entity if entity end nil end |
#match_entities(params = {}) ⇒ Hash
Match entities by name, short, or symbol with different match types
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/unitsdb/database.rb', line 129 def match_entities(params = {}) value = params[:value] return {} unless value match_type = params[:match_type]&.to_s || "exact" result = { exact: [], symbol_match: [] } scope_for(params[:entity_type], COLLECTIONS).each do |name| collection(name).each do |entity| if %w[exact all].include?(match_type) match_exact(entity, value, result) end next unless %w[symbol all].include?(match_type) && SYMBOL_COLLECTIONS.include?(name) match_symbol(entity, value, result) end end result.delete_if { |_, v| v.empty? } result end |
#search(params = {}) ⇒ Array
Search for entities containing the given text in identifiers, names, or short description.
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/unitsdb/database.rb', line 90 def search(params = {}) text = params[:text] return [] unless text needle = text.downcase scope = scope_for(params[:type], COLLECTIONS) scope.each_with_object([]) do |name, results| collection(name).each do |entity| results << entity if matches_text?(entity, needle) end end end |
#validate_references ⇒ Object
Validates references between entities. Delegates to ReferenceValidator.
158 159 160 |
# File 'lib/unitsdb/database.rb', line 158 def validate_references ReferenceValidator.validate(self) end |
#validate_uniqueness ⇒ Object
Checks for uniqueness of identifiers and short names. Delegates to UniquenessValidator.
153 154 155 |
# File 'lib/unitsdb/database.rb', line 153 def validate_uniqueness UniquenessValidator.validate(self) end |