Revisions

gist: 7681 Download_button fork
public
Public Clone URL: git://gist.github.com/7681.git
Embed All Files: show embed
insert.rb #
1
2
3
4
5
6
7
8
9
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
module Insert
  def self.included(model)
    model.class_inheritable_accessor :insert_max_rows
    model.insert_max_rows = 1_000
    model.extend(ClassMethods)
  end
  
  module ClassMethods
    def insert(rows)
      return insert([rows]) unless rows.kind_of?(Array)
      return if rows.empty?
      
      provided_columns = rows.first.keys
      # unless rows.all? { |row| row.keys - provided_columns == [] && row.size == provided_columns.size }
      # raise "All rows must have same columns (#{ provided_columns.join(",") })"
      # end # this is slow
      
      timestamp_columns = column_names & %w( created_at created_on updated_at updated_on )
      insert_columns = provided_columns | timestamp_columns
      column_list = insert_columns.map { |c| connection.quote_column_name(c) }.join(",")
      time = Time.now
      default_values = timestamp_columns.inject({}) { |hsh,col| hsh.update col => time }
      
      prefix = "INSERT INTO #{quoted_table_name} (#{column_list}) VALUES "
      
      rows.each_slice(insert_max_rows) do |slice|
        query = prefix + slice.map { |row|
          values = default_values.merge(row)
          "(" << values.values_at(*insert_columns).map { |v| quote_value(v) }.join(",") << ")"
        }.join(",")
        connection.insert(query)
      end
    end
  end
end