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.
-
#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.
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/expressir/model/repository.rb', line 39 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
28 29 30 |
# File 'lib/expressir/model/repository.rb', line 28 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
287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/expressir/model/repository.rb', line 287 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
304 305 306 |
# File 'lib/expressir/model/repository.rb', line 304 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
66 67 68 69 70 |
# File 'lib/expressir/model/repository.rb', line 66 def add_schema(schema) return unless schema @_schemas << schema end |
#all_schemas ⇒ Array<Declarations::Schema>
Alias for schemas
60 61 62 |
# File 'lib/expressir/model/repository.rb', line 60 def all_schemas schemas end |
#build_indexes ⇒ void
This method returns an undefined value.
Build indexes for entities, types, and references
79 80 81 82 83 84 |
# File 'lib/expressir/model/repository.rb', line 79 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>
73 74 75 |
# File 'lib/expressir/model/repository.rb', line 73 def children schemas end |
#dependency_statistics ⇒ Hash
Get dependency statistics
235 236 237 238 239 240 241 242 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 |
# File 'lib/expressir/model/repository.rb', line 235 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
318 319 320 321 |
# File 'lib/expressir/model/repository.rb', line 318 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
89 90 91 92 |
# File 'lib/expressir/model/repository.rb', line 89 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
97 98 99 100 |
# File 'lib/expressir/model/repository.rb', line 97 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
200 201 202 203 204 205 206 207 |
# File 'lib/expressir/model/repository.rb', line 200 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
106 107 108 109 110 111 112 113 114 |
# File 'lib/expressir/model/repository.rb', line 106 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
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/expressir/model/repository.rb', line 121 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
135 136 137 138 |
# File 'lib/expressir/model/repository.rb', line 135 def resolve_all_references visitor = Expressir::Express::ResolveReferencesModelVisitor.new visitor.visit(self) end |
#schema_complexity(schema) ⇒ Integer
Calculate schema complexity score Entities=2, Types=1, Functions=3, Procedures=3, Rules=4, Interfaces=2
213 214 215 216 217 218 219 220 221 222 |
# File 'lib/expressir/model/repository.rb', line 213 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)
53 54 55 56 |
# File 'lib/expressir/model/repository.rb', line 53 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
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/expressir/model/repository.rb', line 181 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
227 228 229 230 231 |
# File 'lib/expressir/model/repository.rb', line 227 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/expressir/model/repository.rb', line 152 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
272 273 274 275 276 277 278 279 280 281 |
# File 'lib/expressir/model/repository.rb', line 272 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
143 144 145 146 147 |
# File 'lib/expressir/model/repository.rb', line 143 def validate(strict: false) ensure_indexes_built validator = RepositoryValidator.new(all_schemas, @reference_index) validator.validate(strict: strict) end |