diff --git a/lib/granblue/data_importer.rb b/lib/granblue/data_importer.rb index 8e16a0b..1be5b54 100644 --- a/lib/granblue/data_importer.rb +++ b/lib/granblue/data_importer.rb @@ -29,11 +29,22 @@ module Granblue importer = create_importer(filename, file_path) return unless importer - log_info "Processing #{filename} in #{@test_mode ? 'TEST' : 'LIVE'} mode..." - new_records = importer.import - log_import(filename) + log_info "Processing #{filename} in #{@test_mode ? 'test' : 'live'} mode..." + result = importer.import + log_import(filename, result) log_info "Successfully processed #{filename}" - new_records + result + end + + def log_import_results(result) + return unless @verbose + + result[:new].each do |type, ids| + log_info "Created #{ids.size} new #{type.pluralize}" if ids.any? + end + result[:updated].each do |type, ids| + log_info "Updated #{ids.size} existing #{type.pluralize}" if ids.any? + end end def create_importer(filename, file_path) @@ -60,9 +71,19 @@ module Granblue DataVersion.imported?(filename) end - def log_import(filename) + def log_import(filename, result = nil) return if @test_mode + DataVersion.mark_as_imported(filename) + + if result && @verbose + result[:new].each do |type, ids| + log_info "Created #{ids.size} new #{type.pluralize}" if ids.any? + end + result[:updated].each do |type, ids| + log_info "Updated #{ids.size} existing #{type.pluralize}" if ids.any? + end + end end def log_operation(operation) diff --git a/lib/granblue/importers/base_importer.rb b/lib/granblue/importers/base_importer.rb index 0b42908..2c86e34 100644 --- a/lib/granblue/importers/base_importer.rb +++ b/lib/granblue/importers/base_importer.rb @@ -3,7 +3,7 @@ module Granblue module Importers class BaseImporter - attr_reader :new_records + attr_reader :new_records, :updated_records def initialize(file_path, test_mode: false, verbose: false, logger: nil) @file_path = file_path @@ -11,36 +11,65 @@ module Granblue @verbose = verbose @logger = logger @new_records = Hash.new { |h, k| h[k] = [] } + @updated_records = Hash.new { |h, k| h[k] = [] } end def import CSV.foreach(@file_path, headers: true) do |row| import_row(row) end - @new_records + { new: @new_records, updated: @updated_records } end private def import_row(row) attributes = build_attributes(row) - record = create_record(attributes) - track_new_record(record) if record + record = find_or_create_record(attributes) + track_record(record, attributes) if record end - def create_record(attributes) - if @test_mode - log_test_creation(attributes) - nil + def find_or_create_record(attributes) + existing_record = model_class.find_by(granblue_id: attributes[:granblue_id]) + + if existing_record + if @test_mode + log_test_update(existing_record, attributes) + nil + else + update_record(existing_record, attributes) + end else - model_class.create!(attributes) + if @test_mode + log_test_creation(attributes) + nil + else + model_class.create!(attributes) + end end end - def track_new_record(record) + def update_record(record, attributes) + changed = attributes.any? { |key, value| record[key] != value } + record.update!(attributes) if changed + record + end + + def track_record(record, attributes) type = model_class.name.demodulize.downcase - @new_records[type] << record.granblue_id - log_new_record(record) if @verbose + + # For existing records, check if any attributes were actually changed + if record.persisted? && record.previous_changes.any? + @updated_records[type] << record.granblue_id + log_updated_record(record) if @verbose + elsif !record.persisted? + @new_records[type] << record.granblue_id + log_new_record(record) if @verbose + end + end + + def log_test_update(record, attributes) + @logger&.send(:log_operation, "Update #{model_class.name} #{record.granblue_id}: #{attributes.inspect}") end def log_test_creation(attributes) @@ -51,33 +80,43 @@ module Granblue puts "Created #{model_class.name} with ID: #{record.granblue_id}" end + def log_updated_record(record) + puts "Updated #{model_class.name} with ID: #{record.granblue_id}" + end + def parse_value(value) return nil if value.nil? || value.strip.empty? + value end def parse_integer(value) return nil if value.nil? || value.strip.empty? + value.to_i end def parse_float(value) return nil if value.nil? || value.strip.empty? + value.to_f end def parse_boolean(value) return nil if value.nil? || value.strip.empty? + value == 'true' end def parse_date(date_str) return nil if date_str.nil? || date_str.strip.empty? + Date.parse(date_str) rescue nil end def parse_array(array_str) return [] if array_str.nil? || array_str.strip.empty? + array_str.tr('{}', '').split(',') end diff --git a/lib/granblue/post_deployment_manager.rb b/lib/granblue/post_deployment_manager.rb index d7244e8..c24086e 100644 --- a/lib/granblue/post_deployment_manager.rb +++ b/lib/granblue/post_deployment_manager.rb @@ -12,6 +12,7 @@ class PostDeploymentManager @verbose = options.fetch(:verbose, false) @storage = options.fetch(:storage, :both) @new_records = Hash.new { |h, k| h[k] = [] } + @updated_records = Hash.new { |h, k| h[k] = [] } end def run @@ -33,17 +34,26 @@ class PostDeploymentManager end def process_imports(importer) - importer.process_all_files do |file_records| - file_records.each do |type, ids| + importer.process_all_files do |result| + result[:new].each do |type, ids| @new_records[type].concat(ids) end + result[:updated].each do |type, ids| + @updated_records[type].concat(ids) + end end end def display_import_summary log_step "\nImport Summary:" - @new_records.each do |type, ids| - puts "#{type.capitalize}: #{ids.size} new records" + display_record_summary("New", @new_records) + display_record_summary("Updated", @updated_records) + end + + def display_record_summary(label, records) + records.each do |type, ids| + next if ids.empty? + puts "#{type.capitalize}: #{ids.size} #{label.downcase} records" puts "IDs: #{ids.inspect}" if @verbose end end @@ -52,15 +62,16 @@ class PostDeploymentManager return if all_records_empty? if @test_mode - log_step "\nTEST MODE: Would download images for new records..." + log_step "\nTEST MODE: Would download images for new and updated records..." else - log_step "\nDownloading images for new records..." + log_step "\nDownloading images for new and updated records..." end - @new_records.each do |type, ids| - next if ids.empty? - - download_type_images(type, ids) + [@new_records, @updated_records].each do |records| + records.each do |type, ids| + next if ids.empty? + download_type_images(type, ids) + end end end @@ -94,7 +105,7 @@ class PostDeploymentManager end def all_records_empty? - @new_records.values.all?(&:empty?) + @new_records.values.all?(&:empty?) && @updated_records.values.all?(&:empty?) end def log_step(message)