mxrb 0.1.2 → 0.1.3

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.
data/lib/mxrb/writer.rb CHANGED
@@ -31,19 +31,32 @@ module Mxrb
31
31
  def initialize(path, definition)
32
32
  @path = File.expand_path(path)
33
33
  @definition = definition
34
+ @progress = Progress::NullTask.instance
34
35
  end
35
36
 
36
37
  def write!
37
- create_project! unless File.exist?(@path)
38
- mpr = IO::MprFile.open(@path)
39
- mpr.transaction do
40
- apply(mpr)
41
- mpr.write_architecture_definition(@definition)
42
- end
43
- materialize_project_assets
44
- materialize_design_system
38
+ mpr = nil
39
+ native_units = prepared_native_units
40
+ asset_manifest = project_asset_manifest
41
+ total = 4 + native_units.count { _1["containment"] != "Modules" } +
42
+ @definition.fetch(:modules).size + Array(asset_manifest&.fetch("files", [])).size
43
+ Progress.with("Generating #{File.basename(@path)}", total:) do |progress|
44
+ @progress = progress
45
+ create_project! unless File.exist?(@path)
46
+ progress.advance(detail: "project container")
47
+ mpr = IO::MprFile.open(@path)
48
+ mpr.transaction do
49
+ apply(mpr, native_units)
50
+ mpr.write_architecture_definition(@definition)
51
+ end
52
+ progress.advance(detail: "model transaction")
53
+ materialize_project_assets(asset_manifest)
54
+ materialize_design_system
55
+ progress.advance(detail: "design system")
56
+ end
45
57
  self
46
58
  ensure
59
+ @progress = Progress::NullTask.instance
47
60
  mpr&.close
48
61
  end
49
62
 
@@ -56,11 +69,17 @@ module Mxrb
56
69
  Model::DesignMaterializer.new(File.dirname(@path), design_system).materialize!
57
70
  end
58
71
 
59
- def materialize_project_assets
72
+ def project_asset_manifest
60
73
  assets = @definition[:project_assets]
61
74
  return unless assets
62
75
 
63
- manifest = JSON.parse(File.read(assets.fetch(:manifest)))
76
+ JSON.parse(File.read(assets.fetch(:manifest)))
77
+ end
78
+
79
+ def materialize_project_assets(manifest)
80
+ assets = @definition[:project_assets]
81
+ return unless assets && manifest
82
+
64
83
  source_root = File.realpath(assets.fetch(:root))
65
84
  target_root = File.dirname(@path)
66
85
  manifest.fetch("files").each do |entry|
@@ -79,6 +98,7 @@ module Mxrb
79
98
  FileUtils.mv(temporary, target)
80
99
  ensure
81
100
  FileUtils.rm_f(temporary) if temporary
101
+ @progress.advance(detail: "asset #{relative}") if defined?(relative) && relative
82
102
  end
83
103
  end
84
104
 
@@ -161,7 +181,7 @@ module Mxrb
161
181
  JSON.parse(File.read(path))["format_version"]
162
182
  end
163
183
 
164
- def apply(mpr)
184
+ def apply(mpr, native_units)
165
185
  root = mpr.root_unit
166
186
  root_id = root.fetch("UnitID")
167
187
  root_doc = mpr.parse_contents(root)
@@ -171,10 +191,6 @@ module Mxrb
171
191
  "IsSystemProject" => false
172
192
  }
173
193
  mpr.update_unit(root_id, root_doc)
174
- native_units = load_native_units(@definition[:native_units_path])
175
- native_units = apply_native_unit_overrides(
176
- native_units, @definition.fetch(:native_unit_overrides, [])
177
- )
178
194
  apply_native_project_units(mpr, root_id, native_units)
179
195
  apply_default_project_units(mpr, root_id)
180
196
  ensure_project_documents(mpr, root_id)
@@ -194,9 +210,18 @@ module Mxrb
194
210
  write_module_security(mpr, module_id, mod) if mod.key?(:module_roles)
195
211
  write_domain_model(mpr, module_id, mod)
196
212
  write_documents(mpr, module_id, mod)
213
+ @progress.advance(detail: "module #{mod.fetch(:name)}")
197
214
  end
198
215
  write_project_security(mpr, root_id, @definition[:security]) if @definition[:security]
199
216
  write_project_navigation(mpr, root_id, @definition[:navigation]) if @definition[:navigation]
217
+ @progress.advance(detail: "project security and navigation")
218
+ end
219
+
220
+ def prepared_native_units
221
+ apply_native_unit_overrides(
222
+ load_native_units(@definition[:native_units_path]),
223
+ @definition.fetch(:native_unit_overrides, [])
224
+ )
200
225
  end
201
226
 
202
227
  def load_native_units(path)
@@ -323,8 +348,20 @@ module Mxrb
323
348
  mod.fetch(:native_documents, []).each do |document|
324
349
  doc = document.fetch(:doc)
325
350
  doc = legacy_layout_doc(doc) if doc['$Type'] == 'Forms$Layout' && legacy_layout?
351
+ existing = mpr.unit(document[:unit_id]) if document[:unit_id]
352
+ if existing
353
+ current = mpr.parse_contents(existing)
354
+ preserved = current.merge(doc).merge(
355
+ '$ID' => current['$ID'] || existing.fetch('UnitID'), '$Type' => doc.fetch('$Type')
356
+ )
357
+ mpr.update_unit(existing.fetch('UnitID'), preserved)
358
+ next
359
+ end
360
+
361
+ requested_container = document[:container_id]
362
+ target_container = requested_container && mpr.unit(requested_container) ? requested_container : module_id
326
363
  upsert_native_unit(
327
- mpr, module_id,
364
+ mpr, target_container,
328
365
  'containment' => document.fetch(:containment), 'doc' => doc
329
366
  )
