diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2017-10-22 01:55:59 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2017-11-07 22:28:57 +0100 |
commit | bda30182e0d6c0be9f89e2e9a4e8b8325ad7ccb7 (patch) | |
tree | 495a3690aebdcd8c29cf27996210790f9c166695 /lib | |
parent | 44be82dd18c372862c2421a1934ff816f7cccd97 (diff) | |
download | gitlab-ce-bda30182e0d6c0be9f89e2e9a4e8b8325ad7ccb7.tar.gz |
Add returning IDs to Gitlab::Database.bulk_insert
This adds the keyword argument "return_ids" to
Gitlab::Database.bulk_insert. When set to `true` (and PostgreSQL is
used) this method will return an Array of the IDs of the inserted rows,
otherwise it will return an empty Array.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/database.rb | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 43a00d6cedb..cd7b4c043da 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -108,20 +108,41 @@ module Gitlab end end - def self.bulk_insert(table, rows) + # Bulk inserts a number of rows into a table, optionally returning their + # IDs. + # + # table - The name of the table to insert the rows into. + # rows - An Array of Hash instances, each mapping the columns to their + # values. + # return_ids - When set to true the return value will be an Array of IDs of + # the inserted rows, this only works on PostgreSQL. + def self.bulk_insert(table, rows, return_ids: false) return if rows.empty? keys = rows.first.keys columns = keys.map { |key| connection.quote_column_name(key) } + return_ids = false if mysql? tuples = rows.map do |row| row.values_at(*keys).map { |value| connection.quote(value) } end - connection.execute <<-EOF + sql = <<-EOF INSERT INTO #{table} (#{columns.join(', ')}) VALUES #{tuples.map { |tuple| "(#{tuple.join(', ')})" }.join(', ')} EOF + + if return_ids + sql << 'RETURNING id' + end + + result = connection.execute(sql) + + if return_ids + result.values.map { |tuple| tuple[0].to_i } + else + [] + end end def self.sanitize_timestamp(timestamp) |