From 896e09d055979cdfe6e20a8b5939c9a263f7e48a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 20 Jun 2016 15:31:03 +0200 Subject: [PATCH] started working on a migration for projects that have current import_url issues --- app/validators/addressable_url_validator.rb | 14 ++--- ...620110927_fix_no_validatable_import_url.rb | 52 +++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20160620110927_fix_no_validatable_import_url.rb diff --git a/app/validators/addressable_url_validator.rb b/app/validators/addressable_url_validator.rb index 7aab66548e2..585dc182e27 100644 --- a/app/validators/addressable_url_validator.rb +++ b/app/validators/addressable_url_validator.rb @@ -1,6 +1,6 @@ # AddressableUrlValidator # -# Custom validator for URLs. This is a +# Custom validator for URLs. This is a # # By default, only URLs for http, https, ssh, and git protocols will be considered valid. # Provide a `:protocols` option to configure accepted protocols. @@ -22,12 +22,6 @@ class AddressableUrlValidator < ActiveModel::EachValidator end end - private - - def default_options - @default_options ||= { protocols: %w(http https ssh git) } - end - def valid_url?(value) return false unless value @@ -38,6 +32,12 @@ class AddressableUrlValidator < ActiveModel::EachValidator false end + private + + def default_options + @default_options ||= { protocols: %w(http https ssh git) } + end + def valid_uri?(value) Addressable::URI.parse(value).is_a?(Addressable::URI) end diff --git a/db/migrate/20160620110927_fix_no_validatable_import_url.rb b/db/migrate/20160620110927_fix_no_validatable_import_url.rb new file mode 100644 index 00000000000..e56a8a0c853 --- /dev/null +++ b/db/migrate/20160620110927_fix_no_validatable_import_url.rb @@ -0,0 +1,52 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class FixNoValidatableImportUrl < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + class SqlBatches + + attr_reader :results, :query + + def initialize(batch_size: 100, query:) + @offset = 0 + @batch_size = batch_size + @query = query + @results = [] + end + + def next + @results = ActiveRecord::Base.connection.execute(batched_sql) + @offset += @batch_size + @results.any? + end + + private + + def batched_sql + "#{@query} OFFSET #{@offset} LIMIT #{@batch_size}" + end + end + + def up + invalid_import_url_project_ids.each { |project_id| cleanup_import_url(project_id) } + end + + def invalid_import_url_project_ids + ids = [] + batches = SqlBatches.new(query: "SELECT id, import_url FROM projects WHERE import_url IS NOT NULL") + + while batches.nexts + ids += batches.results.map { |result| invalid_url?(result[:import_url]) ? result[:id] : nil } + end + + ids.compact + end + + def invalid_url?(url) + AddressableUrlValidator.new({ attributes: 1 }).valid_url?(url) + end + + def cleanup_import_url(project_id) + execute("UPDATE projects SET mirror = false, import_url = NULL WHERE id = #{project_id}") + end +end