DATACOUCH-237 - Prevent groupby on generated count queries

Fixes #119
This commit is contained in:
markramach
2016-07-06 15:44:13 -05:00
committed by Simon Baslé
parent a40919ef8e
commit f18f61e371
3 changed files with 255 additions and 2 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2012-2016 the original author or authors
*
* Licensed 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.springframework.data.couchbase.repository.query;
import java.util.Iterator;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.parser.PartTree;
import com.couchbase.client.java.query.dsl.Expression;
import com.couchbase.client.java.query.dsl.path.LimitPath;
import com.couchbase.client.java.query.dsl.path.WherePath;
/**
*
* @author Mark Ramach
*
*/
public class N1qlCountQueryCreator extends N1qlQueryCreator {
public N1qlCountQueryCreator(PartTree tree, ParameterAccessor parameters, WherePath selectFrom,
CouchbaseConverter converter, CouchbaseQueryMethod queryMethod) {
super(tree, new CountParameterAccessor(parameters), selectFrom, converter, queryMethod);
}
@Override
protected LimitPath complete(Expression criteria, Sort sort) {
// Sorting is not allowed on aggregate count queries.
return super.complete(criteria, null);
}
private static class CountParameterAccessor implements ParameterAccessor {
private ParameterAccessor delegate;
public CountParameterAccessor(ParameterAccessor delegate) {
this.delegate = delegate;
}
public Pageable getPageable() {
return delegate.getPageable() != null ? new CountPageable(delegate.getPageable()) : null;
}
public Sort getSort() {
return null;
}
public Class<?> getDynamicProjection() {
return delegate.getDynamicProjection();
}
public Object getBindableValue(int index) {
return delegate.getBindableValue(index);
}
public boolean hasBindableNullValue() {
return delegate.hasBindableNullValue();
}
public Iterator<Object> iterator() {
return delegate.iterator();
}
}
private static class CountPageable implements Pageable {
private Pageable delegate;
public CountPageable(Pageable delegate) {
this.delegate = delegate;
}
public int getPageNumber() {
return delegate.getPageNumber();
}
public int getPageSize() {
return delegate.getPageSize();
}
public int getOffset() {
return delegate.getOffset();
}
public Sort getSort() {
// Sorting is not allowed on aggregate count queries.
return null;
}
public Pageable next() {
return delegate.next();
}
public Pageable previousOrFirst() {
return delegate.previousOrFirst();
}
public Pageable first() {
return delegate.first();
}
public boolean hasPrevious() {
return delegate.hasPrevious();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors
* Copyright 2012-2016 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ public class PartTreeN1qlBasedQuery extends AbstractN1qlBasedQuery {
Expression bucket = i(getCouchbaseOperations().getCouchbaseBucket().name());
WherePath countFrom = select(count("*").as(CountFragment.COUNT_ALIAS)).from(bucket);
N1qlQueryCreator queryCreator = new N1qlQueryCreator(partTree, accessor, countFrom,
N1qlQueryCreator queryCreator = new N1qlCountQueryCreator(partTree, accessor, countFrom,
getCouchbaseOperations().getConverter(), getQueryMethod());
return queryCreator.createQuery();
}