diff --git a/lib/data_patcher.rb b/lib/data_patcher.rb index e69de29..37a58d4 100644 --- a/lib/data_patcher.rb +++ b/lib/data_patcher.rb @@ -0,0 +1,32 @@ +require 'activesupport' + +class DataPatcher + + def analyze_record(key, attributes) + existing = Item.find_by_asin(attributes[key]) + if existing + existing_attributes = existing.attributes.dup.symbolize_keys.except(:id) + diff = attributes.diff(existing_attributes) + # always include the key in the mix so that a look-up is possible when applying the patch + unless diff.empty? + patch[:modified] ||= [] + diff[key] = attributes[key] + patch[:modified] << diff + end + else + patch[:added] ||= [] + patch[:added] << attributes + end + end + + # test commodity - remove ? + def analyze_records(key, records) + records.each { |record| analyze_record(key, record) } + end + + def patch + @patch ||= {} + end + +end + diff --git a/spec/data_patcher_spec.rb b/spec/data_patcher_spec.rb index b5dd969..091677e 100644 --- a/spec/data_patcher_spec.rb +++ b/spec/data_patcher_spec.rb @@ -1,7 +1,44 @@ require File.dirname(__FILE__) + '/spec_helper' -describe "DataPatcher" do - it "fails" do - fail "hey buddy, you should probably rename this file and start specing for real" +describe DataPatcher do + + before(:each) do + @existing_item_1 = { + :title => "Mastering Data Warehouse Aggregates", + :summary => "The first book to provide in-depth coverage of star schema aggregates...", + :asin => "0471777099" } + @existing_item_2 = { + :title => "The Data Warehouse ETL Toolkit", + :summary => "The single most authoritative guide on the most difficult phase of building a data warehouse", + :asin => "0764567578" } + @existing_items = [@existing_item_1, @existing_item_2] + Item.delete_all + Item.create!(@existing_item_1) + Item.create!(@existing_item_2) + @patcher = DataPatcher.new end + + def patcher + @patcher + end + + it "provides an addition patch including the key and the attributes" do + patcher.analyze_records(:asin, @existing_items) + patcher.analyze_record(:asin, { :asin => "123", :title => "Hello", :summary => "The best of hello world" } ) + patcher.patch.should == { + :added => [{ :asin => "123", :title => "Hello", :summary => "The best of hello world" }] + } + end + + it "provides a modification patch including the key and updated attributes" do + patcher.analyze_records(:asin, @existing_items) + patcher.analyze_record(:asin, { + :asin => "0471777099", # key + :title => "Mastering Data Warehouse Aggregates (Hard cover)", # changed data + :summary => "The first book to provide in-depth coverage of star schema aggregates..."}) # unchanged data + patcher.patch.should == { + :modified => [{ :asin => "0471777099", :title => "Mastering Data Warehouse Aggregates (Hard cover)"}] + } + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d53253c..c915b4a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'rubygems' require 'spec' $LOAD_PATH.unshift(File.dirname(__FILE__)) @@ -7,3 +8,23 @@ Spec::Runner.configure do |config| end + +require 'active_record' +require 'active_record/connection_adapters/mysql_adapter' + +require 'yaml' + +# database configuration and fixtures setup + +ActiveRecord::Base.establish_connection(YAML.load(IO.read(File.dirname(__FILE__) + "/database.yml"))) + +# Load Models +Dir[File.dirname(__FILE__) + "/models/*.rb"].sort.each do |file| + require file.gsub(/\.rb$/, '') +end + +# Set up database tables and records +Dir[File.dirname(__FILE__) + "/db/migrations/*.rb"].each do |file| + require file.gsub(/\.rb$/, '') +end +