Class: Expressir::Model::Repository
- Inherits:
-
ModelElement
- Object
- Lutaml::Model::Serializable
- ModelElement
- Expressir::Model::Repository
- Defined in:
- lib/expressir/model/repository.rb
Overview
Multi-schema global scope with enhanced repository features Focuses on schema management and delegates indexing/validation to specialized classes
A Repository contains multiple ExpFile instances (one per parsed .exp file).
Structure:
Repository
└── files: [ExpFile, ...]
└── ExpFile (path: "a.exp")
├── untagged_remarks: [...] # file-level preamble
└── schemas: [SchemaA]
Constant Summary
Constants inherited from ModelElement
ModelElement::POLYMORPHIC_CLASS_MAP, ModelElement::SKIP_ATTRIBUTES
Instance Attribute Summary collapse
-
#_schemas ⇒ Object
readonly
Internal schema storage for direct manipulation.
-
#base_dir ⇒ Object
Base directory for schema files.
-
#entity_index ⇒ Object
readonly
Index instances (lazy-loaded).
-
#reference_index ⇒ Object
readonly
Index instances (lazy-loaded).
-
#type_index ⇒ Object
readonly
Index instances (lazy-loaded).
Attributes inherited from ModelElement
Class Method Summary collapse
-
.from_files(file_paths, base_dir: nil) ⇒ Repository
Build repository from list of schema files.
-
.from_package(package_path) ⇒ Repository
Load repository from LER package.
Instance Method Summary collapse
-
#add_schema(schema) ⇒ Object
Add a schema to the repository.
-
#all_schemas ⇒ Array<Declarations::Schema>
Alias for schemas.
-
#build_indexes ⇒ void
Build indexes for entities, types, and references.
- #children ⇒ Array<Declarations::Schema>
-
#dependency_statistics ⇒ Hash
Get dependency statistics.
-
#export_to_package(output_path, options = {}) ⇒ String
Export repository to LER package.
-
#find_entity(qualified_name:) ⇒ Declarations::Entity?
Find entity by qualified name.
-
#find_type(qualified_name:) ⇒ Declarations::Type?
Find type by qualified name.
-
#initialize(base_dir: nil, schemas: nil) ⇒ Repository
constructor
A new instance of Repository.
-
#largest_schemas(limit = 10) ⇒ Array<Hash>
Get largest schemas by total element count.
-
#list_entities(schema: nil, format: :object) ⇒ Array
List all entities.
-
#list_types(schema: nil, category: nil, format: :object) ⇒ Array
List all types.
-
#resolve_all_references ⇒ void
Resolve all references across schemas Uses the existing ResolveReferencesModelVisitor.
-
#restore_indexes(entity_index: nil, type_index: nil, reference_index: nil) ⇒ Object
Restore deserialized indexes (used by Package::Reader).
-
#schema_complexity(schema) ⇒ Integer
Calculate schema complexity score Entities=2, Types=1, Functions=3, Procedures=3, Rules=4, Interfaces=2.
-
#schemas ⇒ Array<Declarations::Schema>
Get all schemas (from both files and direct storage).
-
#schemas_by_category ⇒ Hash
Group schemas by category based on their contents.
-
#schemas_by_complexity(limit = 10) ⇒ Array<Hash>
Get schemas sorted by complexity.
-
#statistics(format: :hash) ⇒ Hash, String
Get statistics.
-
#to_manifest ⇒ SchemaManifest
Generate SchemaManifest from repository.
-
#validate(strict: false) ⇒ Hash
Validate repository consistency.
Methods inherited from ModelElement
#add_remark, #children_by_id, #find, #path, #reset_children_by_id, #source, #to_s
Constructor Details
#initialize(base_dir: nil, schemas: nil) ⇒ Repository
Returns a new instance of Repository.
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/expressir/model/repository.rb', line 47 def initialize(*, base_dir: nil, schemas: nil, **) super(*, **) @base_dir = base_dir @entity_index = nil @type_index = nil @reference_index = nil @_schemas = [] # Support direct schemas initialization schemas&.each { |schema| @_schemas << schema } end |
Instance Attribute Details
#_schemas ⇒ Object (readonly)
Internal schema storage for direct manipulation
36 37 38 |
# File 'lib/expressir/model/repository.rb', line 36 def _schemas @_schemas end |
#base_dir ⇒ Object
Base directory for schema files
22 23 24 |
# File 'lib/expressir/model/repository.rb', line 22 def base_dir @base_dir end |
#entity_index ⇒ Object (readonly)
Index instances (lazy-loaded)
25 26 27 |
# File 'lib/expressir/model/repository.rb', line 25 def entity_index @entity_index end |
#reference_index ⇒ Object (readonly)
Index instances (lazy-loaded)
25 26 27 |
# File 'lib/expressir/model/repository.rb', line 25 def reference_index @reference_index end |
#type_index ⇒ Object (readonly)
Index instances (lazy-loaded)
25 26 27 |
# File 'lib/expressir/model/repository.rb', line 25 def type_index @type_index end |
Class Method Details
.from_files(file_paths, base_dir: nil) ⇒ Repository
Build repository from list of schema files
295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/expressir/model/repository.rb', line 295 def self.from_files(file_paths, base_dir: nil) repo = new(base_dir: base_dir) file_paths.each do |path| parsed = Expressir::Express::Parser.from_file(path) next unless parsed repo.files << parsed if parsed.is_a?(ExpFile) end repo.resolve_all_references repo end |
.from_package(package_path) ⇒ Repository
Load repository from LER package
312 313 314 |
# File 'lib/expressir/model/repository.rb', line 312 def self.from_package(package_path) Package::Reader.load(package_path) end |
Instance Method Details
#add_schema(schema) ⇒ Object
Add a schema to the repository
74 75 76 77 78 |
# File 'lib/expressir/model/repository.rb', line 74 def add_schema(schema) return unless schema @_schemas << schema end |
#all_schemas ⇒ Array<Declarations::Schema>
Alias for schemas
68 69 70 |
# File 'lib/expressir/model/repository.rb', line 68 def all_schemas schemas end |
#build_indexes ⇒ void
This method returns an undefined value.
Build indexes for entities, types, and references
87 88 89 90 91 92 |
# File 'lib/expressir/model/repository.rb', line 87 def build_indexes target_schemas = all_schemas @entity_index = Indexes::EntityIndex.new(target_schemas) @type_index = Indexes::TypeIndex.new(target_schemas) @reference_index = Indexes::ReferenceIndex.new(target_schemas) end |
#children ⇒ Array<Declarations::Schema>
81 82 83 |
# File 'lib/expressir/model/repository.rb', line 81 def children schemas end |
#dependency_statistics ⇒ Hash
Get dependency statistics
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/expressir/model/repository.rb', line 243 def dependency_statistics stats = { total_interfaces: 0, use_from_count: 0, reference_from_count: 0, most_referenced: [], most_dependent: [], } reference_counts = Hash.new(0) dependency_counts = Hash.new(0) all_schemas.each do |schema| next unless schema.interfaces&.any? stats[:total_interfaces] += schema.interfaces.size dependency_counts[schema.id] = schema.interfaces.size schema.interfaces.each do |interface| stats[:use_from_count] += 1 if interface.kind == Declarations::Interface::USE stats[:reference_from_count] += 1 if interface.kind == Declarations::Interface::REFERENCE reference_counts[interface.schema.id] += 1 if interface.schema end end stats[:most_referenced] = reference_counts.sort_by do |_, v| -v end.take(10).to_h stats[:most_dependent] = dependency_counts.sort_by do |_, v| -v end.take(10).to_h stats end |
#export_to_package(output_path, options = {}) ⇒ String
Export repository to LER package
326 327 328 329 |
# File 'lib/expressir/model/repository.rb', line 326 def export_to_package(output_path, = {}) builder = Package::Builder.new builder.build(self, output_path, ) end |
#find_entity(qualified_name:) ⇒ Declarations::Entity?
Find entity by qualified name
97 98 99 100 |
# File 'lib/expressir/model/repository.rb', line 97 def find_entity(qualified_name:) ensure_indexes_built @entity_index.find(qualified_name) end |
#find_type(qualified_name:) ⇒ Declarations::Type?
Find type by qualified name
105 106 107 108 |
# File 'lib/expressir/model/repository.rb', line 105 def find_type(qualified_name:) ensure_indexes_built @type_index.find(qualified_name) end |
#largest_schemas(limit = 10) ⇒ Array<Hash>
Get largest schemas by total element count
208 209 210 211 212 213 214 215 |
# File 'lib/expressir/model/repository.rb', line 208 def largest_schemas(limit = 10) all_schemas.map do |s| { schema: s, total_elements: count_schema_elements(s), } end.sort_by { |item| -item[:total_elements] }.take(limit) end |
#list_entities(schema: nil, format: :object) ⇒ Array
List all entities
114 115 116 117 118 119 120 121 122 |
# File 'lib/expressir/model/repository.rb', line 114 def list_entities(schema: nil, format: :object) ensure_indexes_built entities = @entity_index.list(schema: schema) format_output(entities, format) do |entity| { id: entity.id, schema: entity.parent.id, path: entity.path } end end |
#list_types(schema: nil, category: nil, format: :object) ⇒ Array
List all types
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/expressir/model/repository.rb', line 129 def list_types(schema: nil, category: nil, format: :object) ensure_indexes_built types = @type_index.list(schema: schema, category: category) format_output(types, format) do |type| { id: type.id, schema: type.parent.id, path: type.path, category: @type_index.categorize(type) } end end |
#resolve_all_references ⇒ void
This method returns an undefined value.
Resolve all references across schemas Uses the existing ResolveReferencesModelVisitor
143 144 145 146 |
# File 'lib/expressir/model/repository.rb', line 143 def resolve_all_references visitor = Expressir::Express::ResolveReferencesModelVisitor.new visitor.visit(self) end |
#restore_indexes(entity_index: nil, type_index: nil, reference_index: nil) ⇒ Object
Restore deserialized indexes (used by Package::Reader)
28 29 30 31 32 33 |
# File 'lib/expressir/model/repository.rb', line 28 def restore_indexes(entity_index: nil, type_index: nil, reference_index: nil) @entity_index = entity_index if entity_index @type_index = type_index if type_index @reference_index = reference_index if reference_index end |
#schema_complexity(schema) ⇒ Integer
Calculate schema complexity score Entities=2, Types=1, Functions=3, Procedures=3, Rules=4, Interfaces=2
221 222 223 224 225 226 227 228 229 230 |
# File 'lib/expressir/model/repository.rb', line 221 def schema_complexity(schema) score = 0 score += (schema.entities&.size || 0) * 2 score += (schema.types&.size || 0) * 1 score += (schema.functions&.size || 0) * 3 score += (schema.procedures&.size || 0) * 3 score += (schema.rules&.size || 0) * 4 score += (schema.interfaces&.size || 0) * 2 score end |
#schemas ⇒ Array<Declarations::Schema>
Get all schemas (from both files and direct storage)
61 62 63 64 |
# File 'lib/expressir/model/repository.rb', line 61 def schemas file_schemas = files&.flat_map(&:schemas)&.compact || [] file_schemas + @_schemas end |
#schemas_by_category ⇒ Hash
Group schemas by category based on their contents
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/expressir/model/repository.rb', line 189 def schemas_by_category target_schemas = all_schemas { with_entities: target_schemas.select { |s| s.entities&.any? }, with_types: target_schemas.select { |s| s.types&.any? }, with_functions: target_schemas.select { |s| s.functions&.any? }, with_rules: target_schemas.select { |s| s.rules&.any? }, interface_only: target_schemas.select do |s| s.interfaces&.any? && !s.entities&.any? && !s.types&.any? end, empty: target_schemas.select do |s| !s.entities&.any? && !s.types&.any? && !s.functions&.any? end, } end |
#schemas_by_complexity(limit = 10) ⇒ Array<Hash>
Get schemas sorted by complexity
235 236 237 238 239 |
# File 'lib/expressir/model/repository.rb', line 235 def schemas_by_complexity(limit = 10) all_schemas.map { |s| { schema: s, complexity: schema_complexity(s) } } .sort_by { |item| -item[:complexity] } .take(limit) end |
#statistics(format: :hash) ⇒ Hash, String
Get statistics
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/expressir/model/repository.rb', line 160 def statistics(format: :hash) ensure_indexes_built stats = { total_schemas: all_schemas.size, total_entities: count_entities, total_types: count_types, total_functions: count_functions, total_rules: count_rules, total_procedures: count_procedures, entities_by_schema: entities_by_schema_counts, types_by_category: types_by_category_counts, interfaces: interface_counts, } case format when :json require "json" stats.to_json when :yaml require "yaml" stats.to_yaml else stats end end |
#to_manifest ⇒ SchemaManifest
Generate SchemaManifest from repository
280 281 282 283 284 285 286 287 288 289 |
# File 'lib/expressir/model/repository.rb', line 280 def to_manifest manifest = Expressir::SchemaManifest.new all_schemas.each do |schema| manifest.schemas << Expressir::SchemaManifestEntry.new( id: schema.id, path: schema.file || "#{schema.id}.exp", ) end manifest end |
#validate(strict: false) ⇒ Hash
Validate repository consistency
151 152 153 154 155 |
# File 'lib/expressir/model/repository.rb', line 151 def validate(strict: false) ensure_indexes_built validator = RepositoryValidator.new(all_schemas, @reference_index) validator.validate(strict: strict) end |