aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
diff options
context:
space:
mode:
authorBob Lail <bob.lailfamily@gmail.com>2019-03-05 13:16:44 -0600
committerDavid Heinemeier Hansson <david@loudthinking.com>2019-03-05 11:16:44 -0800
commit91ed21b304c468db8ce9fd830312c151432935d0 (patch)
tree354a329c8b7308a8762ef39a73e2ed1c30c51baa /activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
parentdb94f492c099db89746f945a522aa7e59ede97cb (diff)
downloadrails-91ed21b304c468db8ce9fd830312c151432935d0.tar.gz
rails-91ed21b304c468db8ce9fd830312c151432935d0.tar.bz2
rails-91ed21b304c468db8ce9fd830312c151432935d0.zip
Add insert_all to ActiveRecord models (#35077)
Adds a method to ActiveRecord allowing records to be inserted in bulk without instantiating ActiveRecord models. This method supports options for handling uniqueness violations by skipping duplicate records or overwriting them in an UPSERT operation. ActiveRecord already supports bulk-update and bulk-destroy actions that execute SQL UPDATE and DELETE commands directly. It also supports bulk-read actions through `pluck`. It makes sense for it also to support bulk-creation.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb22
1 files changed, 22 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 96f902792e..1aab36c865 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -109,6 +109,14 @@ module ActiveRecord
true
end
+ def supports_insert_on_duplicate_skip?
+ true
+ end
+
+ def supports_insert_on_duplicate_update?
+ true
+ end
+
def get_advisory_lock(lock_name, timeout = 0) # :nodoc:
query_value("SELECT GET_LOCK(#{quote(lock_name.to_s)}, #{timeout})") == 1
end
@@ -511,6 +519,20 @@ module ActiveRecord
end
end
+ def build_insert_sql(insert) # :nodoc:
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
+
+ if insert.skip_duplicates?
+ any_column = quote_column_name(insert.model.columns.first.name)
+ sql << " ON DUPLICATE KEY UPDATE #{any_column}=#{any_column}"
+ elsif insert.update_duplicates?
+ sql << " ON DUPLICATE KEY UPDATE "
+ sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
+ end
+
+ sql
+ end
+
private
def check_version
if version < "5.5.8"