Module: Opencdd::Database::Mutations

Included in:
Opencdd::Database
Defined in:
lib/opencdd/database/mutations.rb

Overview

Mutations: rename, merge, apply_change_request, remove, apply_view_control, and back-reference rewriting.

Constant Summary collapse

REFERENCE_VALUE_KINDS =
%i[identifier_ref set_of_refs class_ref].freeze

Instance Method Summary collapse

Instance Method Details

#apply_change_request(cr, removals: []) ⇒ Object

Raises:

  • (TypeError)


56
57
58
59
60
61
62
# File 'lib/opencdd/database/mutations.rb', line 56

def apply_change_request(cr, removals: [])
  raise TypeError, "apply_change_request expects a Opencdd::Database" unless cr.is_a?(Opencdd::Database)
  cr.entities.each { |e| add_entity(e) }
  Array(removals).each { |r| remove_by_irdi(r) }
  finalize!
  self
end

#apply_view_control(klass, view_control) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/opencdd/database/mutations.rb', line 72

def apply_view_control(klass, view_control)
  properties = effective_properties.for(klass).to_a
  return properties unless view_control.is_a?(Opencdd::ViewControl)

  controlled = view_control.controlled_class_irdis
  k = coerce_entity(klass)
  return properties unless k.is_a?(Opencdd::Klass) && controlled.include?(k.irdi)

  shown = view_control.shown_property_irdis
  lookup = properties.each_with_object({}) { |p, h| h[p.irdi] = p }
  shown.filter_map { |irdi| lookup[irdi] }
end

#merge(other) ⇒ Object

Raises:

  • (TypeError)


49
50
51
52
53
54
# File 'lib/opencdd/database/mutations.rb', line 49

def merge(other)
  raise TypeError, "merge expects a Opencdd::Database" unless other.is_a?(Opencdd::Database)
  other.entities.each { |e| add_entity(e) }
  finalize!
  self
end

#remove_by_irdi(ref) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/opencdd/database/mutations.rb', line 64

def remove_by_irdi(ref)
  irdi = ref.is_a?(Opencdd::IRDI) ? ref : Opencdd::IRDI.parse(ref.to_s)
  return unless irdi
  remove_entity_by_irdi!(irdi)
  @entity_sources.delete(irdi)
  self
end

#rename_entity(old_code, new_code) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/opencdd/database/mutations.rb', line 10

def rename_entity(old_code, new_code)
  old_code_s = old_code.to_s
  new_code_s = new_code.to_s
  return self if old_code_s == new_code_s

  target = find_by_code(old_code_s)
  return self unless target

  clash = find_by_code(new_code_s)
  if clash && clash.irdi != target.irdi
    warn "Cannot rename #{old_code_s}#{new_code_s}: target code already in use by #{clash.irdi}"
    return self
  end

  old_irdi = target.irdi
  new_irdi = old_irdi.with_code(new_code_s)

  @entities_by_irdi.delete(old_irdi)
  @entities_by_code[old_code_s].delete(target)

  ref_property_ids = Opencdd::PropertyIds::REGISTRY.select do |_, e|
    REFERENCE_VALUE_KINDS.include?(e.value_kind)
  end.keys

  entities.each do |entity|
    rewrite_back_references!(entity, old_irdi, new_irdi, ref_property_ids)
  end

  code_pid = target.class.default_code_property_id(target.meta_class_irdi)
  target.replace_code_value!(code_pid, new_code_s)
  target.replace_irdi!(new_irdi)

  @entities_by_irdi[new_irdi] = target
  @entities_by_code[new_code_s] << target

  rebuild_symbol_table!
  self
end