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, #remark_infos, #reset_children_by_id, #source, #to_s
Constructor Details
#initialize(base_dir: nil, schemas: nil) ⇒ Repository
Returns a new instance of Repository.
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/expressir/model/repository.rb', line 35 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
283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/expressir/model/repository.rb', line 283 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
300 301 302 |
# File 'lib/expressir/model/repository.rb', line 300 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
62 63 64 65 66 |
# File 'lib/expressir/model/repository.rb', line 62 def add_schema(schema) return unless schema @_schemas << schema end |
#all_schemas ⇒ Array<Declarations::Schema>
Alias for schemas
56 57 58 |
# File 'lib/expressir/model/repository.rb', line 56 def all_schemas schemas end |
#build_indexes ⇒ void
This method returns an undefined value.
Build indexes for entities, types, and references
75 76 77 78 79 80 |
# File 'lib/expressir/model/repository.rb', line 75 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>
69 70 71 |
# File 'lib/expressir/model/repository.rb', line 69 def children schemas end |
#dependency_statistics ⇒ Hash
Get dependency statistics
231 232 233 234 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 |
# File 'lib/expressir/model/repository.rb', line 231 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
314 315 316 317 |
# File 'lib/expressir/model/repository.rb', line 314 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
85 86 87 88 |
# File 'lib/expressir/model/repository.rb', line 85 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
93 94 95 96 |
# File 'lib/expressir/model/repository.rb', line 93 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
196 197 198 199 200 201 202 203 |
# File 'lib/expressir/model/repository.rb', line 196 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
102 103 104 105 106 107 108 109 110 |
# File 'lib/expressir/model/repository.rb', line 102 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
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/expressir/model/repository.rb', line 117 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
131 132 133 134 |
# File 'lib/expressir/model/repository.rb', line 131 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
209 210 211 212 213 214 215 216 217 218 |
# File 'lib/expressir/model/repository.rb', line 209 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)
49 50 51 52 |
# File 'lib/expressir/model/repository.rb', line 49 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
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/expressir/model/repository.rb', line 177 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
223 224 225 226 227 |
# File 'lib/expressir/model/repository.rb', line 223 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
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/expressir/model/repository.rb', line 148 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
268 269 270 271 272 273 274 275 276 277 |
# File 'lib/expressir/model/repository.rb', line 268 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
139 140 141 142 143 |
# File 'lib/expressir/model/repository.rb', line 139 def validate(strict: false) ensure_indexes_built validator = RepositoryValidator.new(all_schemas, @reference_index) validator.validate(strict: strict) end |