You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2019/08/21 08:29:49 UTC

[archiva] 02/02: Adding query param object for search queries

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

martin_s pushed a commit to branch feature/storage_refactoring
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 37a92817ef738ea0c0b82aff15605e65de7fc9dd
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Wed Aug 21 10:29:31 2019 +0200

    Adding query param object for search queries
---
 .../apache/archiva/metadata/QueryParameter.java    | 98 ++++++++++++++++++++++
 .../repository/AbstractMetadataRepository.java     | 20 +++--
 .../metadata/repository/MetadataRepository.java    | 11 ++-
 .../repository/AbstractMetadataRepositoryTest.java |  9 +-
 .../cassandra/CassandraMetadataRepository.java     | 15 ++--
 .../repository/file/FileMetadataRepository.java    | 10 +--
 .../repository/jcr/JcrMetadataRepository.java      | 58 +++++++++----
 7 files changed, 174 insertions(+), 47 deletions(-)

diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/QueryParameter.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/QueryParameter.java
new file mode 100644
index 0000000..a5a14d5
--- /dev/null
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/QueryParameter.java
@@ -0,0 +1,98 @@
+package org.apache.archiva.metadata;
+
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * This class is used to provide additional query parameters to search queries.
+ * These parameters are hints for the metadata repository implementation, some parameters may be ignored.
+ *
+ * The defaults are:
+ * <li>
+ *     <ul>Sort order: ascending</ul>
+ *     <ul>Offset: 0</ul>
+ *     <ul>Limit: Long.MAX_VALUE</ul>
+ *     <ul>Sort fields: empty, which means it depends on the query</ul>
+ * </li>
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+public class QueryParameter {
+
+    final boolean ascending;
+    final List<String> sortFields;
+    final long offset;
+    final long limit;
+
+    public QueryParameter(boolean isAscending, long offset, long limit, String... sortFields) {
+        this.ascending = isAscending;
+        this.offset = offset;
+        this.limit = limit;
+        this.sortFields = Arrays.asList(sortFields);
+    }
+
+    public QueryParameter(long offset, long limit) {
+        this.offset=offset;
+        this.limit = limit;
+        this.ascending = true;
+        this.sortFields = Collections.emptyList();
+    }
+
+    public QueryParameter(boolean isAscending, long offset, long limit) {
+        this.ascending = isAscending;
+        this.offset = offset;
+        this.limit = limit;
+        this.sortFields = Collections.emptyList();
+    }
+
+    public QueryParameter(long limit) {
+        this.offset=0;
+        this.ascending=true;
+        this.limit=limit;
+        this.sortFields = Collections.emptyList();
+    }
+
+    public QueryParameter() {
+        this.ascending = true;
+        this.sortFields = Collections.emptyList();
+        this.offset = 0;
+        this.limit = Long.MAX_VALUE;
+    }
+
+    public boolean isAscending() {
+        return ascending;
+    }
+
+    public List<String> getSortFields() {
+        return sortFields;
+    }
+
+    public long getOffset() {
+        return offset;
+    }
+
+    public long getLimit() {
+        return limit;
+    }
+}
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
index d3e18c4..7d72586 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/AbstractMetadataRepository.java
@@ -19,6 +19,7 @@ package org.apache.archiva.metadata.repository;
 * under the License.
 */
 
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.model.MetadataFacet;
 import org.apache.archiva.metadata.model.MetadataFacetFactory;
@@ -111,7 +112,7 @@ public abstract class AbstractMetadataRepository
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
+    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
         throws MetadataRepositoryException
     {
         throw new UnsupportedOperationException();
@@ -306,13 +307,13 @@ public abstract class AbstractMetadataRepository
     @Override
     public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz ) throws MetadataRepositoryException
     {
-        return getMetadataFacetStream( session, repositoryId, facetClazz, 0, Long.MAX_VALUE );
+        return getMetadataFacetStream( session, repositoryId, facetClazz, new QueryParameter());
     }
 
     @Override
     public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime ) throws MetadataRepositoryException
     {
-        return getArtifactsByDateRangeStream( session, repositoryId, startTime, endTime, 0, Long.MAX_VALUE );
+        return getArtifactsByDateRangeStream( session, repositoryId, startTime, endTime, new QueryParameter());
     }
 
     @Override
