lib/ruby_sync/util/utilities.rb in rubysync-0.0.3 vs lib/ruby_sync/util/utilities.rb in rubysync-0.0.4
- old
+ new
@@ -25,16 +25,34 @@
File.delete(file) if File.exist?(file)
end
end
end
+class Object
+
+ # Make the log method globally available
+ def log
+ unless defined? @@log
+ @@log = Logger.new(STDOUT)
+ #@@log.level = Logger::DEBUG
+ @@log.datetime_format = "%H:%M:%S"
+ end
+ @@log
+ end
+end
+
+
# Generally useful methods
module RubySync
module Utilities
-
@@base_path=nil
+ # If not already an array, slip into one
+ def as_array o
+ (o.instance_of? Array)? o : [o]
+ end
+
# Perform an action and rescue any exceptions thrown, display the exception with the specified text
def with_rescue text
begin
yield
rescue Exception => exception
@@ -58,11 +76,11 @@
end
# Ensure that a given path exists as a directory
def ensure_dir_exists paths
- paths.as_array.each do |path|
+ as_array(paths).each do |path|
raise Exception.new("Can't create nil directory") unless path
if File.exist? path
unless File.directory? path
raise Exception.new("'#{path}' exists but is not a directory")
end
@@ -111,11 +129,11 @@
bp = File.expand_path(".")
last = nil
# Keep going up until we start repeating ourselves
while File.directory?(bp) && bp != last && bp != "/"
return bp if File.directory?("#{bp}/pipelines") &&
- File.directory?("#{bp}/connectors")
+ File.directory?("#{bp}/connectors")
last = bp
bp = File.expand_path("#{bp}/..")
end
return false
end
@@ -139,7 +157,82 @@
dir = "#{ENV[HOME]}/.rubysync"
Dir.mkdir(dir)
"#{dir}#{file}"
end
+ # Performs the given operations on the given record. The record is a
+ # Hash in which each key is a field name and each value is an array of
+ # values for that field.
+ # Operations is an Array of RubySync::Operation objects to be performed on the record.
+ def perform_operations operations, record={}, options={}
+ subjects = options[:subjects]
+ operations.each do |op|
+ unless op.instance_of? RubySync::Operation
+ log.warn "!!!!!!!!!! PROBLEM, DUMP FOLLOWS: !!!!!!!!!!!!!!"
+ p op
+ end
+ next if subjects and !subjects.include?(op.subject)
+ case op.type
+ when :add
+ if record[op.subject]
+ existing = as_array(record[op.subject])
+ next if existing == op.values # already same so ignore
+ (existing & op.values).empty? or
+ raise "Attempt to add duplicate elements to #{name}"
+ record[op.subject] = existing + op.values
+ else
+ record[op.subject] = op.values
+ end
+ when :replace
+ record[op.subject] = op.values
+ when :delete
+ if value == nil || value == "" || value == []
+ record.delete(op.subject)
+ else
+ record[op.subject] -= values
+ end
+ else
+ raise Exception.new("Unknown operation '#{op.type}'")
+ end
+ end
+ return record
+ end
+
+
+ # Filter operations to eliminate those that would have
+ # no effect on the record. Returns the resulting array
+ # of operations.
+ def effective_operations operations, record={}
+ effective = []
+ operations.each do |op|
+ existing = as_array(record[op.subject] || [])
+ case op.type
+ when :add
+ if existing.empty?
+ effective << op
+ else
+ next if existing == op.values # already same so ignore
+ effective << Operation.replace(op.subject, op.values)
+ end
+ when :replace
+ if existing.empty?
+ effective << Operation.add(op.subject, op.values)
+ else
+ next if existing == op.values
+ effective << op
+ end
+ when :delete
+ if [nil, "", []].include?(op.values)
+ effective << op if record[op.subject]
+ else
+ targets = op.values & existing
+ targets.empty? or effective << Operation.delete(op.subject, targets)
+ end
+ else
+ raise Exception.new("Unknown operation '#{op.type}'")
+ end
+ end
+ effective
+ end
+
end
-end
\ No newline at end of file
+end