Module: ActiveRecord::Import::MysqlAdapter
- Includes:
- ImportSupport, OnDuplicateKeyUpdateSupport
- Included in:
- ConnectionAdapters::MysqlAdapter, ConnectionAdapters::SeamlessDatabasePoolAdapter, EMMysql2Adapter, Mysql2Adapter
- Defined in:
- lib/activerecord-import/adapters/mysql_adapter.rb
Constant Summary collapse
- NO_MAX_PACKET =
0
- QUERY_OVERHEAD =
This was shown to be true for MySQL, but it’s not clear where the overhead is from.
8
Instance Method Summary collapse
-
#duplicate_key_update_error?(exception) ⇒ Boolean
return true if the statement is a duplicate key record error.
-
#insert_many(sql, values, *args) ⇒ Object
sql
can be a single string or an array. -
#max_allowed_packet ⇒ Object
Returns the maximum number of bytes that the server will allow in a single packet.
-
#sql_for_on_duplicate_key_update(table_name, *args) ⇒ Object
Returns a generated ON DUPLICATE KEY UPDATE statement given the passed in
args
. -
#sql_for_on_duplicate_key_update_as_array(table_name, arr) ⇒ Object
:nodoc:.
-
#sql_for_on_duplicate_key_update_as_hash(table_name, hsh) ⇒ Object
:nodoc:.
Methods included from OnDuplicateKeyUpdateSupport
#supports_on_duplicate_key_update?
Methods included from ImportSupport
Instance Method Details
#duplicate_key_update_error?(exception) ⇒ Boolean
return true if the statement is a duplicate key record error
99 100 101 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 99 def duplicate_key_update_error?(exception)# :nodoc: exception.is_a?(ActiveRecord::StatementInvalid) && exception.to_s.include?('Duplicate entry') end |
#insert_many(sql, values, *args) ⇒ Object
sql
can be a single string or an array. If it is an array all elements that are in position >= 1 will be appended to the final SQL.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 10 def insert_many( sql, values, *args ) # :nodoc: # the number of inserts default number_of_inserts = 0 base_sql,post_sql = if sql.is_a?( String ) [ sql, '' ] elsif sql.is_a?( Array ) [ sql.shift, sql.join( ' ' ) ] end 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 = values.sum {|value| value.bytesize } # the number of bytes (commas) it will take to comma separate our values comma_separated_bytes = values.size-1 # the total number of bytes required if this statement is one statement total_bytes = sql_size + values_in_bytes + comma_separated_bytes max = max_allowed_packet # if we can insert it all as one statement if NO_MAX_PACKET == max or total_bytes < max number_of_inserts += 1 sql2insert = base_sql + values.join( ',' ) + post_sql insert( sql2insert, *args ) else value_sets = ::ActiveRecord::Import::ValueSetsBytesParser.parse(values, :reserved_bytes => sql_size, :max_bytes => max) value_sets.each do |values| number_of_inserts += 1 sql2insert = base_sql + values.join( ',' ) + post_sql insert( sql2insert, *args ) end end number_of_inserts end |
#max_allowed_packet ⇒ Object
Returns the maximum number of bytes that the server will allow in a single packet
54 55 56 57 58 59 60 61 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 54 def max_allowed_packet # :nodoc: @max_allowed_packet ||= begin result = execute( "SHOW VARIABLES like 'max_allowed_packet';" ) # original Mysql gem responds to #fetch_row while Mysql2 responds to #first val = result.respond_to?(:fetch_row) ? result.fetch_row[1] : result.first[1] val.to_i end end |
#sql_for_on_duplicate_key_update(table_name, *args) ⇒ Object
Returns a generated ON DUPLICATE KEY UPDATE statement given the passed in args
.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 65 def sql_for_on_duplicate_key_update( table_name, *args ) # :nodoc: sql = ' ON DUPLICATE KEY UPDATE ' arg = args.first if arg.is_a?( Array ) sql << sql_for_on_duplicate_key_update_as_array( table_name, arg ) elsif arg.is_a?( Hash ) sql << sql_for_on_duplicate_key_update_as_hash( table_name, arg ) elsif arg.is_a?( String ) sql << arg else raise ArgumentError.new( "Expected Array or Hash" ) end sql end |
#sql_for_on_duplicate_key_update_as_array(table_name, arr) ⇒ Object
:nodoc:
80 81 82 83 84 85 86 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 80 def sql_for_on_duplicate_key_update_as_array( table_name, arr ) # :nodoc: results = arr.map do |column| qc = quote_column_name( column ) "#{table_name}.#{qc}=VALUES(#{qc})" end results.join( ',' ) end |
#sql_for_on_duplicate_key_update_as_hash(table_name, hsh) ⇒ Object
:nodoc:
88 89 90 91 92 93 94 95 96 |
# File 'lib/activerecord-import/adapters/mysql_adapter.rb', line 88 def sql_for_on_duplicate_key_update_as_hash( table_name, hsh ) # :nodoc: sql = ' ON DUPLICATE KEY UPDATE ' results = hsh.map do |column1, column2| qc1 = quote_column_name( column1 ) qc2 = quote_column_name( column2 ) "#{table_name}.#{qc1}=VALUES( #{qc2} )" end results.join( ',') end |