expressir 2.1.30 → 2.1.31
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.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +98 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.github/workflows/validate_schemas.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +244 -39
- data/Gemfile +2 -1
- data/README.adoc +621 -54
- data/docs/Gemfile +12 -0
- data/docs/_config.yml +141 -0
- data/docs/_guides/changes/changes-format.adoc +778 -0
- data/docs/_guides/changes/importing-eengine.adoc +898 -0
- data/docs/_guides/changes/index.adoc +396 -0
- data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
- data/docs/_guides/changes/validating-changes.adoc +681 -0
- data/docs/_guides/cli/benchmark-performance.adoc +834 -0
- data/docs/_guides/cli/coverage-analysis.adoc +921 -0
- data/docs/_guides/cli/format-schemas.adoc +547 -0
- data/docs/_guides/cli/index.adoc +8 -0
- data/docs/_guides/cli/managing-changes.adoc +927 -0
- data/docs/_guides/cli/validate-ascii.adoc +645 -0
- data/docs/_guides/cli/validate-schemas.adoc +534 -0
- data/docs/_guides/index.adoc +165 -0
- data/docs/_guides/ler/creating-packages.adoc +664 -0
- data/docs/_guides/ler/index.adoc +305 -0
- data/docs/_guides/ler/loading-packages.adoc +707 -0
- data/docs/_guides/ler/package-formats.adoc +748 -0
- data/docs/_guides/ler/querying-packages.adoc +826 -0
- data/docs/_guides/ler/validating-packages.adoc +750 -0
- data/docs/_guides/liquid/basic-templates.adoc +813 -0
- data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
- data/docs/_guides/liquid/drops-reference.adoc +829 -0
- data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
- data/docs/_guides/liquid/index.adoc +468 -0
- data/docs/_guides/manifests/creating-manifests.adoc +483 -0
- data/docs/_guides/manifests/index.adoc +307 -0
- data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
- data/docs/_guides/manifests/validating-manifests.adoc +713 -0
- data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
- data/docs/_guides/ruby-api/index.adoc +257 -0
- data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
- data/docs/_guides/ruby-api/search-engine.adoc +609 -0
- data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
- data/docs/_pages/data-model.adoc +665 -0
- data/docs/_pages/express-language.adoc +506 -0
- data/docs/_pages/getting-started.adoc +414 -0
- data/docs/_pages/index.adoc +116 -0
- data/docs/_pages/introduction.adoc +256 -0
- data/docs/_pages/ler-packages.adoc +837 -0
- data/docs/_pages/parsers.adoc +683 -0
- data/docs/_pages/schema-manifests.adoc +431 -0
- data/docs/_references/index.adoc +228 -0
- data/docs/_tutorials/creating-ler-package.adoc +735 -0
- data/docs/_tutorials/documentation-coverage.adoc +795 -0
- data/docs/_tutorials/index.adoc +221 -0
- data/docs/_tutorials/liquid-templates.adoc +806 -0
- data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
- data/docs/_tutorials/querying-schemas.adoc +751 -0
- data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
- data/docs/index.adoc +242 -0
- data/docs/lychee.toml +84 -0
- data/examples/demo_ler_usage.sh +86 -0
- data/examples/ler/README.md +111 -0
- data/examples/ler/simple_example.ler +0 -0
- data/examples/ler/simple_schema.exp +33 -0
- data/examples/ler_build.rb +75 -0
- data/examples/ler_cli.rb +79 -0
- data/examples/ler_demo_complete.rb +276 -0
- data/examples/ler_query.rb +91 -0
- data/examples/ler_query_examples.rb +305 -0
- data/examples/ler_stats.rb +81 -0
- data/examples/phase3_demo.rb +159 -0
- data/examples/query_demo_simple.rb +131 -0
- data/expressir.gemspec +2 -0
- data/lib/expressir/cli.rb +12 -4
- data/lib/expressir/commands/manifest.rb +427 -0
- data/lib/expressir/commands/package.rb +1274 -0
- data/lib/expressir/commands/validate.rb +70 -37
- data/lib/expressir/commands/validate_ascii.rb +607 -0
- data/lib/expressir/commands/validate_load.rb +88 -0
- data/lib/expressir/express/formatter.rb +5 -1
- data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
- data/lib/expressir/express/parser.rb +33 -0
- data/lib/expressir/manifest/resolver.rb +213 -0
- data/lib/expressir/manifest/validator.rb +195 -0
- data/lib/expressir/model/declarations/entity.rb +6 -0
- data/lib/expressir/model/dependency_resolver.rb +270 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/reference_index.rb +148 -0
- data/lib/expressir/model/indexes/type_index.rb +149 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/repository.rb +400 -5
- data/lib/expressir/model/repository_validator.rb +295 -0
- data/lib/expressir/model/search_engine.rb +525 -0
- data/lib/expressir/model.rb +4 -94
- data/lib/expressir/package/builder.rb +200 -0
- data/lib/expressir/package/metadata.rb +81 -0
- data/lib/expressir/package/reader.rb +165 -0
- data/lib/expressir/schema_manifest.rb +11 -1
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +15 -2
- metadata +114 -4
- data/docs/benchmarking.adoc +0 -107
- data/docs/liquid_drops.adoc +0 -1547
|
@@ -1,21 +1,416 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../schema_manifest"
|
|
4
|
+
require_relative "../schema_manifest_entry"
|
|
5
|
+
|
|
1
6
|
module Expressir
|
|
2
7
|
module Model
|
|
3
|
-
# Multi-schema global scope
|
|
8
|
+
# Multi-schema global scope with enhanced repository features
|
|
9
|
+
# Focuses on schema management and delegates indexing/validation to specialized classes
|
|
4
10
|
class Repository < ModelElement
|
|
5
11
|
attribute :schemas, Expressir::Model::Declarations::Schema,
|
|
6
|
-
collection: true
|
|
12
|
+
collection: true,
|
|
13
|
+
initialize_empty: true
|
|
7
14
|
attribute :_class, :string, default: -> { send(:name) }
|
|
8
15
|
|
|
16
|
+
# Base directory for schema files
|
|
17
|
+
attr_accessor :base_dir
|
|
18
|
+
|
|
19
|
+
# Index instances (lazy-loaded)
|
|
20
|
+
attr_reader :entity_index, :type_index, :reference_index
|
|
21
|
+
|
|
9
22
|
key_value do
|
|
10
23
|
map "_class", to: :_class, render_default: true
|
|
11
24
|
map "schemas", to: :schemas
|
|
12
25
|
end
|
|
13
26
|
|
|
27
|
+
def initialize(*args, base_dir: nil, **kwargs)
|
|
28
|
+
super(*args, **kwargs)
|
|
29
|
+
@base_dir = base_dir
|
|
30
|
+
@entity_index = nil
|
|
31
|
+
@type_index = nil
|
|
32
|
+
@reference_index = nil
|
|
33
|
+
end
|
|
34
|
+
|
|
14
35
|
# @return [Array<Declaration>]
|
|
15
36
|
def children
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
37
|
+
schemas
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Build indexes for entities, types, and references
|
|
41
|
+
# @return [void]
|
|
42
|
+
def build_indexes
|
|
43
|
+
@entity_index = Indexes::EntityIndex.new(schemas)
|
|
44
|
+
@type_index = Indexes::TypeIndex.new(schemas)
|
|
45
|
+
@reference_index = Indexes::ReferenceIndex.new(schemas)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Find entity by qualified name
|
|
49
|
+
# @param qualified_name [String] Entity qualified name (e.g., "action_schema.action")
|
|
50
|
+
# @return [Declarations::Entity, nil] Found entity or nil
|
|
51
|
+
def find_entity(qualified_name:)
|
|
52
|
+
ensure_indexes_built
|
|
53
|
+
@entity_index.find(qualified_name)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Find type by qualified name
|
|
57
|
+
# @param qualified_name [String] Type qualified name
|
|
58
|
+
# @return [Declarations::Type, nil] Found type or nil
|
|
59
|
+
def find_type(qualified_name:)
|
|
60
|
+
ensure_indexes_built
|
|
61
|
+
@type_index.find(qualified_name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# List all entities
|
|
65
|
+
# @param schema [String, nil] Filter by schema name
|
|
66
|
+
# @param format [Symbol] Output format (:object, :hash, :json, :yaml)
|
|
67
|
+
# @return [Array] List of entities
|
|
68
|
+
def list_entities(schema: nil, format: :object)
|
|
69
|
+
ensure_indexes_built
|
|
70
|
+
|
|
71
|
+
entities = @entity_index.list(schema: schema)
|
|
72
|
+
|
|
73
|
+
format_output(entities, format) do |entity|
|
|
74
|
+
{ id: entity.id, schema: entity.parent.id, path: entity.path }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# List all types
|
|
79
|
+
# @param schema [String, nil] Filter by schema name
|
|
80
|
+
# @param category [String, nil] Filter by type category (select, enumeration, etc.)
|
|
81
|
+
# @param format [Symbol] Output format (:object, :hash, :json, :yaml)
|
|
82
|
+
# @return [Array] List of types
|
|
83
|
+
def list_types(schema: nil, category: nil, format: :object)
|
|
84
|
+
ensure_indexes_built
|
|
85
|
+
|
|
86
|
+
types = @type_index.list(schema: schema, category: category)
|
|
87
|
+
|
|
88
|
+
format_output(types, format) do |type|
|
|
89
|
+
{ id: type.id, schema: type.parent.id, path: type.path,
|
|
90
|
+
category: @type_index.categorize(type) }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Resolve all references across schemas
|
|
95
|
+
# Uses the existing ResolveReferencesModelVisitor
|
|
96
|
+
# @return [void]
|
|
97
|
+
def resolve_all_references
|
|
98
|
+
visitor = Expressir::Express::ResolveReferencesModelVisitor.new
|
|
99
|
+
visitor.visit(self)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Validate repository consistency
|
|
103
|
+
# @param strict [Boolean] Enable strict validation
|
|
104
|
+
# @return [Hash] Validation results with :valid?, :errors, :warnings
|
|
105
|
+
def validate(strict: false)
|
|
106
|
+
ensure_indexes_built
|
|
107
|
+
validator = RepositoryValidator.new(schemas, @reference_index)
|
|
108
|
+
validator.validate(strict: strict)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Get statistics
|
|
112
|
+
# @param format [Symbol] Output format (:hash, :json, :yaml)
|
|
113
|
+
# @return [Hash, String] Repository statistics
|
|
114
|
+
def statistics(format: :hash)
|
|
115
|
+
ensure_indexes_built
|
|
116
|
+
|
|
117
|
+
stats = {
|
|
118
|
+
total_schemas: schemas.size,
|
|
119
|
+
total_entities: count_entities,
|
|
120
|
+
total_types: count_types,
|
|
121
|
+
total_functions: count_functions,
|
|
122
|
+
total_rules: count_rules,
|
|
123
|
+
total_procedures: count_procedures,
|
|
124
|
+
entities_by_schema: entities_by_schema_counts,
|
|
125
|
+
types_by_category: types_by_category_counts,
|
|
126
|
+
interfaces: interface_counts,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
case format
|
|
130
|
+
when :json
|
|
131
|
+
require "json"
|
|
132
|
+
stats.to_json
|
|
133
|
+
when :yaml
|
|
134
|
+
require "yaml"
|
|
135
|
+
stats.to_yaml
|
|
136
|
+
else
|
|
137
|
+
stats
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Group schemas by category based on their contents
|
|
142
|
+
# @return [Hash] Hash with category keys and schema arrays
|
|
143
|
+
def schemas_by_category
|
|
144
|
+
{
|
|
145
|
+
with_entities: schemas.select { |s| s.entities&.any? },
|
|
146
|
+
with_types: schemas.select { |s| s.types&.any? },
|
|
147
|
+
with_functions: schemas.select { |s| s.functions&.any? },
|
|
148
|
+
with_rules: schemas.select { |s| s.rules&.any? },
|
|
149
|
+
interface_only: schemas.select do |s|
|
|
150
|
+
s.interfaces&.any? && !s.entities&.any? && !s.types&.any?
|
|
151
|
+
end,
|
|
152
|
+
empty: schemas.select do |s|
|
|
153
|
+
!s.entities&.any? && !s.types&.any? && !s.functions&.any?
|
|
154
|
+
end,
|
|
155
|
+
}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Get largest schemas by total element count
|
|
159
|
+
# @param limit [Integer] Maximum number of schemas to return
|
|
160
|
+
# @return [Array<Hash>] Array of hashes with :schema and :total_elements
|
|
161
|
+
def largest_schemas(limit = 10)
|
|
162
|
+
schemas.map do |s|
|
|
163
|
+
{
|
|
164
|
+
schema: s,
|
|
165
|
+
total_elements: count_schema_elements(s),
|
|
166
|
+
}
|
|
167
|
+
end.sort_by { |item| -item[:total_elements] }.take(limit)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Calculate schema complexity score
|
|
171
|
+
# Entities=2, Types=1, Functions=3, Procedures=3, Rules=4, Interfaces=2
|
|
172
|
+
# @param schema [Declarations::Schema] Schema to analyze
|
|
173
|
+
# @return [Integer] Complexity score
|
|
174
|
+
def schema_complexity(schema)
|
|
175
|
+
score = 0
|
|
176
|
+
score += (schema.entities&.size || 0) * 2
|
|
177
|
+
score += (schema.types&.size || 0) * 1
|
|
178
|
+
score += (schema.functions&.size || 0) * 3
|
|
179
|
+
score += (schema.procedures&.size || 0) * 3
|
|
180
|
+
score += (schema.rules&.size || 0) * 4
|
|
181
|
+
score += (schema.interfaces&.size || 0) * 2
|
|
182
|
+
score
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Get schemas sorted by complexity
|
|
186
|
+
# @param limit [Integer] Maximum number of schemas to return
|
|
187
|
+
# @return [Array<Hash>] Array of hashes with :schema and :complexity
|
|
188
|
+
def schemas_by_complexity(limit = 10)
|
|
189
|
+
schemas.map { |s| { schema: s, complexity: schema_complexity(s) } }
|
|
190
|
+
.sort_by { |item| -item[:complexity] }
|
|
191
|
+
.take(limit)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Get dependency statistics
|
|
195
|
+
# @return [Hash] Statistics about interface dependencies
|
|
196
|
+
def dependency_statistics
|
|
197
|
+
stats = {
|
|
198
|
+
total_interfaces: 0,
|
|
199
|
+
use_from_count: 0,
|
|
200
|
+
reference_from_count: 0,
|
|
201
|
+
most_referenced: [],
|
|
202
|
+
most_dependent: [],
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
reference_counts = Hash.new(0)
|
|
206
|
+
dependency_counts = Hash.new(0)
|
|
207
|
+
|
|
208
|
+
schemas.each do |schema|
|
|
209
|
+
next unless schema.interfaces&.any?
|
|
210
|
+
|
|
211
|
+
stats[:total_interfaces] += schema.interfaces.size
|
|
212
|
+
dependency_counts[schema.id] = schema.interfaces.size
|
|
213
|
+
|
|
214
|
+
schema.interfaces.each do |interface|
|
|
215
|
+
stats[:use_from_count] += 1 if interface.kind == Declarations::Interface::USE
|
|
216
|
+
stats[:reference_from_count] += 1 if interface.kind == Declarations::Interface::REFERENCE
|
|
217
|
+
reference_counts[interface.schema.id] += 1 if interface.schema
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
stats[:most_referenced] = reference_counts.sort_by do |_, v|
|
|
222
|
+
-v
|
|
223
|
+
end.take(10).to_h
|
|
224
|
+
stats[:most_dependent] = dependency_counts.sort_by do |_, v|
|
|
225
|
+
-v
|
|
226
|
+
end.take(10).to_h
|
|
227
|
+
|
|
228
|
+
stats
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Generate SchemaManifest from repository
|
|
232
|
+
# @return [SchemaManifest] Manifest describing all schemas
|
|
233
|
+
def to_manifest
|
|
234
|
+
manifest = Expressir::SchemaManifest.new
|
|
235
|
+
schemas.each do |schema|
|
|
236
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
|
237
|
+
id: schema.id,
|
|
238
|
+
path: schema.file || "#{schema.id}.exp",
|
|
239
|
+
)
|
|
240
|
+
end
|
|
241
|
+
manifest
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Build repository from list of schema files
|
|
245
|
+
# @param file_paths [Array<String>] Schema file paths
|
|
246
|
+
# @param base_dir [String, nil] Base directory for path resolution
|
|
247
|
+
# @return [Repository] Built repository with all schemas
|
|
248
|
+
def self.from_files(file_paths, base_dir: nil)
|
|
249
|
+
repo = new(base_dir: base_dir)
|
|
250
|
+
|
|
251
|
+
file_paths.each do |path|
|
|
252
|
+
parsed = Expressir::Express::Parser.from_file(path)
|
|
253
|
+
parsed&.schemas&.each { |schema| repo.schemas << schema }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
repo.resolve_all_references
|
|
257
|
+
repo
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Load repository from LER package
|
|
261
|
+
# @param package_path [String] Path to .ler package file
|
|
262
|
+
# @return [Repository] Loaded repository
|
|
263
|
+
def self.from_package(package_path)
|
|
264
|
+
require_relative "../package/reader"
|
|
265
|
+
Package::Reader.load(package_path)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Export repository to LER package
|
|
269
|
+
# @param output_path [String] Path for output .ler file
|
|
270
|
+
# @param options [Hash] Package options
|
|
271
|
+
# @option options [String] :name Package name
|
|
272
|
+
# @option options [String] :version Package version
|
|
273
|
+
# @option options [String] :description Package description
|
|
274
|
+
# @option options [String] :express_mode ('include_all') Bundling mode
|
|
275
|
+
# @option options [String] :resolution_mode ('resolved') Resolution mode
|
|
276
|
+
# @option options [String] :serialization_format ('marshal') Serialization format
|
|
277
|
+
# @return [String] Path to created package
|
|
278
|
+
def export_to_package(output_path, options = {})
|
|
279
|
+
require_relative "../package/builder"
|
|
280
|
+
builder = Package::Builder.new
|
|
281
|
+
builder.build(self, output_path, options)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
private
|
|
285
|
+
|
|
286
|
+
# Count total elements in schema
|
|
287
|
+
# @param schema [Declarations::Schema] Schema to count elements from
|
|
288
|
+
# @return [Integer] Total count of all elements
|
|
289
|
+
def count_schema_elements(schema)
|
|
290
|
+
(schema.entities&.size || 0) +
|
|
291
|
+
(schema.types&.size || 0) +
|
|
292
|
+
(schema.functions&.size || 0) +
|
|
293
|
+
(schema.procedures&.size || 0) +
|
|
294
|
+
(schema.rules&.size || 0) +
|
|
295
|
+
(schema.constants&.size || 0)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Ensure indexes are built before use
|
|
299
|
+
# @return [void]
|
|
300
|
+
def ensure_indexes_built
|
|
301
|
+
build_indexes if @entity_index.nil? || @entity_index.empty?
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Format output based on requested format
|
|
305
|
+
# @param items [Array] Items to format
|
|
306
|
+
# @param format [Symbol] Output format
|
|
307
|
+
# @yield [item] Block to convert item to hash
|
|
308
|
+
# @return [Array, String] Formatted output
|
|
309
|
+
def format_output(items, format, &block)
|
|
310
|
+
case format
|
|
311
|
+
when :hash
|
|
312
|
+
items.map(&block)
|
|
313
|
+
when :json
|
|
314
|
+
require "json"
|
|
315
|
+
items.map(&block).to_json
|
|
316
|
+
when :yaml
|
|
317
|
+
require "yaml"
|
|
318
|
+
items.map(&block).to_yaml
|
|
319
|
+
else
|
|
320
|
+
items
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Count entities by schema
|
|
325
|
+
# @return [Hash<String, Integer>] Entity counts per schema
|
|
326
|
+
def entities_by_schema_counts
|
|
327
|
+
counts = {}
|
|
328
|
+
schemas.each do |schema|
|
|
329
|
+
counts[schema.id] = schema.entities&.size || 0
|
|
330
|
+
end
|
|
331
|
+
counts
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Count types by category
|
|
335
|
+
# @return [Hash<Symbol, Integer>] Type counts per category
|
|
336
|
+
def types_by_category_counts
|
|
337
|
+
counts = {
|
|
338
|
+
select: 0,
|
|
339
|
+
enumeration: 0,
|
|
340
|
+
aggregate: 0,
|
|
341
|
+
defined: 0,
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
schemas.each do |schema|
|
|
345
|
+
next unless schema.types
|
|
346
|
+
|
|
347
|
+
schema.types.each do |type|
|
|
348
|
+
category = @type_index.categorize(type).to_sym
|
|
349
|
+
counts[category] ||= 0
|
|
350
|
+
counts[category] += 1
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
counts
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Count interfaces by type
|
|
358
|
+
# @return [Hash<Symbol, Integer>] Interface counts
|
|
359
|
+
def interface_counts
|
|
360
|
+
counts = {
|
|
361
|
+
use_from: 0,
|
|
362
|
+
reference_from: 0,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
schemas.each do |schema|
|
|
366
|
+
next unless schema.interfaces
|
|
367
|
+
|
|
368
|
+
schema.interfaces.each do |interface|
|
|
369
|
+
if interface.kind == Declarations::Interface::USE
|
|
370
|
+
counts[:use_from] += 1
|
|
371
|
+
elsif interface.kind == Declarations::Interface::REFERENCE
|
|
372
|
+
counts[:reference_from] += 1
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
counts
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# Count total entities across all schemas
|
|
381
|
+
# Uses indexes if available, falls back to schemas collection
|
|
382
|
+
# @return [Integer] Total entity count
|
|
383
|
+
def count_entities
|
|
384
|
+
return @entity_index.count if @entity_index && !@entity_index.empty?
|
|
385
|
+
|
|
386
|
+
schemas.sum { |schema| schema.entities&.size || 0 }
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Count total types across all schemas
|
|
390
|
+
# Uses indexes if available, falls back to schemas collection
|
|
391
|
+
# @return [Integer] Total type count
|
|
392
|
+
def count_types
|
|
393
|
+
return @type_index.count if @type_index && !@type_index.empty?
|
|
394
|
+
|
|
395
|
+
schemas.sum { |schema| schema.types&.size || 0 }
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# Count total functions across all schemas
|
|
399
|
+
# @return [Integer] Total function count
|
|
400
|
+
def count_functions
|
|
401
|
+
schemas.sum { |schema| schema.functions&.size || 0 }
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# Count total rules across all schemas
|
|
405
|
+
# @return [Integer] Total rule count
|
|
406
|
+
def count_rules
|
|
407
|
+
schemas.sum { |schema| schema.rules&.size || 0 }
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# Count total procedures across all schemas
|
|
411
|
+
# @return [Integer] Total procedure count
|
|
412
|
+
def count_procedures
|
|
413
|
+
schemas.sum { |schema| schema.procedures&.size || 0 }
|
|
19
414
|
end
|
|
20
415
|
end
|
|
21
416
|
end
|