Class: Mxrb::Semantic::DomainMutator

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/semantic/domain_mutator.rb

Overview

Factory for domain model mutation plans.

Usage:

project.plan_add_attribute("M.Product", name: :Price, type: :decimal)
project.plan_remove_attribute("M.Product/Price")
project.plan_change_attribute("M.Product/Price", type: :integer, default: "0")
project.plan_add_entity("M", name: :Tag, attributes: [{name: :Label, type: :string}])
project.plan_remove_entity("M.Product")

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project) ⇒ DomainMutator

Returns a new instance of DomainMutator.



293
294
295
# File 'lib/mxrb/semantic/domain_mutator.rb', line 293

def initialize(project)
  @project = project
end

Class Method Details

.entities_key(doc) ⇒ Object



360
361
362
# File 'lib/mxrb/semantic/domain_mutator.rb', line 360

def self.entities_key(doc)
  doc.key?("entities") ? "entities" : "Entities"
end

.extract_attributes(entity_doc) ⇒ Object



364
365
366
# File 'lib/mxrb/semantic/domain_mutator.rb', line 364

def self.extract_attributes(entity_doc)
  IO::BsonCodec.parse_array(entity_doc["attributes"] || entity_doc["Attributes"])[:items]
end

.extract_entities(doc) ⇒ Object

── BSON helpers used by plans ──────────────────────────────────────────



356
357
358
# File 'lib/mxrb/semantic/domain_mutator.rb', line 356

def self.extract_entities(doc)
  IO::BsonCodec.parse_array(doc["entities"] || doc["Entities"])[:items]
end

.put_attributes(entity_doc, attrs) ⇒ Object



368
369
370
371
# File 'lib/mxrb/semantic/domain_mutator.rb', line 368

def self.put_attributes(entity_doc, attrs)
  key = entity_doc.key?("attributes") ? "attributes" : "Attributes"
  entity_doc[key] = IO::BsonCodec.build_array(attrs)
end

.put_entity(domain_doc, entity_id, updated_entity_doc) ⇒ Object



373
374
375
376
377
378
379
380
# File 'lib/mxrb/semantic/domain_mutator.rb', line 373

def self.put_entity(domain_doc, entity_id, updated_entity_doc)
  key      = entities_key(domain_doc)
  entities = IO::BsonCodec.parse_array(domain_doc[key])[:items]
  updated  = entities.map do |e|
    IO::BsonCodec.extract_id(e["$ID"] || e["\$ID"]) == entity_id ? updated_entity_doc : e
  end
  domain_doc[key] = IO::BsonCodec.build_array(updated)
end

Instance Method Details

#plan_add_attribute(entity_qname, name:, type: :string, default: nil, documentation: nil) ⇒ Object



297
298
299
300
301
302
303
304
# File 'lib/mxrb/semantic/domain_mutator.rb', line 297

def plan_add_attribute(entity_qname, name:, type: :string, default: nil, documentation: nil)
  mod_name, entity_name, dm_id, entity_id = resolve_entity(entity_qname)
  AddAttributePlan.new(
    project: @project, module_name: mod_name, entity_name: entity_name,
    entity_id: entity_id, domain_unit_id: dm_id,
    attribute_def: { name: name.to_s, type: type, default: default, documentation: documentation.to_s }
  )
end

#plan_add_entity(module_qname, name:, attributes: [], documentation: nil, non_persistent: false) ⇒ Object



333
334
335
336
337
338
339
340
341
342
# File 'lib/mxrb/semantic/domain_mutator.rb', line 333

def plan_add_entity(module_qname, name:, attributes: [], documentation: nil, non_persistent: false)
  mod_name, dm_id = resolve_module(module_qname)
  AddEntityPlan.new(
    project: @project, module_name: mod_name, domain_unit_id: dm_id,
    entity_def: {
      name: name.to_s, attributes: attributes,
      documentation: documentation.to_s, non_persistent: non_persistent
    }
  )
end

#plan_change_attribute(attribute_qname, type: nil, default: nil, documentation: nil) ⇒ Object

Raises:

  • (ArgumentError)


318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/mxrb/semantic/domain_mutator.rb', line 318

def plan_change_attribute(attribute_qname, type: nil, default: nil, documentation: nil)
  mod_name, entity_name, dm_id, entity_id, attr_name = resolve_attribute(attribute_qname)
  updates = {}
  updates[:type]          = type          if type
  updates[:default]       = default       unless default.nil?
  updates[:documentation] = documentation if documentation
  raise ArgumentError, "plan_change_attribute: no changes specified" if updates.empty?

  ChangeAttributePlan.new(
    project: @project, module_name: mod_name, entity_name: entity_name,
    entity_id: entity_id, domain_unit_id: dm_id,
    attribute_name: attr_name, updates: updates
  )
end

#plan_remove_attribute(attribute_qname) ⇒ Object



306
307
308
309
310
311
312
313
314
315
316
# File 'lib/mxrb/semantic/domain_mutator.rb', line 306

def plan_remove_attribute(attribute_qname)
  mod_name, entity_name, dm_id, entity_id, attr_name = resolve_attribute(attribute_qname)
  # Attribute qualified names in the semantic index use dots: M.Entity.Attr
  artifact = @project.find_artifact("#{mod_name}.#{entity_name}.#{attr_name}", kind: :attribute)
  incoming = artifact ? @project.references_to(artifact) : []
  RemoveAttributePlan.new(
    project: @project, module_name: mod_name, entity_name: entity_name,
    entity_id: entity_id, domain_unit_id: dm_id,
    attribute_name: attr_name, incoming: incoming
  )
end

#plan_remove_entity(entity_qname) ⇒ Object



344
345
346
347
348
349
350
351
352
# File 'lib/mxrb/semantic/domain_mutator.rb', line 344

def plan_remove_entity(entity_qname)
  mod_name, entity_name, dm_id, entity_id = resolve_entity(entity_qname)
  artifact = @project.find_artifact(entity_qname, kind: :entity)
  incoming = artifact ? @project.references_to(artifact).reject { _1.source.qualified_name == entity_qname } : []
  RemoveEntityPlan.new(
    project: @project, module_name: mod_name, entity_name: entity_name,
    entity_id: entity_id, domain_unit_id: dm_id, incoming: incoming
  )
end