Class: RubySync::Event

Inherits:
Object show all
Includes:
Utilities
Defined in:
lib/ruby_sync/event.rb

Overview

Represents a change of some type to a record in the source datastore. If the event type is :add or :modify then the payload will be an array of RubySync::Operations describing changes to the attributes of the record.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#as_array, #call_if_exists, #connector_called, #effective_operations, #ensure_dir_exists, #get_preference, #get_preference_file_path, #include_in_search_path, #log_progress, #perform_operations, #pipeline_called, #set_preference, #something_called, #with_rescue

Constructor Details

#initialize(type, source, source_path = nil, association = nil, payload = nil) ⇒ Event

Returns a new instance of Event.



79
80
81
82
83
84
85
86
# File 'lib/ruby_sync/event.rb', line 79

def initialize type, source, source_path=nil, association=nil, payload=nil
  self.type = type.to_sym
  self.source = source
  self.source_path = source_path
  self.association = make_association(association)
  self.payload = payload
  @target_path = nil
end

Instance Attribute Details

#associationObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def association
  @association
end

#payloadObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def payload
  @payload
end

#sourceObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def source
  @source
end

#source_pathObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def source_path
  @source_path
end

#targetObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def target
  @target
end

#target_pathObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def target_path
  @target_path
end

#typeObject

:delete, :add, :modify, :disassociate



49
50
51
# File 'lib/ruby_sync/event.rb', line 49

def type
  @type
end

Class Method Details

.add(source, source_path, association = nil, payload = nil) ⇒ Object



65
66
67
# File 'lib/ruby_sync/event.rb', line 65

def self.add source, source_path, association=nil, payload=nil
  self.new(:add, source, source_path, association, payload)
end

.delete(source, source_path, association = nil) ⇒ Object



61
62
63
# File 'lib/ruby_sync/event.rb', line 61

def self.delete source, source_path, association=nil
  self.new(:delete, source, source_path, association)
end

.disassociate(source, source_path, association = nil, payload = nil) ⇒ Object

Remove the association between the entry on the source and the associated entry (if any) on the target.



75
76
77
# File 'lib/ruby_sync/event.rb', line 75

def self.disassociate source, source_path, association=nil, payload=nil
  self.new(:disassociate, source, source_path, association, payload)
end

.force_resync(source) ⇒ Object



57
58
59
# File 'lib/ruby_sync/event.rb', line 57

def self.force_resync source
  self.new(:force_resync, source)
end

.modify(source, source_path, association = nil, payload = nil) ⇒ Object



69
70
71
# File 'lib/ruby_sync/event.rb', line 69

def self.modify source, source_path, association=nil, payload=nil
  self.new(:modify, source, source_path, association, payload)
end

Instance Method Details

#add_default(field_name, value) ⇒ Object

Add a value to a given subject unless it already sets a value



183
184
185
# File 'lib/ruby_sync/event.rb', line 183

def add_default field_name, value
  add_value(field_name.to_s, value) unless sets_value? field_name.to_s
end

#add_value(field_name, value) ⇒ Object



188
189
190
# File 'lib/ruby_sync/event.rb', line 188

def add_value field_name, value
  uncommitted_operations << Operation.new(:add, field_name.to_s, as_array(value))
end

#append(new_operations) ⇒ Object

Add one or more operations to the list to be performed. The operations won’t be added to the payload until commit_changes is called and won’t be added at all if rollback_changes is called first.



221
222
223
224
# File 'lib/ruby_sync/event.rb', line 221

def append new_operations
  uncommitted_operations
  @uncommitted_operations += as_array(new_operations)
end

#associated?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/ruby_sync/event.rb', line 101

def associated?
  self.association && self.association.context && self.association.key
end

#commit_changesObject



231
232
233
234
235
236
# File 'lib/ruby_sync/event.rb', line 231

def commit_changes
  if uncommitted_operations 
    @payload = uncommitted_operations
    @uncommitted_operations = nil
  end
end

#convert_to_addObject

Retrieves all known values for the record affected by this event and sets the event’s type to :add If the source connector doesn’t implement retrieve we’ll assume thats because it can’t and that it gave us all it had to start with.



117
118
119
120
121
122
123
124
# File 'lib/ruby_sync/event.rb', line 117

def convert_to_add
  log.info "Converting '#{type}' event to add"
  if (source.respond_to? :retrieve)
    full = source.retrieve(source_path)
    payload = full.payload
  end
  @type = :add
end

#convert_to_modifyObject



126
127
128
129
130
131
132
# File 'lib/ruby_sync/event.rb', line 126

def convert_to_modify
  log.info "Converting '#{type}' event to modify"
  @type = :modify
  @payload.each do |op|
    op.type = :replace
  end
end

#delete_when_blankObject



171
172
173
174
175
176
177
178
179
# File 'lib/ruby_sync/event.rb', line 171

