Class: SK::SDK::Sync

Inherits:
Object
  • Object
show all
Defined in:
lib/sk_sdk/sync.rb

Overview

Provide methods for mapping and syncing the fields of a remote to local object. Sync needs a local(left), a remote(right) object and a field-map(Array) to map the field-names between those two. Optionally you can add transition methods to convert the values from on side to the other.

When syncing the corresponding fields, the names are simply #send to each object.

After an object was updated you can check the #log for changes. Sync does not save anything, it only sets the field values on the other object.

Example

map =[
 [:name, :full_name, :'someClass.set_local_name', :'MyClass.set_remote_name'],
 [:street, :address1]
]
map = SK::SDK::Sync.new(@local_user, @remote_user, map)
map.update(:r)

Mapping Explained

Mappings are passed as an array:

[
 [:local_field_name, :remote_field_name, "MyClass.local_trans", "MyClass.remote_trans"]
 [:firstname, :first_name, :'MyClass.set_local_name', :'MyClass.set_remote_name']
]

A mapping consist of a local and the remote field(method) name. And might contain transition methods, if the value needs to be changed when set from one side to the other. Those methods will be called with the value from the other side.

local_obj.field = MyClass.local_trans(remote_obj.field)

Defined Under Namespace

Classes: Field

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(local_object, remote_object, field_map) ⇒ Sync

Returns a new instance of Sync.

Parameters:

  • local_object (Object)
  • remote_object (Object)
  • field_map (Array<String,Symbol>)

    assign local to remote field names



54
55
56
57
58
59
# File 'lib/sk_sdk/sync.rb', line 54

def initialize(local_object, remote_object, field_map)
  @l_obj = local_object
  @r_obj = remote_object
  self.fields = field_map
  @log = []
end

Instance Attribute Details

#fieldsArray<Field>

Returns mapped fields.

Returns:

  • (Array<Field>)

    mapped fields



45
46
47
# File 'lib/sk_sdk/sync.rb', line 45

def fields
  @fields
end

#l_objObject

Returns The local object.

Returns:

  • (Object)

    The local object



41
42
43
# File 'lib/sk_sdk/sync.rb', line 41

def l_obj
  @l_obj
end

#logArray<String> (readonly)

Returns log of field changes.

Returns:

  • (Array<String>)

    log of field changes



49
50
51
# File 'lib/sk_sdk/sync.rb', line 49

def log
  @log
end

#outdatedArray<Field> (readonly)

Returns outdated fields.

Returns:

  • (Array<Field>)

    outdated fields



47
48
49
# File 'lib/sk_sdk/sync.rb', line 47

def outdated
  @outdated
end

#r_objObject

Returns The remote object.

Returns:

  • (Object)

    The remote object



43
44
45
# File 'lib/sk_sdk/sync.rb', line 43

def r_obj
  @r_obj
end

Instance Method Details

#field(l_name) ⇒ Field

Find a field by its local name

Parameters:

  • l_name (Symbol)

    local name

Returns:



73
74
75
# File 'lib/sk_sdk/sync.rb', line 73

def field(l_name)
  fields.find{|fld| fld.l_name == l_name}
end

#outdated?Boolean

Check if the any of the fields are outdated Populates #outdated with local field names

Returns:

  • (Boolean)

    false if not outdated



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/sk_sdk/sync.rb', line 81

def outdated?
  @outdated = []
  fields.each do |fld|
    if fld.transition?
      # call r_trans method with local val to compare local with remote val
      # SomeTrans.remote_transfer_method( l_obj.field )
      virtual_l_val = eval "#{fld.r_trans} l_obj.send( fld.l_name )"
      @outdated << fld if virtual_l_val != r_obj.send( fld.r_name )
    else
      # no transfer method, directly compare values
      @outdated << fld if r_obj.send( fld.r_name ) != l_obj.send( fld.l_name )
    end
  end
  !@outdated.empty?
end

#update(side, flds = nil) ⇒ Object

Update a side with the values from the other side. Populates the log with updated fields and values.

Parameters:

  • side (String|Symbol)

    to update l OR r

  • flds (Array<Field>, nil) (defaults to: nil)

    fields to update, default nil update all fields

Raises:

  • (ArgumentError)


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/sk_sdk/sync.rb', line 111

def update(side, flds=nil)
  raise ArgumentError, 'The side to update must be :l or :r' unless [:l, :r].include?(side)
  target, source = (side==:l) ? [:l, :r] : [:r, :l]
  # use set field/s or update all
  flds ||= fields
  target_obj = self.send("#{target}_obj")
  source_obj = self.send("#{source}_obj")
  flds.each do |fld|
    target_name = fld.send("#{target}_name")
    source_name = fld.send("#{source}_name")
    # remember for log
    old_val = target_obj.send(target_name) rescue 'empty'
    # get new value through transfer method or direct
    new_val = if fld.transition?
                cur_trans = fld.send("#{target}_trans")
                eval "#{cur_trans} source_obj.send( source_name )"
              else
                source_obj.send( source_name )
              end
    target_obj.send( "#{target_name}=" , new_val )

    log << "#{target_name} was: #{old_val} updated from: #{source_name} with value: #{new_val}"
  end
end

#update_local_outdatedObject

update all local outdated fields with values from remote object



98
99
100
# File 'lib/sk_sdk/sync.rb', line 98

def update_local_outdated
  update(:l, @outdated) if outdated?
end

#update_remote_outdatedObject

update all remote outdated fields with values from local object



102
103
104
# File 'lib/sk_sdk/sync.rb', line 102

def update_remote_outdated
  update( :r, @outdated) if outdated?
end