You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2021/05/11 08:07:10 UTC

[sling-org-apache-sling-graphql-core] branch SLING-10309/experiment updated: SLING-10309 - use our own pagination interfaces

This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch SLING-10309/experiment
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-graphql-core.git


The following commit(s) were added to refs/heads/SLING-10309/experiment by this push:
     new d3b13cc  SLING-10309 - use our own pagination interfaces
d3b13cc is described below

commit d3b13cc2dcf4dcd4c8dc9ae9edb368f52b42e8b5
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Tue May 11 10:06:47 2021 +0200

    SLING-10309 - use our own pagination interfaces
---
 .../apache/sling/graphql/api/pagination/Edge.java  |  26 +++++
 .../sling/graphql/api/pagination/PageInfo.java     |  28 ++++++
 .../sling/graphql/api/pagination/ResultsPage.java  |  30 ++++++
 .../sling/graphql/core/engine/PaginationTest.java  | 108 ++++++++-------------
 4 files changed, 124 insertions(+), 68 deletions(-)

diff --git a/src/main/java/org/apache/sling/graphql/api/pagination/Edge.java b/src/main/java/org/apache/sling/graphql/api/pagination/Edge.java
new file mode 100644
index 0000000..9b234db
--- /dev/null
+++ b/src/main/java/org/apache/sling/graphql/api/pagination/Edge.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.sling.graphql.api.pagination;
+
+ /** Edges provide paginated data as per https://relay.dev/graphql/connections.htm */
+public interface Edge<T> {
+    T getNode();
+    String getCursor();
+}
diff --git a/src/main/java/org/apache/sling/graphql/api/pagination/PageInfo.java b/src/main/java/org/apache/sling/graphql/api/pagination/PageInfo.java
new file mode 100644
index 0000000..dd07408
--- /dev/null
+++ b/src/main/java/org/apache/sling/graphql/api/pagination/PageInfo.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.sling.graphql.api.pagination;
+
+ /** Information about a results page as per https://relay.dev/graphql/connections.htm */
+public interface PageInfo {
+    String getStartCursor();
+    String getEndCursor();
+    boolean isHasPreviousPage();
+    boolean isHasNextPage();
+}
diff --git a/src/main/java/org/apache/sling/graphql/api/pagination/ResultsPage.java b/src/main/java/org/apache/sling/graphql/api/pagination/ResultsPage.java
new file mode 100644
index 0000000..a946407
--- /dev/null
+++ b/src/main/java/org/apache/sling/graphql/api/pagination/ResultsPage.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.sling.graphql.api.pagination;
+
+import java.util.List;
+
+/** This is what https://relay.dev/graphql/connections.htm calls a "connection".
+ *  It actually represents a page of results, so why not call it that?
+*/
+public interface ResultsPage<T> {
+    List<Edge<T>> getEdges();
+    PageInfo getPageInfo();
+}
diff --git a/src/test/java/org/apache/sling/graphql/core/engine/PaginationTest.java b/src/test/java/org/apache/sling/graphql/core/engine/PaginationTest.java
index 995beba..285ca45 100644
--- a/src/test/java/org/apache/sling/graphql/core/engine/PaginationTest.java
+++ b/src/test/java/org/apache/sling/graphql/core/engine/PaginationTest.java
@@ -23,8 +23,8 @@ import java.util.List;
 
 import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
 
-import static org.junit.Assert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.apache.sling.graphql.core.mocks.TestUtil;
 import org.jetbrains.annotations.NotNull;
@@ -33,16 +33,14 @@ import org.apache.sling.graphql.core.mocks.CharacterTypeResolver;
 import org.apache.sling.graphql.core.mocks.HumanDTO;
 import org.apache.sling.graphql.api.SlingDataFetcher;
 import org.apache.sling.graphql.api.SlingDataFetcherEnvironment;
+import org.apache.sling.graphql.api.pagination.Edge;
+import org.apache.sling.graphql.api.pagination.PageInfo;
+import org.apache.sling.graphql.api.pagination.ResultsPage;
 import org.junit.Test;
 
