Class: Mxrb::Compiler::RuntimeModelSchema

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/compiler/runtime_model_schema.rb

Overview

Learns ordered Runtime BSON fields and existing compiled values from model.mdp.

Constant Summary collapse

DEFAULT_FIELDS =
JSON.parse(
  File.read(File.join(__dir__, 'schemas', 'runtime-11.json'))
).transform_values(&:freeze).freeze
AUDITED_FIELDS =
Dir[File.join(__dir__, 'schemas', 'runtime-*.json')].sort.reduce(DEFAULT_FIELDS) do |all, path|
  all.merge(JSON.parse(File.read(path)).transform_values(&:freeze))
end.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(package, version: nil) ⇒ RuntimeModelSchema

Returns a new instance of RuntimeModelSchema.



32
33
34
35
36
37
38
39
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 32

def initialize(package, version: nil)
  @by_id = {}
  @by_qualified_name = {}
  @fields = Hash.new { |hash, key| hash[key] = [] }
  @builtin_fields = self.class.builtin_fields(version)
  @versioned_fields = versioned_fields(version)
  package.documents.each { index(_1) }
end

Class Method Details

.builtin_fields(version) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 15

def self.builtin_fields(version)
  return DEFAULT_FIELDS unless version

  seed_version = SystemModelSeed.seed_version_for(version)
  path = schema_path(seed_version)
  return DEFAULT_FIELDS unless path

  versioned = JSON.parse(File.read(path)).transform_values(&:freeze)
  AUDITED_FIELDS.merge(versioned).freeze
end

.schema_path(version) ⇒ Object



26
27
28
29
30
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 26

def self.schema_path(version)
  exact = File.join(__dir__, 'schemas', "runtime-#{version}.json")
  major = File.join(__dir__, 'schemas', "runtime-#{version.to_s.split('.').first}.json")
  [exact, major].find { File.file?(_1) }
end

Instance Method Details

#counterpart(source) ⇒ Object



41
42
43
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 41

def counterpart(source)
  @by_id[IO::BsonCodec.extract_id(source['$ID'])]
end

#counterpart_id(id) ⇒ Object



45
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 45

def counterpart_id(id) = @by_id[IO::BsonCodec.extract_id(id)]

#fields_for(source) ⇒ Object

rubocop:disable Metrics/AbcSize

Raises:



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 48

def fields_for(source) # rubocop:disable Metrics/AbcSize
  return @versioned_fields.fetch(source['$Type']) if @versioned_fields.key?(source['$Type'])

  existing = counterpart(source)
  return existing.keys if existing && existing['$Type'] == source['$Type']
  return @builtin_fields.fetch(source['$Type']) if @builtin_fields.key?(source['$Type'])

  candidates = @fields.fetch(source['$Type'], [])
  raise CompilationError, "no Runtime schema for #{source['$Type']}" if candidates.empty?

  candidates.max_by(&:length)
end

#named(qualified_name) ⇒ Object



46
# File 'lib/mxrb/compiler/runtime_model_schema.rb', line 46

def named(qualified_name) = @by_qualified_name[qualified_name]