Class: ActiveRecord::ConnectionAdapters::AbstractAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/ar-extensions/adapters/abstract_adapter.rb

Overview

:nodoc:

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_insert_value_sets(values, sql_size, max_bytes) ⇒ Object

:nodoc:



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 123

def self.get_insert_value_sets( values, sql_size, max_bytes ) # :nodoc:
  value_sets = []          
  arr, current_arr_values_size, current_size = [], 0, 0
  values.each_with_index do |val,i|
    comma_bytes = arr.size
    sql_size_thus_far = sql_size + current_size + val.size + comma_bytes
    if NO_MAX_PACKET == max_bytes or sql_size_thus_far <= max_bytes
      current_size += val.size            
      arr << val
    else
      value_sets << arr
      arr = [ val ]
      current_size = val.size
    end
    
    # if we're on the last iteration push whatever we have in arr to value_sets
    value_sets << arr if i == (values.size-1)
  end
  [ *value_sets ]
end

.sum_sizes(*objects) ⇒ Object

Returns the sum of the sizes of the passed in objects. This should probably be moved outside this class, but to where?



113
114
115
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 113

def self.sum_sizes( *objects ) # :nodoc:
  objects.inject( 0 ){|sum,o| sum += o.size }
end

Instance Method Details

#after_import_synchronize(instances) ⇒ Object

Synchronizes the passed in ActiveRecord instances with the records in the database by calling reload on each instance.



71
72
73
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 71

def after_import_synchronize( instances )
  instances.each { |e| e.reload }
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.



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
51
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 13

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 = self.class.sum_sizes( *values )
  
  # 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 = self.class.get_insert_value_sets( values, sql_size, 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_packetObject

Returns the maximum number of bytes that the server will allow in a single packet



119
120
121
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 119

def max_allowed_packet
  NO_MAX_PACKET
end

#multiple_value_sets_insert_sql(table_name, column_names, options) ⇒ Object

Generates the INSERT statement used in insert multiple value sets.



93
94
95
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 93

def multiple_value_sets_insert_sql(table_name, column_names, options) # :nodoc:
  "INSERT #{options[:ignore] ? 'IGNORE ':''}INTO #{table_name} (#{column_names.join(',')}) VALUES "
end

#next_value_for_sequence(sequence_name) ⇒ Object



7
8
9
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 7

def next_value_for_sequence(sequence_name)
  %{#{sequence_name}.nextval}
end

#post_sql_statements(table_name, options) ⇒ Object

Returns an array of post SQL statements given the passed in options.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 76

def post_sql_statements( table_name, options ) # :nodoc:
  post_sql_statements = []
  if options[:on_duplicate_key_update]
    post_sql_statements << sql_for_on_duplicate_key_update( table_name, options[:on_duplicate_key_update] )
  end

  #custom user post_sql
  post_sql_statements << options[:post_sql] if options[:post_sql]

  #with rollup
  post_sql_statements << rollup_sql if options[:rollup]

  post_sql_statements
end

#pre_sql_statements(options) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 53

def pre_sql_statements(options)
  sql = []
  sql << options[:pre_sql] if options[:pre_sql]
  sql << options[:command] if options[:command]
  sql << "IGNORE" if options[:ignore]

  #add keywords like IGNORE or DELAYED
  if options[:keywords].is_a?(Array)
    sql.concat(options[:keywords])
  elsif options[:keywords]
    sql << options[:keywords].to_s
  end

  sql
end

#values_sql_for_column_names_and_attributes(columns, array_of_attributes) ⇒ Object

Returns SQL the VALUES for an INSERT statement given the passed in columns and array_of_attributes.



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ar-extensions/adapters/abstract_adapter.rb', line 99

def values_sql_for_column_names_and_attributes( columns, array_of_attributes )   # :nodoc:
  values = []
  array_of_attributes.each do |arr|
    my_values = []
    arr.each_with_index do |val,j|
      my_values << quote( val, columns[j] )
    end
    values << my_values
  end   
  values_arr = values.map{ |arr| '(' + arr.join( ',' ) + ')' }
end