diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2016-03-01 14:02:06 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2016-03-11 23:25:21 +0300 |
commit | 135659a75135b47563b349d13a9846b9b017af15 (patch) | |
tree | 207b6c6e6ca741f7bdd90af14d1034548d703b4b /spec/models | |
parent | d24ee2a2065692bd4edff59af55353de3c1c49e6 (diff) |
Use ILIKE/LIKE + UNION in Project.search
This chance is broken up in two steps:
1. Use ILIKE on PostgreSQL and LIKE on MySQL, instead of using
"WHERE lower(x) LIKE lower(y)" as ILIKE is significantly faster than
using lower(). In many cases the use of lower() will force a slow
sequence scan.
2. Instead of using 1 query that searches both projects and namespaces
using a JOIN we're using 2 separate queries that are UNION'd
together. Using a JOIN would force a slow sequence scan, using a
UNION avoids this.
This method now uses Arel as Arel automatically uses ILIKE on PostgreSQL
and LIKE on MySQL, removing the need to handle this manually.
Diffstat (limited to 'spec/models')
-rw-r--r-- | spec/models/project_spec.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 2fa38a5d3d3..6627432aa83 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -582,7 +582,58 @@ describe Project, models: true do it { expect(forked_project.visibility_level_allowed?(Gitlab::VisibilityLevel::INTERNAL)).to be_truthy } it { expect(forked_project.visibility_level_allowed?(Gitlab::VisibilityLevel::PUBLIC)).to be_falsey } end + end + + describe '.search' do + let(:project) { create(:project, description: 'kitten mittens') } + + it 'returns projects with a matching name' do + expect(described_class.search(project.name)).to eq([project]) + end + it 'returns projects with a partially matching name' do + expect(described_class.search(project.name[0..2])).to eq([project]) + end + + it 'returns projects with a matching name regardless of the casing' do + expect(described_class.search(project.name.upcase)).to eq([project]) + end + + it 'returns projects with a matching description' do + expect(described_class.search(project.description)).to eq([project]) + end + + it 'returns projects with a partially matching description' do + expect(described_class.search('kitten')).to eq([project]) + end + + it 'returns projects with a matching description regardless of the casing' do + expect(described_class.search('KITTEN')).to eq([project]) + end + + it 'returns projects with a matching path' do + expect(described_class.search(project.path)).to eq([project]) + end + + it 'returns projects with a partially matching path' do + expect(described_class.search(project.path[0..2])).to eq([project]) + end + + it 'returns projects with a matching path regardless of the casing' do + expect(described_class.search(project.path.upcase)).to eq([project]) + end + + it 'returns projects with a matching namespace name' do + expect(described_class.search(project.namespace.name)).to eq([project]) + end + + it 'returns projects with a partially matching namespace name' do + expect(described_class.search(project.namespace.name[0..2])).to eq([project]) + end + + it 'returns projects with a matching namespace name regardless of the casing' do + expect(described_class.search(project.namespace.name.upcase)).to eq([project]) + end end describe '#rename_repo' do |