Commit 828519ba authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'fix_importers' into 'master'

Fix importers with OCC

Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/1180

Using validates_uniqueness_of does not guarantee the absence of duplicate record insertions. When users click button "import all" it will create duplicating group in database and data integrity will be broken.

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of

I use optimistic concurrency control for handling this situation.

See merge request !1647
parents 0fa4d092 02ed61c4
......@@ -3,19 +3,17 @@ class Import::BaseController < ApplicationController
private
def get_or_create_namespace
existing_namespace = Namespace.find_by_path_or_name(@target_namespace)
if existing_namespace
if existing_namespace.owner == current_user
namespace = existing_namespace
else
begin
namespace = Group.create!(name: @target_namespace, path: @target_namespace, owner: current_user)
namespace.add_owner(current_user)
rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
namespace = Namespace.find_by_path_or_name(@target_namespace)
unless namespace.owner == current_user
@already_been_taken = true
return false
end
else
namespace = Group.create(name: @target_namespace, path: @target_namespace, owner: current_user)
namespace.add_owner(current_user)
namespace
end
namespace
end
end
class FixNamespaceDuplication < ActiveRecord::Migration
def up
#fixes path duplication
select_all('SELECT MAX(id) max, COUNT(id) cnt, path FROM namespaces GROUP BY path HAVING COUNT(id) > 1').each do |nms|
bad_nms_ids = select_all("SELECT id FROM namespaces WHERE path = '#{nms['path']}' AND id <> #{nms['max']}").map{|x| x["id"]}
execute("UPDATE projects SET namespace_id = #{nms["max"]} WHERE namespace_id IN(#{bad_nms_ids.join(', ')})")
execute("DELETE FROM namespaces WHERE id IN(#{bad_nms_ids.join(', ')})")
end
#fixes name duplication
select_all('SELECT MAX(id) max, COUNT(id) cnt, name FROM namespaces GROUP BY name HAVING COUNT(id) > 1').each do |nms|
bad_nms_ids = select_all("SELECT id FROM namespaces WHERE name = '#{nms['name']}' AND id <> #{nms['max']}").map{|x| x["id"]}
execute("UPDATE projects SET namespace_id = #{nms["max"]} WHERE namespace_id IN(#{bad_nms_ids.join(', ')})")
execute("DELETE FROM namespaces WHERE id IN(#{bad_nms_ids.join(', ')})")
end
end
def down
# not implemented
end
end
class AddUniqueIndexToNamespace < ActiveRecord::Migration
def change
remove_index :namespaces, column: :name if index_exists?(:namespaces, :name)
remove_index :namespaces, column: :path if index_exists?(:namespaces, :path)
add_index :namespaces, :name, unique: true
add_index :namespaces, :path, unique: true
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150225065047) do
ActiveRecord::Schema.define(version: 20150306023112) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -242,9 +242,9 @@ ActiveRecord::Schema.define(version: 20150225065047) do
end
add_index "namespaces", ["created_at", "id"], name: "index_namespaces_on_created_at_and_id", using: :btree
add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
add_index "namespaces", ["name"], name: "index_namespaces_on_name", unique: true, using: :btree
add_index "namespaces", ["owner_id"], name: "index_namespaces_on_owner_id", using: :btree
add_index "namespaces", ["path"], name: "index_namespaces_on_path", using: :btree
add_index "namespaces", ["path"], name: "index_namespaces_on_path", unique: true, using: :btree
add_index "namespaces", ["type"], name: "index_namespaces_on_type", using: :btree
create_table "notes", force: true do |t|
......@@ -334,12 +334,12 @@ ActiveRecord::Schema.define(version: 20150225065047) do
t.string "import_url"
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.string "avatar"
t.string "import_status"
t.float "repository_size", default: 0.0
t.integer "star_count", default: 0, null: false
t.string "import_type"
t.string "import_source"
t.string "avatar"
end
add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment