diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-06 21:06:29 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-06 21:06:29 +0300 |
commit | bcdcff749598f4275f7c250c07cbfe632cfe7fdb (patch) | |
tree | fa3f6e54632837f21319794dbd9136e3de3a76ba /lib/gitlab/graphql | |
parent | 5277f8e69e935eabd3bf8c5e7833471b5bfad1d9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/graphql')
-rw-r--r-- | lib/gitlab/graphql/connections/keyset/connection.rb | 9 | ||||
-rw-r--r-- | lib/gitlab/graphql/connections/keyset/order_info.rb | 32 |
2 files changed, 29 insertions, 12 deletions
diff --git a/lib/gitlab/graphql/connections/keyset/connection.rb b/lib/gitlab/graphql/connections/keyset/connection.rb index 0daf726c005..c75ea206edb 100644 --- a/lib/gitlab/graphql/connections/keyset/connection.rb +++ b/lib/gitlab/graphql/connections/keyset/connection.rb @@ -8,10 +8,15 @@ # https://coderwall.com/p/lkcaag/pagination-you-re-probably-doing-it-wrong # # It currently supports sorting on two columns, but the last column must -# be the primary key. For example +# be the primary key. If it's not already included, an order on the +# primary key will be added automatically, like `order(id: :desc)` # # Issue.order(created_at: :asc).order(:id) -# Issue.order(due_date: :asc).order(:id) +# Issue.order(due_date: :asc) +# +# You can also use `Gitlab::Database.nulls_last_order`: +# +# Issue.reorder(::Gitlab::Database.nulls_last_order('due_date', 'DESC')) # # It will tolerate non-attribute ordering, but only attributes determine the cursor. # For example, this is legitimate: diff --git a/lib/gitlab/graphql/connections/keyset/order_info.rb b/lib/gitlab/graphql/connections/keyset/order_info.rb index 6c4be93bfee..4d85e8f79b7 100644 --- a/lib/gitlab/graphql/connections/keyset/order_info.rb +++ b/lib/gitlab/graphql/connections/keyset/order_info.rb @@ -5,12 +5,15 @@ module Gitlab module Connections module Keyset class OrderInfo - def initialize(order_value) - @order_value = order_value - end + attr_reader :attribute_name, :sort_direction - def attribute_name - order_value.expr.name + def initialize(order_value) + if order_value.is_a?(String) + @attribute_name, @sort_direction = extract_nulls_last_order(order_value) + else + @attribute_name = order_value.expr.name + @sort_direction = order_value.direction + end end def operator_for(before_or_after) @@ -22,10 +25,10 @@ module Gitlab end end - # Only allow specific node types. For example ignore String nodes + # Only allow specific node types def self.build_order_list(relation) order_list = relation.order_values.select do |value| - value.is_a?(Arel::Nodes::Ascending) || value.is_a?(Arel::Nodes::Descending) + supported_order_value?(value) end order_list.map { |info| OrderInfo.new(info) } @@ -52,12 +55,21 @@ module Gitlab end end + def self.supported_order_value?(order_value) + return true if order_value.is_a?(Arel::Nodes::Ascending) || order_value.is_a?(Arel::Nodes::Descending) + return false unless order_value.is_a?(String) + + tokens = order_value.downcase.split + + tokens.last(2) == %w(nulls last) && tokens.count == 4 + end + private - attr_reader :order_value + def extract_nulls_last_order(order_value) + tokens = order_value.downcase.split - def sort_direction - order_value.direction + [tokens.first, (tokens[1] == 'asc' ? :asc : :desc)] end end end |