summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Mathiesen <marius@shortcut.no>2009-12-14 14:12:01 +0100
committerMarius Mathiesen <marius@shortcut.no>2009-12-14 15:15:35 +0100
commit8eef9e3d5dea455e41a702909d8c54b21d7cd37a (patch)
tree5b4aff511cffdd5db4bff43dcac2adc616aabe60
parent7a97031db4937d3f2664062152ac6dfc5254ba1d (diff)
downloadgitorious-mainline-outdated-8eef9e3d5dea455e41a702909d8c54b21d7cd37a.zip
gitorious-mainline-outdated-8eef9e3d5dea455e41a702909d8c54b21d7cd37a.tar.gz
gitorious-mainline-outdated-8eef9e3d5dea455e41a702909d8c54b21d7cd37a.tar.bz2
Perform Repository#search_clones in SQL instead of Ruby
-rw-r--r--app/controllers/repositories_controller.rb2
-rw-r--r--app/models/repository.rb18
-rw-r--r--test/test_helper.rb15
-rw-r--r--test/unit/repository_test.rb50
4 files changed, 82 insertions, 3 deletions
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 696655a..b46dc3c 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -152,7 +152,7 @@ class RepositoriesController < ApplicationController
def search_clones
@repository = @owner.repositories.find_by_name_in_project!(params[:id], @containing_project)
- @repositories = @repository.search_clones(Regexp.new(params[:filter]))
+ @repositories = @repository.search_clones(params[:filter])
render :json => to_json(@repositories)
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 079609a..7d68449 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -670,7 +670,23 @@ class Repository < ActiveRecord::Base
end
def search_clones(term)
- clones.find_all { |r| r.matches_regexp?(term)}
+ sql = "SELECT repositories.* FROM repositories
+ INNER JOIN users on repositories.user_id=users.id
+ INNER JOIN groups on repositories.owner_id=groups.id
+ WHERE repositories.parent_id=:id
+ AND (repositories.name LIKE :q OR repositories.description LIKE :q OR groups.name LIKE :q)
+ AND repositories.owner_type='Group'
+ AND kind in (:kinds)
+ UNION ALL
+ SELECT repositories.* from repositories
+ INNER JOIN users on repositories.user_id=users.id
+ INNER JOIN users owners on repositories.owner_id=owners.id
+ WHERE repositories.parent_id=:id
+ AND (repositories.name LIKE :q OR repositories.description LIKE :q OR owners.login LIKE :q)
+ AND repositories.owner_type='User'
+ AND kind in (:kinds)"
+ clones.find_by_sql([sql, {:q => "%#{term}%", :id => id, :kinds =>
+ [KIND_TEAM_REPO, KIND_USER_REPO, KIND_PROJECT_REPO]}])
end
protected
diff --git a/test/test_helper.rb b/test/test_helper.rb
index cdf4ea5..021bf2c 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -68,6 +68,21 @@ class ActiveSupport::TestCase
error_msg = (value_before == value_after) ? "unchanged" : "incremented by #{(value_after - value_before)}"
assert_equal(value, (value_after - value_before), "#{obj}##{meth} should be incremented by #{value} but was #{error_msg}")
end
+
+ def assert_includes(collection, object, message=nil)
+ assert(collection.include?(object),
+ (message || inclusion_failure(collection, object, true)))
+ end
+
+ def assert_not_includes(collection, object, message=nil)
+ assert(!collection.include?(object),
+ (message || inclusion_failure(collection, object, false)))
+ end
+
+ def inclusion_failure(collection, object, should_be_included)
+ not_message = should_be_included ? "" : " not"
+ "Expected collection (#{collection.count} items) #{not_message} to include #{object.class.name}"
+ end
def self.should_render_in_global_context(options = {})
should "Render in global context for actions" do
diff --git a/test/unit/repository_test.rb b/test/unit/repository_test.rb
index bfb5b7a..da1d938 100644
--- a/test/unit/repository_test.rb
+++ b/test/unit/repository_test.rb
@@ -1017,8 +1017,56 @@ class RepositoryTest < ActiveSupport::TestCase
should "find clones matching an owning group's name" do
assert @repo.clones.include?(@clone)
- assert @repo.search_clones(/sproject/).include?(@clone)
+ assert @repo.search_clones("sproject").include?(@clone)
end
+
+ context "by user name" do
+ setup do
+ @repo = repositories(:moes)
+ @clone = repositories(:johans_moe_clone)
+ users(:johan).update_attribute(:login, "rohan")
+ @clone.update_attribute(:name, "rohans-clone-of-moes")
+ end
+
+ should "match users with a matching name" do
+ assert_includes(@repo.search_clones("rohan"), @clone)
+ end
+
+ should "not match user with diverging name" do
+ assert_not_includes(@repo.search_clones("johan"), @clone)
+ end
+ end
+
+ context "by group name" do
+ setup do
+ @repo = repositories(:johans)
+ @clone = repositories(:johans2)
+ end
+
+ should "match groups with a matching name" do
+ assert_includes(@repo.search_clones("thunderbird"), @clone)
+ end
+
+ should "not match groups with diverging name" do
+ assert_not_includes(@repo.search_clones("A-team"), @clone)
+ end
+ end
+
+ context "by repo name and description" do
+ setup do
+ @repo = repositories(:johans)
+ @clone = repositories(:johans2)
+ end
+
+ should "match repos with a matching name" do
+ assert_includes(@repo.search_clones("projectrepos"), @clone)
+ end
+
+ should "not match repos with a different parent" do
+ assert_not_includes(@repo.search_clones("projectrepos"), repositories(:moes))
+ end
+ end
+
end
context "Sequences" do