lib/db/sync.rb in db-sync-0.0.4 vs lib/db/sync.rb in db-sync-0.0.5

- old
+ new

@@ -7,107 +7,124 @@ module Db # Databse Sync class Sync include ActiveSupport::Configurable - def self.sync_up + def log + @log ||= [] + end + + def sync_up(commit = true) + @log = [] # TODO: change to row by row loading working_tables.each do |table| table_model = data_model(table) fail 'Tables without id are not supported!' unless table_model.include_id? data = File.read(table_filename(table)) all_records = YAML.load(data) - current_records = table_model.records.map(&:attributes) + current_records = table_model.records diff = Db::Sync::Diff.new(current_records, all_records, table_model.pkey) - insert_records(table, diff.inserts) - delete_records(table, diff.deletes) - update_records(table, diff.updates) + insert_records(table, diff.inserts, commit) + delete_records(table, diff.deletes, commit) + update_records(table, diff.updates, commit) end end - def self.insert_records(table, inserts) + def insert_records(table, inserts, commit = true) inserts.each do |record| + log << "[#{table}] INSERT #{record}" + next unless commit + insert_manager = Arel::InsertManager.new(ActiveRecord::Base) arel_model = Arel::Table.new(table) insert_data = record.map do |key, value| [arel_model[key], value] end + insert_manager.insert(insert_data) # print "#{insert_manager.to_sql}\n" ActiveRecord::Base.connection.execute(insert_manager.to_sql) end end - def self.delete_records(table, deletes) + def delete_records(table, deletes, commit = false) arel_model = Arel::Table.new(table) deletes.each do |delete_params| + log << "[#{table}] DELETE #{delete_params}" + next unless commit + delete_manager = Arel::DeleteManager.new(ActiveRecord::Base) delete_manager.from(arel_model) delete_data = delete_params.map do |key, value| [arel_model[key].eq(value)] end + delete_manager.where(delete_data) # print "#{delete_manager.to_sql}\n" ActiveRecord::Base.connection.execute(delete_manager.to_sql) end end - def self.update_records(table, updates) + def update_records(table, updates, commit = false) arel_model = Arel::Table.new(table) updates.each do |update| + log << "[#{table}] UPDATE #{update[:key]} with #{update[:changes]}" + next unless commit + update_manager = Arel::UpdateManager.new(ActiveRecord::Base) update_key = update[:key].map do |key, value| [arel_model[key].eq(value)] end update_changes = update[:changes].map do |key, value| [arel_model[key], value] end + update_manager.table(arel_model).where(update_key).set(update_changes) # print "#{update_manager.to_sql}\n" ActiveRecord::Base.connection.execute(update_manager.to_sql) end end - def self.sync_down + def sync_down # TODO: change to row by row saving working_tables.each do |table| File.open(table_filename(table), 'w') do |f| current_records = table_model_records(table) f << current_records.to_yaml end end end - def self.table_model_records(table) + def table_model_records(table) # TODO: Some kind of paging table_model = data_model(table) - table_model.records.map(&:attributes) + table_model.records end - def self.working_tables + def working_tables config.tables || all_tables end - def self.all_tables + def all_tables ActiveRecord::Base.connection.tables.reject do |table| %w(schema_info, schema_migrations).include?(table) end end - def self.table_filename(table) + def table_filename(table) # TODO: change data with custom dir File.join(Rails.root || '.', 'db', 'data', "#{table}.yml") end - def self.configure + def configure yield(config) end - def self.data_model(table) + def data_model(table) result = Class.new(Db::Sync::Model) result.table_name = table result end