330
367
  end
@@ -365,7 +402,10 @@ module Mxrb
365
402
 
366
403
  def apply_native_unit_tree(mpr, target_root_id, units)
367
404
  if units.any? { _1["unit_id"].to_s.empty? || _1["container_id"].to_s.empty? }
368
- units.each { upsert_native_unit(mpr, target_root_id, _1) }
405
+ units.each do |unit|
406
+ upsert_native_unit(mpr, target_root_id, unit)
407
+ @progress.advance(detail: "native unit #{unit['name']}")
408
+ end
369
409
  return
370
410
  end
371
411
 
@@ -382,6 +422,7 @@ module Mxrb
382
422
  target_container = mapped_containers.fetch(unit.fetch("container_id"))
383
423
  actual_id = upsert_native_unit(mpr, target_container, unit)
384
424
  mapped_containers[unit.fetch("unit_id")] = actual_id
425
+ @progress.advance(detail: "native unit #{unit['name']}")
385
426
  end
386
427
  pending = blocked
387
428
  end
@@ -1360,7 +1401,7 @@ module Mxrb
1360
1401
  previous&.dig(rules_key) || IO::BsonCodec.build_array([])
1361
1402
  end
1362
1403
  doc = (previous || {}).merge(
1363
- "$ID" => id, "$Type" => "DomainModels$EntityImpl",
1404
+ "$ID" => id, "$Type" => previous&.fetch("$Type", nil) || "DomainModels$EntityImpl",
1364
1405
  "Name" => entity.fetch(:name), "Documentation" => entity.fetch(:documentation, ""),
1365
1406
  "GUID" => previous&.dig("GUID") || SecureRandom.uuid,
1366
1407
  "Location" => previous&.dig("Location") || "#{(index % 4) * 220};#{(index / 4) * 160}",
@@ -1368,6 +1409,7 @@ module Mxrb
1368
1409
  "IsRemote" => previous&.fetch("IsRemote", false) || false,
1369
1410
  "RemoteSource" => previous&.fetch("RemoteSource", "") || ""
1370
1411
  )
1412
+ apply_oql_view!(doc, entity.fetch(:oql_view, nil), previous)
1371
1413
  doc[attrs_key] = IO::BsonCodec.build_array(attrs)
1372
1414
  doc[rules_key] = access_rules
1373
1415
  doc[validation_key] = validation_rules_doc(
@@ -1397,6 +1439,25 @@ module Mxrb
1397
1439
  doc
1398
1440
  end
1399
1441
 
1442
+ def apply_oql_view!(doc, view, previous)
1443
+ return unless view
1444
+
1445
+ if view[:source]
1446
+ source_key = native_existing_key(previous, 'source', 'Source') || 'Source'
1447
+ current_source = previous&.dig(source_key)
1448
+ source = (current_source.is_a?(Hash) ? current_source : {}).merge(
1449
+ '$ID' => current_source&.fetch('$ID', nil) || SecureRandom.uuid,
1450
+ '$Type' => 'DomainModels$OqlViewEntitySource',
1451
+ 'SourceDocument' => view.fetch(:source)
1452
+ )
1453
+ doc[source_key] = source
1454
+ end
1455
+ return unless view[:query]
1456
+
1457
+ query_key = native_existing_key(previous, 'oqlQuery', 'OqlQuery', 'OQLQuery') || 'OqlQuery'
1458
+ doc[query_key] = view.fetch(:query)
1459
+ end
1460
+
1400
1461
  def attribute_doc(attr, previous)
1401
1462
  storage_type = Model::Attribute::TYPE_MAP.fetch(attr.fetch(:type))
1402
1463
  type_key = native_existing_key(previous, "type", "Type", "newType", "NewType") || "NewType"
data/lib/mxrb.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "mxrb/version"
4
4
  require_relative "mxrb/errors"
5
+ require_relative "mxrb/progress"
5
6
  require_relative "mxrb/doctor"
6
7
  require_relative "mxrb/benchmark"
7
8
  require_relative "mxrb/project_lifecycle"
@@ -139,14 +140,18 @@ module Mxrb
139
140
  #
140
141
  # Mxrb.open("MyApp.mpr") { |p| puts p.modules.map(&:name) }
141
142
  #
142
- def self.open(path, readonly: true, &block)
143
- project = Model::Project.open(path, readonly: readonly)
144
- return project unless block
143
+ def self.open(path, readonly: true, &block) # rubocop:disable Metrics/MethodLength
144
+ return Model::Project.open(path, readonly: readonly) unless block
145
145
 
146
- begin
147
- block.call(project)
148
- ensure
149
- project.close
146
+ Progress.with("Loading #{File.basename(path)}") do |progress|
147
+ progress.update(detail: "opening model")
148
+ project = Model::Project.open(path, readonly: readonly)
149
+ begin
150
+ progress.update(detail: "processing model")
151
+ block.call(project)
152
+ ensure
153
+ project.close
154
+ end
150
155
  end
151
156
  end
152
157
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mxrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Moura
@@ -372,6 +372,7 @@ files:
372
372
  - lib/mxrb/oql/sql_server_workload_analyzer.rb
373
373
  - lib/mxrb/oql/workload_analyzer.rb
374
374
  - lib/mxrb/oql/workload_baseline.rb
375
+ - lib/mxrb/progress.rb
375
376
  - lib/mxrb/project_lifecycle.rb
376
377
  - lib/mxrb/protocols.rb
377
378
  - lib/mxrb/protocols/plan.rb