Class: Mxrb::Compiler::ModelPackage

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

Overview

Mendix model.mdp is an ordered stream of BSON documents without a container header. Each document carries its own int32 BSON length.

Defined Under Namespace

Classes: Entry

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entries) ⇒ ModelPackage

Returns a new instance of ModelPackage.



64
65
66
# File 'lib/mxrb/compiler/model_package.rb', line 64

def initialize(entries)
  @entries = entries
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries.



16
17
18
# File 'lib/mxrb/compiler/model_package.rb', line 16

def entries
  @entries
end

Class Method Details

.decode(bytes, label = 'model.mdp') ⇒ Object



24
# File 'lib/mxrb/compiler/model_package.rb', line 24

def self.decode(bytes, label = 'model.mdp') = new(parse(bytes, label))

.emptyObject



23
# File 'lib/mxrb/compiler/model_package.rb', line 23

def self.empty = new([].freeze)

.from_documents(documents) ⇒ Object



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

def self.from_documents(documents)
  new([].freeze).then do |package|
    documents.reduce(package) { |result, document| result.with_appended(document) }
  end
end

.read(path) ⇒ Object



18
19
20
21
# File 'lib/mxrb/compiler/model_package.rb', line 18

def self.read(path)
  bytes = File.binread(path)
  new(parse(bytes, path))
end

Instance Method Details

#documentsObject



68
# File 'lib/mxrb/compiler/model_package.rb', line 68

def documents = entries.map(&:document)

#find(id) ⇒ Object



70
# File 'lib/mxrb/compiler/model_package.rb', line 70

def find(id) = entries.find { _1.id == id }

#replace(id, document) ⇒ Object

Raises:



72
73
74
75
76
77
78
79
80
# File 'lib/mxrb/compiler/model_package.rb', line 72

def replace(id, document)
  index = entries.index { _1.id == id }
  raise CompilationError, "model document #{id} not found" unless index

  updated = entries.map.with_index do |entry, position|
    position == index ? Entry.new(offset: 0, size: 0, document:) : entry
  end
  self.class.new(reindex(updated))
end

#typesObject



69
# File 'lib/mxrb/compiler/model_package.rb', line 69

def types = entries.map(&:type).tally.freeze

#upsert(document) ⇒ Object

Raises:



82
83
84
85
86
87
88
# File 'lib/mxrb/compiler/model_package.rb', line 82

def upsert(document)
  id = IO::BsonCodec.extract_id(document['$ID'])
  raise CompilationError, 'model document has no $ID' unless id
  return replace(id, document) if find(id)

  self.class.new(reindex(entries + [Entry.new(offset: 0, size: 0, document:)]))
end

#with_appended(document) ⇒ Object



90
91
92
# File 'lib/mxrb/compiler/model_package.rb', line 90

def with_appended(document)
  self.class.new(reindex(entries + [Entry.new(offset: 0, size: 0, document:)]))
end

#write(path) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# File 'lib/mxrb/compiler/model_package.rb', line 94

def write(path)
  output = File.expand_path(path)
  FileUtils.mkdir_p(File.dirname(output))
  Dir.mktmpdir('mxrb-model-', File.dirname(output)) do |directory|
    temporary = File.join(directory, 'model.mdp')
    File.binwrite(temporary, entries.map { IO::BsonCodec.serialize(_1.document) }.join)
    FileUtils.mv(temporary, output, force: true)
  end
  output
end