From 62ff6312b4173f3e5662f7a08d8afb4f8d45cce2 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Wed, 3 Apr 2013 20:03:52 +0400 Subject: [PATCH 1/8] #73: Increatse performance for #autocomplete_to_project action --- .../projects/pull_requests_controller.rb | 16 ++++++++++++---- lib/modules/models/owner.rb | 6 +++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects/pull_requests_controller.rb b/app/controllers/projects/pull_requests_controller.rb index 5a4e7cbd9..5c9ba0e38 100644 --- a/app/controllers/projects/pull_requests_controller.rb +++ b/app/controllers/projects/pull_requests_controller.rb @@ -115,9 +115,17 @@ class Projects::PullRequestsController < Projects::BaseController end def autocomplete_to_project - items = Project.accessible_by(current_ability, :membered) | @project.ancestors - term = Regexp.new(Regexp.escape params[:term].downcase) - items.select! {|e| term.match(e.name_with_owner.downcase) && e.repo.branches.count > 0} + items = [] + term = params[:term].to_s.strip.downcase + condition = ["lower(concat(owners.uname, '/', projects.name)) ILIKE ?", "%#{term}%"] + [Project.accessible_by(current_ability, :membered), @project.ancestors].each do |p| + p = p.where(condition) + items.concat p.where(:owner_type => 'User').includes(:owner_user). + joins("INNER JOIN users as owners ON projects.owner_id = owners.id") + items.concat p.where(:owner_type => 'Group').includes(:owner_group). + joins("INNER JOIN groups as owners ON projects.owner_id = owners.id") + end + items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0} render :json => json_for_autocomplete_base(items) end @@ -129,7 +137,7 @@ class Projects::PullRequestsController < Projects::BaseController def json_for_autocomplete_base items items.collect do |project| - hash = {"id" => project.id.to_s, "label" => project.name_with_owner, "value" => project.name_with_owner} + hash = {:id => project.id.to_s, :label => project.name_with_owner, :value => project.name_with_owner} hash[:get_refs_url] = project_refs_list_path(project) hash end diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index e88ac3f5f..5108b81c6 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -5,11 +5,15 @@ module Modules extend ActiveSupport::Concern included do + belongs_to :owner_user, :class_name => 'User', :foreign_key => 'owner_id' + belongs_to :owner_group, :class_name => 'Group', :foreign_key => 'owner_id' + after_create lambda { relations.create :actor_id => owner.id, :actor_type => owner.class.to_s, :role => 'admin' } end def name_with_owner - "#{owner.respond_to?(:uname) ? owner.uname : owner.name}/#{self.name}" + o = owner_type == 'User' ? owner_user : owner_group + "#{o.respond_to?(:uname) ? o.uname : o.name}/#{self.name}" end end end From 9dcd08b86879d77e203cf893d8a604a53bf025db Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 4 Apr 2013 01:06:13 +0400 Subject: [PATCH 2/8] #73: add owner_uname into Project --- .../projects/pull_requests_controller.rb | 8 ++----- app/models/platform.rb | 1 - app/models/project.rb | 6 +++++- ...03202853_add_name_with_owner_to_project.rb | 21 +++++++++++++++++++ db/schema.rb | 3 ++- lib/modules/models/owner.rb | 9 +++----- 6 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20130403202853_add_name_with_owner_to_project.rb diff --git a/app/controllers/projects/pull_requests_controller.rb b/app/controllers/projects/pull_requests_controller.rb index 5c9ba0e38..6701bc12d 100644 --- a/app/controllers/projects/pull_requests_controller.rb +++ b/app/controllers/projects/pull_requests_controller.rb @@ -117,13 +117,9 @@ class Projects::PullRequestsController < Projects::BaseController def autocomplete_to_project items = [] term = params[:term].to_s.strip.downcase - condition = ["lower(concat(owners.uname, '/', projects.name)) ILIKE ?", "%#{term}%"] + condition = ["lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%"] [Project.accessible_by(current_ability, :membered), @project.ancestors].each do |p| - p = p.where(condition) - items.concat p.where(:owner_type => 'User').includes(:owner_user). - joins("INNER JOIN users as owners ON projects.owner_id = owners.id") - items.concat p.where(:owner_type => 'Group').includes(:owner_group). - joins("INNER JOIN groups as owners ON projects.owner_id = owners.id") + items.concat p.where(condition) end items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0} render :json => json_for_autocomplete_base(items) diff --git a/app/models/platform.rb b/app/models/platform.rb index 29d4f8d2f..7c4d425be 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -19,7 +19,6 @@ class Platform < ActiveRecord::Base has_many :mass_builds validates :description, :presence => true - validates :owner, :presence => true validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES} validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /\A[a-zA-Z0-9_\-\.]+\z/ } validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']} diff --git a/app/models/project.rb b/app/models/project.rb index 6d5d5e8f2..2e25b4230 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,7 +28,6 @@ class Project < ActiveRecord::Base validates :name, :uniqueness => {:scope => [:owner_id, :owner_type], :case_sensitive => false}, :presence => true, :format => {:with => /\A#{NAME_REGEXP}\z/, :message => I18n.t("activerecord.errors.project.uname")} - validates :owner, :presence => true validates :maintainer_id, :presence => true, :unless => :new_record? validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES} validate { errors.add(:base, :can_have_less_or_equal, :count => MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS } @@ -58,6 +57,7 @@ class Project < ActiveRecord::Base } before_validation :truncate_name, :on => :create + before_save lambda { self.owner_uname = owner.uname if owner_id_changed? || owner_type_changed? } before_create :set_maintainer after_save :attach_to_personal_repository after_update :set_new_git_head @@ -81,6 +81,10 @@ class Project < ActiveRecord::Base end end + def name_with_owner + "#{owner_uname}/#{name}" + end + def to_param name end diff --git a/db/migrate/20130403202853_add_name_with_owner_to_project.rb b/db/migrate/20130403202853_add_name_with_owner_to_project.rb new file mode 100644 index 000000000..7119ac232 --- /dev/null +++ b/db/migrate/20130403202853_add_name_with_owner_to_project.rb @@ -0,0 +1,21 @@ +class AddNameWithOwnerToProject < ActiveRecord::Migration + def up + add_column :projects, :owner_uname, :string + + execute <<-SQL + UPDATE projects SET owner_uname = owners.uname + FROM users as owners + WHERE projects.owner_type = 'User' AND projects.owner_id = owners.id + SQL + + execute <<-SQL + UPDATE projects SET owner_uname = owners.uname + FROM groups as owners + WHERE projects.owner_type = 'Group' AND projects.owner_id = owners.id + SQL + end + + def down + remove_column :projects, :owner_uname + end +end diff --git a/db/schema.rb b/db/schema.rb index 723c833d8..7462f4f00 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130328112110) do +ActiveRecord::Schema.define(:version => 20130403202853) do create_table "activity_feeds", :force => true do |t| t.integer "user_id", :null => false @@ -387,6 +387,7 @@ ActiveRecord::Schema.define(:version => 20130328112110) do t.integer "build_count", :default => 0, :null => false t.integer "maintainer_id" t.boolean "publish_i686_into_x86_64", :default => false + t.string "owner_uname" end add_index "projects", ["owner_id", "name", "owner_type"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index 5108b81c6..24ac4340c 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -5,16 +5,13 @@ module Modules extend ActiveSupport::Concern included do - belongs_to :owner_user, :class_name => 'User', :foreign_key => 'owner_id' - belongs_to :owner_group, :class_name => 'Group', :foreign_key => 'owner_id' + belongs_to :owner_user, :class_name => 'User', :foreign_key => 'owner_id' + belongs_to :owner_group, :class_name => 'Group', :foreign_key => 'owner_id' + validates :owner, :presence => true after_create lambda { relations.create :actor_id => owner.id, :actor_type => owner.class.to_s, :role => 'admin' } end - def name_with_owner - o = owner_type == 'User' ? owner_user : owner_group - "#{o.respond_to?(:uname) ? o.uname : o.name}/#{self.name}" - end end end end From 105e5f54a4ee7c2f52ca6f82ef6464b4aee2f620 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 4 Apr 2013 01:16:20 +0400 Subject: [PATCH 3/8] #73: hot fix --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 2e25b4230..2ce765f10 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -82,7 +82,7 @@ class Project < ActiveRecord::Base end def name_with_owner - "#{owner_uname}/#{name}" + "#{owner_uname || owner.uname}/#{name}" end def to_param From 110499360ba2f390c8d308083f32707f5ebbe85f Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 4 Apr 2013 01:18:56 +0400 Subject: [PATCH 4/8] #73: small refactoring --- app/controllers/projects/pull_requests_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/projects/pull_requests_controller.rb b/app/controllers/projects/pull_requests_controller.rb index 6701bc12d..eb1ab8586 100644 --- a/app/controllers/projects/pull_requests_controller.rb +++ b/app/controllers/projects/pull_requests_controller.rb @@ -117,9 +117,8 @@ class Projects::PullRequestsController < Projects::BaseController def autocomplete_to_project items = [] term = params[:term].to_s.strip.downcase - condition = ["lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%"] [Project.accessible_by(current_ability, :membered), @project.ancestors].each do |p| - items.concat p.where(condition) + items.concat p.where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") end items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0} render :json => json_for_autocomplete_base(items) From 179615f5b7a0ff9234bb3a544e1689cfeeb28028 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 4 Apr 2013 17:33:11 +0400 Subject: [PATCH 5/8] #73: create #by_owner_and_name scope --- app/controllers/projects/pull_requests_controller.rb | 2 +- app/models/project.rb | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects/pull_requests_controller.rb b/app/controllers/projects/pull_requests_controller.rb index eb1ab8586..cce92b69e 100644 --- a/app/controllers/projects/pull_requests_controller.rb +++ b/app/controllers/projects/pull_requests_controller.rb @@ -118,7 +118,7 @@ class Projects::PullRequestsController < Projects::BaseController items = [] term = params[:term].to_s.strip.downcase [Project.accessible_by(current_ability, :membered), @project.ancestors].each do |p| - items.concat p.where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") + items.concat p.by_owner_and_name(term) end items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0} render :json => json_for_autocomplete_base(items) diff --git a/app/models/project.rb b/app/models/project.rb index 2ce765f10..0976247f2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -40,6 +40,10 @@ class Project < ActiveRecord::Base scope :search_order, order("CHAR_LENGTH(#{table_name}.name) ASC") scope :search, lambda {|q| by_name("%#{q.to_s.strip}%")} scope :by_name, lambda {|name| where("#{table_name}.name ILIKE ?", name) if name.present?} + scope :by_owner_and_name, lambda { |*params| + term = params.map(&:strip).join('/').downcase + where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present? + } scope :by_visibilities, lambda {|v| where(:visibility => v)} scope :opened, where(:visibility => 'open') scope :package, where(:is_package => true) @@ -70,10 +74,8 @@ class Project < ActiveRecord::Base class << self def find_by_owner_and_name(owner_name, project_name) - owner = User.find_by_uname(owner_name) || Group.find_by_uname(owner_name) || User.by_uname(owner_name).first || Group.by_uname(owner_name).first and - scoped = where(:owner_id => owner.id, :owner_type => owner.class) and - scoped.find_by_name(project_name) || scoped.by_name(project_name).first - # owner.projects.find_by_name(project_name) || owner.projects.by_name(project_name).first # TODO force this work? + where(:owner_uname => owner_name, :name => project_name).first || + by_owner_and_name(owner_name, project_name).first end def find_by_owner_and_name!(owner_name, project_name) From 588a7d8bab77de30a3615c7f032446b06a86d06a Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 4 Apr 2013 17:36:54 +0400 Subject: [PATCH 6/8] #73: remove unnecessary code --- lib/modules/models/owner.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/modules/models/owner.rb b/lib/modules/models/owner.rb index 24ac4340c..395d30db1 100644 --- a/lib/modules/models/owner.rb +++ b/lib/modules/models/owner.rb @@ -5,9 +5,6 @@ module Modules extend ActiveSupport::Concern included do - belongs_to :owner_user, :class_name => 'User', :foreign_key => 'owner_id' - belongs_to :owner_group, :class_name => 'Group', :foreign_key => 'owner_id' - validates :owner, :presence => true after_create lambda { relations.create :actor_id => owner.id, :actor_type => owner.class.to_s, :role => 'admin' } end From 3328866d118e7b457d73c5d4f69e2e4b447dd181 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 8 Apr 2013 22:53:15 +0400 Subject: [PATCH 7/8] #73: set not null for owner_uname --- app/models/project.rb | 2 +- ...20130403202853_add_name_with_owner_to_project.rb | 1 + db/schema.rb | 13 +++++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 0976247f2..791b87088 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -61,7 +61,7 @@ class Project < ActiveRecord::Base } before_validation :truncate_name, :on => :create - before_save lambda { self.owner_uname = owner.uname if owner_id_changed? || owner_type_changed? } + before_save lambda { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? } before_create :set_maintainer after_save :attach_to_personal_repository after_update :set_new_git_head diff --git a/db/migrate/20130403202853_add_name_with_owner_to_project.rb b/db/migrate/20130403202853_add_name_with_owner_to_project.rb index 7119ac232..7f7cd58f2 100644 --- a/db/migrate/20130403202853_add_name_with_owner_to_project.rb +++ b/db/migrate/20130403202853_add_name_with_owner_to_project.rb @@ -13,6 +13,7 @@ class AddNameWithOwnerToProject < ActiveRecord::Migration FROM groups as owners WHERE projects.owner_type = 'Group' AND projects.owner_id = owners.id SQL + change_column :projects, :owner_uname, :string, :null => false end def down diff --git a/db/schema.rb b/db/schema.rb index 7462f4f00..2c76efa40 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -152,11 +152,20 @@ ActiveRecord::Schema.define(:version => 20130403202853) do t.text "body" t.datetime "created_at" t.datetime "updated_at" - t.decimal "commentable_id", :precision => 50, :scale => 0 + t.decimal "commentable_id", :precision => 50, :scale => 0 t.integer "project_id" t.text "data" + t.boolean "automatic", :default => false + t.decimal "created_from_commit_hash", :precision => 50, :scale => 0 + t.integer "created_from_issue_id" end + add_index "comments", ["automatic"], :name => "index_comments_on_automatic" + add_index "comments", ["commentable_id"], :name => "index_comments_on_commentable_id" + add_index "comments", ["commentable_type"], :name => "index_comments_on_commentable_type" + add_index "comments", ["created_from_commit_hash"], :name => "index_comments_on_created_from_commit_hash" + add_index "comments", ["created_from_issue_id"], :name => "index_comments_on_created_from_issue_id" + create_table "event_logs", :force => true do |t| t.integer "user_id" t.string "user_name" @@ -387,7 +396,7 @@ ActiveRecord::Schema.define(:version => 20130403202853) do t.integer "build_count", :default => 0, :null => false t.integer "maintainer_id" t.boolean "publish_i686_into_x86_64", :default => false - t.string "owner_uname" + t.string "owner_uname", :null => false end add_index "projects", ["owner_id", "name", "owner_type"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false From da746ab901d94490d6478839dbdd94f23b58de8f Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Tue, 9 Apr 2013 00:51:38 +0400 Subject: [PATCH 8/8] #73: fixed specs --- spec/controllers/api/v1/build_lists_controller_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/controllers/api/v1/build_lists_controller_spec.rb b/spec/controllers/api/v1/build_lists_controller_spec.rb index fdb82b5dd..cb0e68149 100644 --- a/spec/controllers/api/v1/build_lists_controller_spec.rb +++ b/spec/controllers/api/v1/build_lists_controller_spec.rb @@ -480,8 +480,11 @@ describe Api::V1::BuildListsController do @user = FactoryGirl.create(:user) @group.actors.create :role => 'reader', :actor_id => @user.id, :actor_type => 'User' + old_path = @project.path @project.owner = @owner_group @project.save + # Move GIT repo into new folder + system "mkdir -p #{@project.path} && mv -f #{old_path}/* #{@project.path}/" @project.relations.create :role => 'reader', :actor_id => @member_group.id, :actor_type => 'Group' @project.relations.create :role => 'admin', :actor_id => @owner_group.id, :actor_type => 'Group'