summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2017-05-05 14:43:22 +0200
committerJames Lopez <james@jameslopez.es>2017-05-05 14:43:22 +0200
commit606584c115d5f7a22f3b5c7e0ac6803b96fe999e (patch)
tree26c2cd9588fcef95e9b7e5f07b1354fff2b6900e
parent9ec39568c5284f5a3a17a342d12f87befb6cfb4c (diff)
downloadgitlab-ce-606584c115d5f7a22f3b5c7e0ac6803b96fe999e.tar.gz
bulk insert FTW - This would introduce more complexity, but should be faster
-rw-r--r--app/services/projects/propagate_service.rb27
-rw-r--r--lib/gitlab/sql/bulk_insert.rb21
2 files changed, 41 insertions, 7 deletions
diff --git a/app/services/projects/propagate_service.rb b/app/services/projects/propagate_service.rb
index f952b5108bb..c420f24fe02 100644
--- a/app/services/projects/propagate_service.rb
+++ b/app/services/projects/propagate_service.rb
@@ -24,20 +24,23 @@ module Projects
loop do
batch = project_ids_batch
- bulk_create_from_template(batch)
+ bulk_create_from_template(batch) unless batch.empty?
break if batch.size < BATCH_SIZE
end
end
def bulk_create_from_template(batch)
- service_hash_list = batch.map do |project_id|
- service_hash.merge('project_id' => project_id)
+ service_list = batch.map do |project_id|
+ service_hash.merge('project_id' => project_id).values
end
- Project.transaction do
- Service.create!(service_hash_list)
- end
+ # Project.transaction do
+ # Service.create!(service_hash_list)
+ # end
+ Gitlab::SQL::BulkInsert.new(service_hash.keys + ['project_id'],
+ service_list,
+ 'services').execute
end
def project_ids_batch
@@ -57,7 +60,17 @@ module Projects
end
def service_hash
- @service_hash ||= @template.as_json(methods: :type).except('id', 'template')
+ @service_hash ||=
+ begin
+ template_hash = @template.as_json(methods: :type).except('id', 'template', 'project_id')
+
+ template_hash.each_with_object({}) do |(key, value), service_hash|
+ value = value.is_a?(Hash) ? value.to_json : value
+ key = Gitlab::Database.postgresql? ? "\"#{key}\"" : "`#{key}`"
+
+ service_hash[key] = ActiveRecord::Base.sanitize(value)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/sql/bulk_insert.rb b/lib/gitlab/sql/bulk_insert.rb
new file mode 100644
index 00000000000..097f9ff237b
--- /dev/null
+++ b/lib/gitlab/sql/bulk_insert.rb
@@ -0,0 +1,21 @@
+module Gitlab
+ module SQL
+ # Class for building SQL bulk inserts
+ class BulkInsert
+ def initialize(columns, values_array, table)
+ @columns = columns
+ @values_array = values_array
+ @table = table
+ end
+
+ def execute
+ ActiveRecord::Base.connection.execute(
+ <<-SQL.strip_heredoc
+ INSERT INTO #{@table} (#{@columns.join(', ')})
+ VALUES #{@values_array.map { |tuple| "(#{tuple.join(', ')})" }.join(', ')}
+ SQL
+ )
+ end
+ end
+ end
+end