summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2018-07-04 09:31:07 +0000
committerDouwe Maan <douwe@gitlab.com>2018-07-04 09:31:07 +0000
commit03f0f2566b3c536cf512b287e0d4d52d40a065c5 (patch)
treefd28c5029e51fa7240060a1a029903cc63ab3cc6 /lib
parentd81ce8b25c50d96f47d6cdbcdfc3d1f66fca0f96 (diff)
parent04b046587fe609cd889f3fa518f08299abc61267 (diff)
downloadgitlab-ce-03f0f2566b3c536cf512b287e0d4d52d40a065c5.tar.gz
Merge branch 'bvl-graphql-pipeline-lists' into 'master'
Add pipeline lists to graphql Closes #48469 See merge request gitlab-org/gitlab-ce!20249
Diffstat (limited to 'lib')
-rw-r--r--lib/api/pipelines.rb2
-rw-r--r--lib/gitlab/graphql/connections.rb12
-rw-r--r--lib/gitlab/graphql/connections/keyset_connection.rb73
-rw-r--r--lib/gitlab/graphql/errors.rb8
-rw-r--r--lib/gitlab/graphql/present/instrumentation.rb2
5 files changed, 96 insertions, 1 deletions
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index 8374a57edfa..5d33a13d035 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -31,7 +31,7 @@ module API
get ':id/pipelines' do
authorize! :read_pipeline, user_project
- pipelines = PipelinesFinder.new(user_project, params).execute
+ pipelines = PipelinesFinder.new(user_project, current_user, params).execute
present paginate(pipelines), with: Entities::PipelineBasic
end
diff --git a/lib/gitlab/graphql/connections.rb b/lib/gitlab/graphql/connections.rb
new file mode 100644
index 00000000000..2582ffeb2a8
--- /dev/null
+++ b/lib/gitlab/graphql/connections.rb
@@ -0,0 +1,12 @@
+module Gitlab
+ module Graphql
+ module Connections
+ def self.use(_schema)
+ GraphQL::Relay::BaseConnection.register_connection_implementation(
+ ActiveRecord::Relation,
+ Gitlab::Graphql::Connections::KeysetConnection
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/connections/keyset_connection.rb b/lib/gitlab/graphql/connections/keyset_connection.rb
new file mode 100644
index 00000000000..abee2afe144
--- /dev/null
+++ b/lib/gitlab/graphql/connections/keyset_connection.rb
@@ -0,0 +1,73 @@
+module Gitlab
+ module Graphql
+ module Connections
+ class KeysetConnection < GraphQL::Relay::BaseConnection
+ def cursor_from_node(node)
+ encode(node[order_field].to_s)
+ end
+
+ def sliced_nodes
+ @sliced_nodes ||=
+ begin
+ sliced = nodes
+
+ sliced = sliced.where(before_slice) if before.present?
+ sliced = sliced.where(after_slice) if after.present?
+
+ sliced
+ end
+ end
+
+ def paged_nodes
+ if first && last
+ raise Gitlab::Graphql::Errors::ArgumentError.new("Can only provide either `first` or `last`, not both")
+ end
+
+ if last
+ sliced_nodes.last(limit_value)
+ else
+ sliced_nodes.limit(limit_value)
+ end
+ end
+
+ private
+
+ def before_slice
+ if sort_direction == :asc
+ table[order_field].lt(decode(before))
+ else
+ table[order_field].gt(decode(before))
+ end
+ end
+
+ def after_slice
+ if sort_direction == :asc
+ table[order_field].gt(decode(after))
+ else
+ table[order_field].lt(decode(after))
+ end
+ end
+
+ def limit_value
+ @limit_value ||= [first, last, max_page_size].compact.min
+ end
+
+ def table
+ nodes.arel_table
+ end
+
+ def order_info
+ @order_info ||= nodes.order_values.first
+ end
+
+ def order_field
+ @order_field ||= order_info&.expr&.name || nodes.primary_key
+ end
+
+ def sort_direction
+ @order_direction ||= order_info&.direction || :desc
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/errors.rb b/lib/gitlab/graphql/errors.rb
new file mode 100644
index 00000000000..1d8e8307ab9
--- /dev/null
+++ b/lib/gitlab/graphql/errors.rb
@@ -0,0 +1,8 @@
+module Gitlab
+ module Graphql
+ module Errors
+ BaseError = Class.new(GraphQL::ExecutionError)
+ ArgumentError = Class.new(BaseError)
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/present/instrumentation.rb b/lib/gitlab/graphql/present/instrumentation.rb
index 6f2b26c9676..f87fd147b15 100644
--- a/lib/gitlab/graphql/present/instrumentation.rb
+++ b/lib/gitlab/graphql/present/instrumentation.rb
@@ -3,6 +3,8 @@ module Gitlab
module Present
class Instrumentation
def instrument(type, field)
+ return field unless field.metadata[:type_class]
+
presented_in = field.metadata[:type_class].owner
return field unless presented_in.respond_to?(:presenter_class)
return field unless presented_in.presenter_class