@@ -323,7 +324,7 @@ public abstract class AbstractMetadataRepository
     }
 
     @Override
-    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
+    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         throw new UnsupportedOperationException();
     }
@@ -337,7 +338,7 @@ public abstract class AbstractMetadataRepository
 
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
+    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         throw new UnsupportedOperationException();
     }
@@ -358,4 +359,13 @@ public abstract class AbstractMetadataRepository
     protected Class<? extends MetadataFacet> getFactoryClassForId( String facetId ) {
         return metadataService.getFactoryClassForId( facetId );
     }
+
+
+
+    @Override
+    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime)
+            throws MetadataRepositoryException {
+        return getArtifactsByDateRange(session, repoId, startTime, endTime, new QueryParameter());
+    }
+
 }
diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
index 68ba5e0..b0849cd 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/metadata/repository/MetadataRepository.java
@@ -19,6 +19,7 @@ package org.apache.archiva.metadata.repository;
  * under the License.
  */
 
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.model.MetadataFacet;
 import org.apache.archiva.metadata.model.ProjectMetadata;
@@ -157,7 +158,7 @@ public interface MetadataRepository
     <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz)
         throws MetadataRepositoryException;
 
-    <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries)
+    <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter)
         throws MetadataRepositoryException;
 
     /**
@@ -251,6 +252,10 @@ public interface MetadataRepository
     List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
         throws MetadataRepositoryException;
 
+    List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
+            throws MetadataRepositoryException;
+
+
     /**
      * Returns all the artifacts
      * @param session
@@ -263,8 +268,8 @@ public interface MetadataRepository
     Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
         throws MetadataRepositoryException;
 
-    Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId,
-                                                            ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries )
+    Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId,
+                                                           ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter)
         throws MetadataRepositoryException;
 
     Collection<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )
diff --git a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
index a13abdc..d34f8ab 100644
--- a/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
+++ b/archiva-modules/metadata/metadata-repository-api/src/test/java/org/apache/archiva/metadata/repository/AbstractMetadataRepositoryTest.java
@@ -20,26 +20,21 @@ package org.apache.archiva.metadata.repository;
  */
 
 import junit.framework.TestCase;
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.generic.GenericMetadataFacet;
 import org.apache.archiva.metadata.generic.GenericMetadataFacetFactory;
 import org.apache.archiva.metadata.model.*;
-import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
-import org.apache.archiva.repository.Repository;
 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.format.annotation.NumberFormat;
 import org.springframework.test.context.ContextConfiguration;
 
 import java.text.SimpleDateFormat;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.time.temporal.TemporalUnit;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -915,7 +910,7 @@ public abstract class AbstractMetadataRepositoryTest
         try ( RepositorySession session = getSessionFactory( ).createSession( ) )
         {
             tryAssert( ( ) -> {
-                Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class, 0, 100 );
+                Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class, new QueryParameter(0, 100));
                 assertNotNull( str );
                 List<TestMetadataFacet> result = str.collect( Collectors.toList( ) );
                 assertEquals( 100, result.size( ) );
diff --git a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
index aefa51d..21df69d 100644
--- a/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-cassandra/src/main/java/org/apache/archiva/metadata/repository/cassandra/CassandraMetadataRepository.java
@@ -38,6 +38,7 @@ import me.prettyprint.hector.api.mutation.Mutator;
 import me.prettyprint.hector.api.query.QueryResult;
 import me.prettyprint.hector.api.query.RangeSlicesQuery;
 import org.apache.archiva.configuration.ArchivaConfiguration;
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.model.CiManagement;
 import org.apache.archiva.metadata.model.Dependency;
@@ -70,13 +71,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.time.Instant;
-import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -88,7 +87,6 @@ import java.util.Spliterator;
 import java.util.UUID;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
@@ -1590,17 +1588,16 @@ public class CassandraMetadataRepository
      * Implementation is not very performant, because sorting is part of the stream. I do not know how to specify the sort
      * in the query.
      * 
+     * @param <T>
      * @param session
      * @param repositoryId
      * @param facetClazz
-     * @param offset
-     * @param maxEntries
-     * @param <T>
+     * @param queryParameter
      * @return
      * @throws MetadataRepositoryException
      */
     @Override
-    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
+    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
         final String facetId = metadataFacetFactory.getFacetId( );
@@ -1637,7 +1634,7 @@ public class CassandraMetadataRepository
             }
             return updateItem;
 
