From 15d3cc21f41af4b3caaae4f3586481effa77058f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 22 Mar 2011 09:18:01 -0700 Subject: [PATCH] pushing id insertion and prefetch primary keys down to Relation#insert --- .../abstract/database_statements.rb | 4 ++++ .../connection_adapters/sqlite_adapter.rb | 4 ++++ activerecord/lib/active_record/persistence.rb | 10 +--------- activerecord/lib/active_record/relation.rb | 17 ++++++++++++++--- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 5c1ce173c8..756c221fad 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -272,6 +272,10 @@ def insert_fixture(fixture, table_name) execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert' end + def null_insert_value + Arel.sql 'DEFAULT' + end + def empty_insert_statement_value "VALUES(DEFAULT)" end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 9ee6b88ab6..ae61d6ce94 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -336,6 +336,10 @@ def rename_column(table_name, column_name, new_column_name) #:nodoc: alter_table(table_name, :rename => {column_name.to_s => new_column_name.to_s}) end + def null_insert_value + Arel.sql 'NULL' + end + def empty_insert_statement_value "VALUES(NULL)" end diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index df7b22080c..17a64b6e86 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -270,17 +270,9 @@ def update(attribute_names = @attributes.keys) # Creates a record with values matching those of the instance attributes # and returns its id. def create - if id.nil? && connection.prefetch_primary_key?(self.class.table_name) - self.id = connection.next_sequence_value(self.class.sequence_name) - end - attributes_values = arel_attributes_values(!id.nil?) - new_id = if attributes_values.empty? - self.class.unscoped.insert connection.empty_insert_statement_value - else - self.class.unscoped.insert attributes_values - end + new_id = self.class.unscoped.insert attributes_values self.id ||= new_id diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 371403f510..8e545f9cad 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -30,15 +30,26 @@ def initialize(klass, table) end def insert(values) - im = arel.compile_insert values - im.into @table - primary_key_value = nil if primary_key && Hash === values primary_key_value = values[values.keys.find { |k| k.name == primary_key }] + + if !primary_key_value && connection.prefetch_primary_key?(klass.table_name) + primary_key_value = connection.next_sequence_value(klass.sequence_name) + values[klass.arel_table[klass.primary_key]] = primary_key_value + end + end + + im = arel.create_insert + im.into @table + + if values.empty? # empty insert + im.values = im.create_values [connection.null_insert_value], [] + else + im.insert values end @klass.connection.insert(