summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2018-05-17 16:20:41 +0000
committerRémy Coutable <remy@rymai.me>2018-05-17 16:20:41 +0000
commitbe54edbfd31e49b5d01f9130591b9ab8579081ab (patch)
treeb5902078050ac04390ca8642ae301db2b9056627
parent47555ef85e2a138e5ac16bfff597b7e72f818b25 (diff)
parentb11c218ad9d4635c2230e7f8d105236ca32e5072 (diff)
downloadgitlab-ce-be54edbfd31e49b5d01f9130591b9ab8579081ab.tar.gz
Merge branch 'order_groups' into 'master'
Fix: Use case in-sensitive ordering by name for groups See merge request gitlab-org/gitlab-ce!18553
-rw-r--r--app/models/concerns/sortable.rb4
-rw-r--r--changelogs/unreleased/use-case-insensitive-ordering-for-dashboard-filters.yml5
-rw-r--r--db/migrate/20180504195842_project_name_lower_index.rb32
-rw-r--r--lib/tasks/migrate/setup_postgresql.rake2
-rw-r--r--spec/models/concerns/sortable_spec.rb108
5 files changed, 149 insertions, 2 deletions
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index cefa5c13c5f..db7254c27e0 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -12,8 +12,8 @@ module Sortable
scope :order_created_asc, -> { reorder(created_at: :asc) }
scope :order_updated_desc, -> { reorder(updated_at: :desc) }
scope :order_updated_asc, -> { reorder(updated_at: :asc) }
- scope :order_name_asc, -> { reorder(name: :asc) }
- scope :order_name_desc, -> { reorder(name: :desc) }
+ scope :order_name_asc, -> { reorder("lower(name) asc") }
+ scope :order_name_desc, -> { reorder("lower(name) desc") }
end
module ClassMethods
diff --git a/changelogs/unreleased/use-case-insensitive-ordering-for-dashboard-filters.yml b/changelogs/unreleased/use-case-insensitive-ordering-for-dashboard-filters.yml
new file mode 100644
index 00000000000..098e4b1d5fa
--- /dev/null
+++ b/changelogs/unreleased/use-case-insensitive-ordering-for-dashboard-filters.yml
@@ -0,0 +1,5 @@
+---
+title: "Use case in-sensitive ordering by name for dashboard"
+merge_request: 18553
+author: "@vedharish"
+type: fixed
diff --git a/db/migrate/20180504195842_project_name_lower_index.rb b/db/migrate/20180504195842_project_name_lower_index.rb
new file mode 100644
index 00000000000..d6f25d3d4ab
--- /dev/null
+++ b/db/migrate/20180504195842_project_name_lower_index.rb
@@ -0,0 +1,32 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class ProjectNameLowerIndex < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+ INDEX_NAME = 'index_projects_on_lower_name'
+
+ disable_ddl_transaction!
+
+ def up
+ return unless Gitlab::Database.postgresql?
+
+ disable_statement_timeout
+
+ execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON projects (LOWER(name))"
+ end
+
+ def down
+ return unless Gitlab::Database.postgresql?
+
+ disable_statement_timeout
+
+ if supports_drop_index_concurrently?
+ execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}"
+ else
+ execute "DROP INDEX IF EXISTS #{INDEX_NAME}"
+ end
+ end
+end
diff --git a/lib/tasks/migrate/setup_postgresql.rake b/lib/tasks/migrate/setup_postgresql.rake
index af30ecb0e9b..e7aab50e42a 100644
--- a/lib/tasks/migrate/setup_postgresql.rake
+++ b/lib/tasks/migrate/setup_postgresql.rake
@@ -8,6 +8,7 @@ task setup_postgresql: :environment do
require Rails.root.join('db/migrate/20170503185032_index_redirect_routes_path_for_like')
require Rails.root.join('db/migrate/20171220191323_add_index_on_namespaces_lower_name.rb')
require Rails.root.join('db/migrate/20180215181245_users_name_lower_index.rb')
+ require Rails.root.join('db/migrate/20180504195842_project_name_lower_index.rb')
require Rails.root.join('db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb')
NamespacesProjectsPathLowerIndexes.new.up
@@ -18,5 +19,6 @@ task setup_postgresql: :environment do
IndexRedirectRoutesPathForLike.new.up
AddIndexOnNamespacesLowerName.new.up
UsersNameLowerIndex.new.up
+ ProjectNameLowerIndex.new.up
AddPathIndexToRedirectRoutes.new.up
end
diff --git a/spec/models/concerns/sortable_spec.rb b/spec/models/concerns/sortable_spec.rb
new file mode 100644
index 00000000000..b821a84d5e0
--- /dev/null
+++ b/spec/models/concerns/sortable_spec.rb
@@ -0,0 +1,108 @@
+require 'spec_helper'
+
+describe Sortable do
+ describe '.order_by' do
+ let(:relation) { Group.all }
+
+ describe 'ordering by id' do
+ it 'ascending' do
+ expect(relation).to receive(:reorder).with(id: :asc)
+
+ relation.order_by('id_asc')
+ end
+
+ it 'descending' do
+ expect(relation).to receive(:reorder).with(id: :desc)
+
+ relation.order_by('id_desc')
+ end
+ end
+
+ describe 'ordering by created day' do
+ it 'ascending' do
+ expect(relation).to receive(:reorder).with(created_at: :asc)
+
+ relation.order_by('created_asc')
+ end
+
+ it 'descending' do
+ expect(relation).to receive(:reorder).with(created_at: :desc)
+
+ relation.order_by('created_desc')
+ end
+
+ it 'order by "date"' do
+ expect(relation).to receive(:reorder).with(created_at: :desc)
+
+ relation.order_by('created_date')
+ end
+ end
+
+ describe 'ordering by name' do
+ it 'ascending' do
+ expect(relation).to receive(:reorder).with("lower(name) asc")
+
+ relation.order_by('name_asc')
+ end
+
+ it 'descending' do
+ expect(relation).to receive(:reorder).with("lower(name) desc")
+
+ relation.order_by('name_desc')
+ end
+ end
+
+ describe 'ordering by Updated Time' do
+ it 'ascending' do
+ expect(relation).to receive(:reorder).with(updated_at: :asc)
+
+ relation.order_by('updated_asc')
+ end
+
+ it 'descending' do
+ expect(relation).to receive(:reorder).with(updated_at: :desc)
+
+ relation.order_by('updated_desc')
+ end
+ end
+
+ it 'does not call reorder in case of unrecognized ordering' do
+ expect(relation).not_to receive(:reorder)
+
+ relation.order_by('random_ordering')
+ end
+ end
+
+ describe 'sorting groups' do
+ def ordered_group_names(order)
+ Group.all.order_by(order).map(&:name)
+ end
+
+ let!(:ref_time) { Time.parse('2018-05-01 00:00:00') }
+ let!(:group1) { create(:group, name: 'aa', id: 1, created_at: ref_time - 15.seconds, updated_at: ref_time) }
+ let!(:group2) { create(:group, name: 'AAA', id: 2, created_at: ref_time - 10.seconds, updated_at: ref_time - 5.seconds) }
+ let!(:group3) { create(:group, name: 'BB', id: 3, created_at: ref_time - 5.seconds, updated_at: ref_time - 10.seconds) }
+ let!(:group4) { create(:group, name: 'bbb', id: 4, created_at: ref_time, updated_at: ref_time - 15.seconds) }
+
+ it 'sorts groups by id' do
+ expect(ordered_group_names('id_asc')).to eq(%w(aa AAA BB bbb))
+ expect(ordered_group_names('id_desc')).to eq(%w(bbb BB AAA aa))
+ end
+
+ it 'sorts groups by name via case-insentitive comparision' do
+ expect(ordered_group_names('name_asc')).to eq(%w(aa AAA BB bbb))
+ expect(ordered_group_names('name_desc')).to eq(%w(bbb BB AAA aa))
+ end
+
+ it 'sorts groups by created_at' do
+ expect(ordered_group_names('created_asc')).to eq(%w(aa AAA BB bbb))
+ expect(ordered_group_names('created_desc')).to eq(%w(bbb BB AAA aa))
+ expect(ordered_group_names('created_date')).to eq(%w(bbb BB AAA aa))
+ end
+
+ it 'sorts groups by updated_at' do
+ expect(ordered_group_names('updated_asc')).to eq(%w(bbb BB AAA aa))
+ expect(ordered_group_names('updated_desc')).to eq(%w(aa AAA BB bbb))
+ end
+ end
+end