-        }), false ).sorted( (f1, f2) -> f1.getName()!=null ? f1.getName().compareTo( f2.getName() ) : 1 ).skip( offset ).limit( maxEntries );
+        }), false ).sorted( (f1, f2) -> f1.getName()!=null ? f1.getName().compareTo( f2.getName() ) : 1 ).skip( queryParameter.getOffset()).limit( queryParameter.getLimit());
     }
 
     @Override
@@ -1835,7 +1832,7 @@ public class CassandraMetadataRepository
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
+    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         return null;
     }
diff --git a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
index da7007e..eee6c02 100644
--- a/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-file/src/main/java/org/apache/archiva/metadata/repository/file/FileMetadataRepository.java
@@ -21,6 +21,7 @@ package org.apache.archiva.metadata.repository.file;
 
 import org.apache.archiva.configuration.ArchivaConfiguration;
 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.model.CiManagement;
 import org.apache.archiva.metadata.model.Dependency;
@@ -60,7 +61,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -352,7 +352,7 @@ public class FileMetadataRepository
     }
 
     @Override
-    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
+    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
         if (metadataFacetFactory==null) {
@@ -367,8 +367,8 @@ public class FileMetadataRepository
                 .filter( path -> Files.exists( path.resolve( searchFile ) ) )
                 .map(path -> directory.relativize(path).toString())
                 .sorted()
-                .skip( offset )
-                .limit(maxEntries)
+                .skip( queryParameter.getOffset())
+                .limit(queryParameter.getLimit())
                 .map(name -> getMetadataFacet( session, repositoryId, facetClazz, name ));
         } catch (IOException e) {
             throw new MetadataRepositoryException( e.getMessage( ), e );
@@ -517,7 +517,7 @@ public class FileMetadataRepository
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
+    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         return null;
     }
diff --git a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
index 404762d..fd3fd49 100644
--- a/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
+++ b/archiva-modules/plugins/metadata-store-jcr/src/main/java/org/apache/archiva/metadata/repository/jcr/JcrMetadataRepository.java
@@ -20,6 +20,7 @@ package org.apache.archiva.metadata.repository.jcr;
  */
 
 import com.google.common.collect.ImmutableMap;
+import org.apache.archiva.metadata.QueryParameter;
 import org.apache.archiva.metadata.model.ArtifactMetadata;
 import org.apache.archiva.metadata.model.CiManagement;
 import org.apache.archiva.metadata.model.Dependency;
@@ -49,7 +50,6 @@ import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.commons.cnd.ParseException;
-import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,7 +72,6 @@ import javax.jcr.query.RowIterator;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
-import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.*;
 import java.util.Map.Entry;
@@ -528,9 +527,30 @@ public class JcrMetadataRepository
         };
     }
 
+    private StringBuilder appendQueryParams(StringBuilder query, String selector, String defaultProperty, QueryParameter queryParameter) {
+        if (queryParameter.getSortFields().size()==0) {
+            query.append(" ORDER BY [").append(selector).append("].[").append(defaultProperty).append("]");
+            if (queryParameter.isAscending()) {
+                query.append(" ASC");
+            } else {
+                query.append(" DESC");
+            }
+        } else {
+            query.append(" ORDER BY");
+            for (String property : queryParameter.getSortFields()) {
+                query.append(" [").append(selector).append("].[").append(property).append("]");
+                if (queryParameter.isAscending()) {
+                    query.append(" ASC");
+                } else {
+                    query.append(" DESC");
+                }
+            }
+        }
+        return query;
+    }
+
     @Override
