From 8d20594f123538511284b4de11462be7c28cf207 Mon Sep 17 00:00:00 2001 From: Ben Woosley Date: Wed, 4 May 2011 22:42:00 -0500 Subject: [PATCH] Replace #sum_sizes with calls to ActiveSupport #sum, as splatting large numbers of values is resource intensive andcan cause stack overflows of the sort 'SystemStackError: stack level too deep' --- lib/activerecord-import/adapters/abstract_adapter.rb | 8 +------- test/support/mysql/import_examples.rb | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/activerecord-import/adapters/abstract_adapter.rb b/lib/activerecord-import/adapters/abstract_adapter.rb index 20f5167..5f38001 100644 --- a/lib/activerecord-import/adapters/abstract_adapter.rb +++ b/lib/activerecord-import/adapters/abstract_adapter.rb @@ -3,12 +3,6 @@ module ActiveRecord::Import::AbstractAdapter QUERY_OVERHEAD = 8 #This was shown to be true for MySQL, but it's not clear where the overhead is from. module ClassMethods - # Returns the sum of the sizes of the passed in objects. This should - # probably be moved outside this class, but to where? - def sum_sizes( *objects ) # :nodoc: - objects.inject( 0 ){ |sum,o| sum += o.bytesize } - end - def get_insert_value_sets( values, sql_size, max_bytes ) # :nodoc: value_sets = [] arr, current_arr_values_size, current_size = [], 0, 0 @@ -51,7 +45,7 @@ module ActiveRecord::Import::AbstractAdapter sql_size = QUERY_OVERHEAD + base_sql.size + post_sql.size # the number of bytes the requested insert statement values will take up - values_in_bytes = self.class.sum_sizes( *values ) + values_in_bytes = values.sum {|value| value.bytesize } # the number of bytes (commas) it will take to comma separate our values comma_separated_bytes = values.size-1 diff --git a/test/support/mysql/import_examples.rb b/test/support/mysql/import_examples.rb index 83e34c7..cf05299 100644 --- a/test/support/mysql/import_examples.rb +++ b/test/support/mysql/import_examples.rb @@ -9,7 +9,7 @@ def should_support_mysql_import_functionality "('7','8','9')" ] adapter = ActiveRecord::Base.connection.class - values_size_in_bytes = adapter.sum_sizes( *values ) + values_size_in_bytes = values.sum {|value| value.bytesize } base_sql_size_in_bytes = 15 max_bytes = 30 @@ -38,7 +38,7 @@ def should_support_mysql_import_functionality base_sql_size_in_bytes = 15 max_bytes = 26 - values_size_in_bytes = adapter.sum_sizes( *values ) + values_size_in_bytes = values.sum {|value| value.bytesize } value_sets = adapter.get_insert_value_sets( values, base_sql_size_in_bytes, max_bytes ) assert_equal 2, value_sets.size, 'Two value sets were expected!'