def delete_when_blank
    @uncommitted_operations = uncommitted_operations.map do |op| 
      if op.sets_blank?
 @type == :modify ? op.same_but_as(:delete) : nil
   else
 op
   end
    end.compact
end

#drop_all_but_changes_to(*subjects) ⇒ Object



166
167
168
169
# File 'lib/ruby_sync/event.rb', line 166

def drop_all_but_changes_to *subjects
  subjects = subjects.flatten.collect {|s| s.to_s}
  @uncommitted_operations = uncommitted_operations.delete_if {|op| !subjects.include?(op.subject.to_s)}
end

#drop_changes_to(*subjects) ⇒ Object

Remove any operations from the payload that affect fields with the given key or keys (key can be a single field name or an array of field names).



160
161
162
163
164
# File 'lib/ruby_sync/event.rb', line 160

def drop_changes_to *subjects
  subjects = subjects.flatten.collect {|s| s.to_s}
  uncommitted_operations
  @uncommitted_operations = @uncommitted_operations.delete_if {|op| subjects.include? op.subject }
end

#hintObject



135
136
137
# File 'lib/ruby_sync/event.rb', line 135

def hint
"(#{source.name} => #{target.name}) #{source_path}"
end

#map(left, right = nil, &blk) ⇒ Object

Typically this will be called in the ‘transform_in’ and ‘transform_out’ blocks in a pipeline configuration.



240
241
242
243
244
245
246
247
248
249
250
# File 'lib/ruby_sync/event.rb', line 240

def map(left, right=nil, &blk)
  if right
    drop_changes_to left
    @uncommitted_operations = uncommitted_operations.map do |op|
      (op.subject.to_s == right.to_s)? op.same_but_on(left.to_s) : op
    end
  elsif blk and [:add, :modify].include? @type
    drop_changes_to left.to_s
    uncommitted_operations << RubySync::Operation.replace(left.to_s, blk.call) 
  end
end

#merge(other) ⇒ Object

Reduces the operations in this event to those that will alter the target record



107
108
109
110
111
# File 'lib/ruby_sync/event.rb', line 107

def merge other
#      other.type == :add or raise "Can only merge with add events"
#      record = perform_operations(other.payload)
  payload = effective_operations(@payload, other)
end

#place(&blk) ⇒ Object



252
253
254
# File 'lib/ruby_sync/event.rb', line 252

def place(&blk)
  self.target_path = blk.call
end

#retrieve_association(context) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ruby_sync/event.rb', line 88

def retrieve_association(context)
  if self.source.is_vault?
    self.association ||=  self.source.association_for(context, self.source_path)
  else
    if self.association # association key was supplied when the event was created
      self.association.context = context # just add the context
    else
      key = self.source.own_association_key_for(self.source_path)
      @association = Association.new(context, key)
    end
  end
end

#rollback_changesObject

Rollback any changes that



227
228
229
# File 'lib/ruby_sync/event.rb', line 227

def rollback_changes
  @uncommitted_operations = nil
end

#set_value(field_name, value) ⇒ Object



192
193
194
# File 'lib/ruby_sync/event.rb', line 192

def set_value field_name, value
  uncommitted_operations << Operation.new(:replace, field_name.to_s, as_array(value))
end

#sets_value?(subject, value = nil) ⇒ Boolean

True if this event will lead to the field name given being set. If value is non-nil then if it will lead to it being set to the value given. Note: This implementation is not completely accurate. Just looks at the last operation in the payload. A better implementation would look at all items that affect the named field to work out the value.

Returns:

  • (Boolean)


150
151
152
153
154
155
156
# File 'lib/ruby_sync/event.rb', line 150

def sets_value? subject, value=nil
  return false if @payload == nil
  @payload.reverse_each do |op|
    return true if op.subject == subject.to_s && (value == nil || op.values == as_array(value))
  end
  return false
end

#to_yaml_propertiesObject



140
141
142
# File 'lib/ruby_sync/event.rb', line 140

def to_yaml_properties
  %w{ @type @source_path @target_path @association @payload}
end

#uncommitted_operationsObject



208
209
210
211
# File 'lib/ruby_sync/event.rb', line 208

def uncommitted_operations
  @uncommitted_operations ||= @payload || []
  return @uncommitted_operations
end

#uncommitted_operations=(ops) ⇒ Object



213
214
215
# File 'lib/ruby_sync/event.rb', line 213

def uncommitted_operations= ops
  @uncommitted_operations = ops
end

#value_for(field_name, default = '') ⇒ Object Also known as: value_of



202
203
204
205
# File 'lib/ruby_sync/event.rb', line 202

def value_for field_name, default=''
  values = values_for field_name
  values[0] || default
end

#values_for(field_name, default = []) ⇒ Object Also known as: values_of



196
197
198
199
# File 'lib/ruby_sync/event.rb', line 196

def values_for field_name, default=[]
  values = perform_operations @payload, {}, :subjects=>[field_name.to_s]
  values[field_name.to_s] || default
end