aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorDoug Cole <doug@estately.com>2012-03-31 13:38:11 -0700
committerDoug Cole <doug@estately.com>2012-03-31 17:14:28 -0700
commitf09bb33bb534fe2e729e292c8ac6b0e2ffdcea2a (patch)
treef6835824b94cbb6185dfc0b051be9be4a24cdbee /activerecord/lib/active_record
parent67b000ebd59a9fd90abf77bd3d6f32f188b03f1f (diff)
downloadrails-f09bb33bb534fe2e729e292c8ac6b0e2ffdcea2a.tar.gz
rails-f09bb33bb534fe2e729e292c8ac6b0e2ffdcea2a.tar.bz2
rails-f09bb33bb534fe2e729e292c8ac6b0e2ffdcea2a.zip
add use_returning as a postgresql connection config
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb50
2 files changed, 48 insertions, 6 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 174450eb00..f08040a1a7 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -59,7 +59,7 @@ module ActiveRecord
# Executes insert +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is the logged along with
# the executed +sql+ statement.
- def exec_insert(sql, name, binds)
+ def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
exec_query(sql, name, binds)
end
@@ -87,7 +87,7 @@ module ActiveRecord
# passed in as +id_value+.
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
- value = exec_insert(sql, name, binds)
+ value = exec_insert(sql, name, binds, pk, sequence_name)
id_value || last_inserted_id(value)
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 10a178e369..2509fe0490 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -406,6 +406,7 @@ module ActiveRecord
initialize_type_map
@local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
+ self.use_returning = true
end
# Clears the prepared statements cache.
@@ -667,8 +668,11 @@ module ActiveRecord
pk = primary_key(table_ref) if table_ref
end
- if pk
+ if pk && use_returning?
select_value("#{sql} RETURNING #{quote_column_name(pk)}")
+ elsif pk
+ super
+ last_insert_id_value(sequence_name || default_sequence_name(table_ref, pk))
else
super
end
@@ -783,11 +787,35 @@ module ActiveRecord
pk = primary_key(table_ref) if table_ref
end
- sql = "#{sql} RETURNING #{quote_column_name(pk)}" if pk
+ if pk && use_returning?
+ sql = "#{sql} RETURNING #{quote_column_name(pk)}"
+ end
[sql, binds]
end
+ def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
+ val = exec_query(sql, name, binds)
+ if !use_returning? && pk
+ if sequence_name
+ last_insert_id_value(sequence_name)
+ else
+ table_ref = extract_table_ref_from_insert_sql(sql)
+ sequence_name = default_sequence_name(table_ref, pk)
+ return val unless sequence_name
+ last_insert_id(sequence_name)
+ end
+ else
+ val
+ end
+ end
+
+ def last_inserted_id(result)
+ return result if result.kind_of?(Integer)
+ row = result.rows.first
+ row && row.first
+ end
+
# Executes an UPDATE query and returns the number of affected tuples.
def update_sql(sql, name = nil)
super.cmd_tuples
@@ -1028,7 +1056,9 @@ module ActiveRecord
# Returns the sequence name for a table's primary key or some other specified key.
def default_sequence_name(table_name, pk = nil) #:nodoc:
- serial_sequence(table_name, pk || 'id').split('.').last
+ result = serial_sequence(table_name, pk || 'id')
+ return nil unless result
+ result.split('.').last
rescue ActiveRecord::StatementInvalid
"#{table_name}_#{pk || 'id'}_seq"
end
@@ -1236,6 +1266,14 @@ module ActiveRecord
end
end
+ def use_returning=(val)
+ @use_returning = val
+ end
+
+ def use_returning?
+ @use_returning
+ end
+
protected
# Returns the version of the connected PostgreSQL server.
def postgresql_version
@@ -1365,8 +1403,12 @@ module ActiveRecord
# Returns the current ID of a table's sequence.
def last_insert_id(sequence_name) #:nodoc:
+ Integer(last_insert_id_value(sequence_name))
+ end
+
+ def last_insert_id_value(sequence_name) #:nodoc:
r = exec_query("SELECT currval($1)", 'SQL', [[nil, sequence_name]])
- Integer(r.rows.first.first)
+ r.rows.first.first
end
# Executes a SELECT query and returns the results, performing any data type