-    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz,
-        long offset, long maxEntries) throws MetadataRepositoryException
+    public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         final Session jcrSession = getSession( session );
         final MetadataFacetFactory<T> factory = metadataService.getFactory( facetClazz );
@@ -538,10 +558,11 @@ public class JcrMetadataRepository
         final String facetPath = '/'+getFacetPath( repositoryId, facetId );
         StringBuilder query = new StringBuilder("SELECT * FROM [");
         query.append(FACET_NODE_TYPE).append("] AS facet WHERE ISDESCENDANTNODE(facet, [")
-                .append(facetPath).append("]) ORDER BY [facet].[archiva:name]");
+                .append(facetPath).append("])");
+        appendQueryParams(query, "facet", "archiva:name", queryParameter);
         String q = query.toString();
-         Map<String, String> params = new HashMap<>( );
-        QueryResult result = runNativeJcrQuery( jcrSession, q, params, offset, maxEntries );
+        Map<String, String> params = new HashMap<>( );
+        QueryResult result = runNativeJcrQuery( jcrSession, q, params, queryParameter.getOffset(), queryParameter.getLimit());
         return StreamSupport.stream( createResultSpliterator( result, (Row row)-> {
             try
             {
@@ -744,7 +765,8 @@ public class JcrMetadataRepository
         }
     }
 
-    private String buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime) {
+    private StringBuilder buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime,
+                                                        QueryParameter queryParameter) {
         StringBuilder q = getArtifactQuery( repoId );
 
         if ( startTime != null )
@@ -755,19 +777,19 @@ public class JcrMetadataRepository
         {
             q.append(" AND [artifact].[whenGathered] <= $end");
         }
-        q.append(" ORDER BY [artifact].[whenGathered]");
-        return q.toString();
+        appendQueryParams(q, "artifact", "whenGathered", queryParameter);
+        return q;
     }
 
     private QueryResult queryArtifactByDateRange(Session jcrSession, String repositoryId,
                                                  ZonedDateTime startTime, ZonedDateTime endTime,
-                                                 long offset, long maxEntries) throws MetadataRepositoryException {
-        String q = buildArtifactByDateRangeQuery(repositoryId, startTime, endTime);
+                                                 QueryParameter queryParameter) throws MetadataRepositoryException {
+        String q = buildArtifactByDateRangeQuery(repositoryId, startTime, endTime, queryParameter).toString();
 
         try {
             Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
-            query.setOffset(offset);
-            query.setLimit(maxEntries);
+            query.setOffset(queryParameter.getOffset());
+            query.setLimit(queryParameter.getLimit());
             ValueFactory valueFactory = jcrSession.getValueFactory();
             if (startTime != null) {
                 query.bindValue("start", valueFactory.createValue(createCalendar(startTime)));
@@ -782,7 +804,7 @@ public class JcrMetadataRepository
     }
 
     @Override
-    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime )
+    public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter )
         throws MetadataRepositoryException
     {
         final Session jcrSession = getSession( session );
@@ -790,7 +812,7 @@ public class JcrMetadataRepository
         List<ArtifactMetadata> artifacts;
         try
         {
-            QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, 0, Long.MAX_VALUE);
+            QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, queryParameter);
 
             artifacts = new ArrayList<>();
             for ( Node n : JcrUtils.getNodes( result ) )
@@ -806,10 +828,10 @@ public class JcrMetadataRepository
     }
 
     @Override
-    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
+    public Stream<ArtifactMetadata> getArtifactsByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
     {
         final Session jcrSession = getSession( session );
-        QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, offset, maxEntries);
+        QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, queryParameter);
         return StreamSupport.stream(createResultSpliterator(result, (row) -> {
             try {
                 return getArtifactFromNode(repositoryId, row.getNode("artifact"));