-import graphql.relay.Connection;
-import graphql.relay.ConnectionCursor;
-import graphql.relay.Edge;
-import graphql.relay.PageInfo;
-
 public class PaginationTest extends ResourceQueryTestBase {
 
-    static class ConnectionDataFetcher implements SlingDataFetcher<Connection<HumanDTO>> {
+    static class ConnectionDataFetcher implements SlingDataFetcher<Object> {
         private List<HumanDTO> humans = new ArrayList<>();
 
         ConnectionDataFetcher(List<HumanDTO> humans) {
@@ -50,49 +48,27 @@ public class PaginationTest extends ResourceQueryTestBase {
         }
 
         @Override
-        public @Nullable Connection<HumanDTO> get(@NotNull SlingDataFetcherEnvironment e) throws Exception {
+        public @Nullable Object get(@NotNull SlingDataFetcherEnvironment e) throws Exception {
             final String cursor = e.getArgument("after", null);
             final int limit = e.getArgument("limit", 2);
-            return new DataConnection(humans, cursor, limit);
-        }
-    }
-
-    static class Cursor implements ConnectionCursor {
-        private final String value;
-        Cursor(HumanDTO dto) {
-            value = dto.getId();
-        }
-        Cursor(String c) {
-            value = c;
-        }
-        @Override
-        public String getValue() {
-            return value == null ? "" : value;
-        }
-        @Override
-        public String toString() {
-            return getValue();
-        }
-        public boolean isEmpty() {
-            return value == null || value.length() == 0;
+            return new HumansResultPage(humans, cursor, limit);
         }
     }
 
-    static class DataConnection implements Connection<HumanDTO> {
+    static class HumansResultPage implements ResultsPage<HumanDTO>,PageInfo {
 
-        private final Cursor startCursor;
-        private Cursor endCursor;
+        private final String startCursor;
+        private String endCursor;
         private boolean hasPreviousPage;
         private boolean hasNextPage;
-        private final int limit; 
-        private final List<Edge<HumanDTO>> edges = new ArrayList();
-        private final PageInfo pageInfo;
+        private final List<Edge<HumanDTO>> edges = new ArrayList<>();
 
-        DataConnection(List<HumanDTO> humans, String cursor, int limit) {
-            this.startCursor = new Cursor(cursor);
-            this.limit = limit;
+        HumansResultPage(List<HumanDTO> humans, String cursor, int limit) {
+            this.startCursor = cursor == null ? "" : cursor;
 
-            // skip to cursor and add the following humanDTOs as edges
+            // TODO this should be generalized so that data can be provided as 
+            // a data source with "skip after cursor" functionality, and the
+            // rest of this class is then generic
             boolean inRange = false;
             int remaining = limit;
             for(HumanDTO dto : humans) {
@@ -110,12 +86,12 @@ public class PaginationTest extends ResourceQueryTestBase {
                         }
 
                         @Override
-                        public ConnectionCursor getCursor() {
-                            return new Cursor(dto);
+                        public String getCursor() {
+                            return dto.getId();
                         }
 
                     });
-                    endCursor = new Cursor(dto);
+                    endCursor = dto.getId();
                 } else if(startCursor.isEmpty()) {
                     inRange = true;
                     hasPreviousPage = false;
@@ -124,42 +100,38 @@ public class PaginationTest extends ResourceQueryTestBase {
                     hasPreviousPage = true;
                 }
             }
+        }
 
-            // setup page info
-            pageInfo = new PageInfo() {
-                @Override
-                public ConnectionCursor getStartCursor() {
-                    return startCursor;
-                }
-
-                @Override
-                public ConnectionCursor getEndCursor() {
-                    return endCursor;
-                }
+        @Override
+        public List<Edge<HumanDTO>> getEdges() {
+            return edges;
+        }
 
-                @Override
-                public boolean isHasPreviousPage() {
-                    return hasPreviousPage;
-                }
+        @Override
+        public PageInfo getPageInfo() {
+            return this;
+        }
 
-                @Override
-                public boolean isHasNextPage() {
-                    return hasNextPage;
-                }
+        @Override
+        public String getStartCursor() {
+            return startCursor;
+        }
 
-            };
+        @Override
+        public String getEndCursor() {
+            return endCursor;
         }
 
         @Override
-        public List<Edge<HumanDTO>> getEdges() {
-            return edges;
+        public boolean isHasPreviousPage() {
+            return hasPreviousPage;
         }
 
         @Override
-        public PageInfo getPageInfo() {
-            return pageInfo;
+        public boolean isHasNextPage() {
+            return hasNextPage;
         }
-    }
+}
 
     @Override
     protected void setupAdditionalServices() {