Class: Zonesync::Diff

Inherits:
Struct
  • Object
show all
Defined in:
lib/zonesync/diff.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fromObject

Returns the value of attribute from



4
5
6
# File 'lib/zonesync/diff.rb', line 4

def from
  @from
end

#toObject

Returns the value of attribute to



4
5
6
# File 'lib/zonesync/diff.rb', line 4

def to
  @to
end

Class Method Details

.call(from:, to:) ⇒ Object



5
6
7
# File 'lib/zonesync/diff.rb', line 5

def self.call(from:, to:)
  new(from, to).call
end

Instance Method Details

#callObject



9
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
48
49
50
51
# File 'lib/zonesync/diff.rb', line 9

def call
  # Group records by their primary key (name + type)
  from_by_key = from.group_by { |r| [r.name, r.type] }
  to_by_key = to.group_by { |r| [r.name, r.type] }

  operations = []

  # Process all keys that exist in from
  from_by_key.each do |key, from_records|
    to_records = to_by_key[key] || []

    if to_records.empty?
      # All records with this key were removed
      from_records.each { |r| operations << [:remove, [r]] }
    elsif from_records.length == 1 && to_records.length == 1
      # Single record with this key - check if it changed
      from_record = from_records.first
      to_record = to_records.first

      unless from_record == to_record
        operations << [:change, [from_record, to_record]]
      end
    else
      # Multiple records with same name+type, or count mismatch
      # Use set difference to find what was added/removed
      removed = from_records - to_records
      added = to_records - from_records

      removed.each { |r| operations << [:remove, [r]] }
      added.each { |r| operations << [:add, [r]] }
    end
  end

  # Process keys that only exist in to (new records)
  to_by_key.each do |key, to_records|
    unless from_by_key.key?(key)
      to_records.each { |r| operations << [:add, [r]] }
    end
  end

  # Sort operations (remove first)
  operations.sort_by { |op| op.first }.reverse
end