You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2026/08/30 18:36:04 UTC
(cayenne) branch master updated (debcdc94d -> 0daf3cc6c)
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
from debcdc94d removing dead code - EOQuery
new 8ba638365 Query cleanup .. route() can be implemented at the top
new d86f8be72 Query cleanup... AbstractQuery is uneeded
new 34aaa780e Query cleanup... Unwinding CacheableQuery
new f357868dd Query cleanup: QueryChain is deprecated
new 0daf3cc6c Cleanup: getting rid of obsolete TranslatableQueryWrapper
The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../apache/cayenne/lifecycle/id/StringIdQuery.java | 19 +-
.../translator/select/DefaultSelectTranslator.java | 5 +-
.../select/DescriptorColumnExtractor.java | 8 +-
.../translator/select/FluentSelectWrapper.java | 77 -
.../translator/select/HavingTranslationStage.java | 2 +-
.../translator/select/IdColumnExtractor.java | 2 +-
.../translator/select/PrefetchNodeStage.java | 5 +-
.../select/QualifierTranslationStage.java | 2 +-
.../access/translator/select/SQLResultStage.java | 2 +-
.../translator/select/SelectTranslatorContext.java | 22 +-
.../select/TranslatableQueryWrapper.java | 56 -
.../org/apache/cayenne/exp/parser/ASTSubquery.java | 18 +-
.../apache/cayenne/map/SelectQueryDescriptor.java | 1 -
.../org/apache/cayenne/query/AbstractQuery.java | 118 --
.../java/org/apache/cayenne/query/BatchQuery.java | 8 -
.../org/apache/cayenne/query/CacheableQuery.java | 5 -
.../java/org/apache/cayenne/query/EJBQLQuery.java | 12 -
.../org/apache/cayenne/query/FluentSelect.java | 85 +-
.../org/apache/cayenne/query/MappedSelect.java | 14 +-
.../org/apache/cayenne/query/ProcedureQuery.java | 49 +-
.../main/java/org/apache/cayenne/query/Query.java | 15 +-
.../java/org/apache/cayenne/query/QueryChain.java | 4 +
.../java/org/apache/cayenne/query/SQLTemplate.java | 73 +-
.../java/org/apache/cayenne/query/SelectById.java | 1473 ++++++++++----------
.../java/org/apache/cayenne/query/package.html | 1 -
.../DataContextEJBQLFunctionalExpressionsIT.java | 21 +-
.../cayenne/access/DataContextQueryCachingIT.java | 6 +-
.../select/ColumnDescriptorStageTest.java | 5 +-
.../select/CustomColumnSetExtractorTest.java | 14 +-
.../DbAdapterDelegatedSelectTranslatorIT.java | 8 +-
.../select/DbEntityColumnExtractorTest.java | 9 +-
.../select/DescriptorColumnExtractorIT.java | 4 +-
.../select/DescriptorColumnExtractorTest.java | 5 +-
.../translator/select/DistinctStageTest.java | 13 +-
.../access/translator/select/GroupByStageTest.java | 5 +-
.../select/HavingTranslationStageTest.java | 7 +-
.../translator/select/IdColumnExtractorTest.java | 9 +-
.../translator/select/LimitOffsetStageTest.java | 5 +-
.../translator/select/MockFluentSelectBuilder.java | 101 ++
.../translator/select/MockQueryWrapperBuilder.java | 141 --
.../select/MockSelectTranslatorContext.java | 5 +-
.../translator/select/ObjPathProcessorIT.java | 2 +-
.../translator/select/OrderingStageTest.java | 5 +-
.../select/QualifierTranslationStageTest.java | 7 +-
.../QualifierTranslatorExistExpressionIT.java | 24 +-
.../translator/select/QualifierTranslatorIT.java | 6 +-
.../translator/select/QualifierTranslatorTest.java | 5 +-
.../cayenne/exp/property/SelfPropertyTest.java | 8 +-
.../cayenne/map/SelectQueryDescriptorTest.java | 2 +-
.../apache/cayenne/query/AbstractQueryTest.java | 65 -
.../apache/cayenne/query/MockAbstractQuery.java | 38 -
.../apache/cayenne/query/ProcedureQueryTest.java | 22 +
.../org/apache/cayenne/query/SQLTemplateTest.java | 46 +
.../_cayenne-guide/part2/objectContext.adoc | 13 +-
54 files changed, 1253 insertions(+), 1424 deletions(-)
delete mode 100644 cayenne/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
delete mode 100644 cayenne/src/main/java/org/apache/cayenne/access/translator/select/TranslatableQueryWrapper.java
delete mode 100644 cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
create mode 100644 cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockFluentSelectBuilder.java
delete mode 100644 cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockQueryWrapperBuilder.java
delete mode 100644 cayenne/src/test/java/org/apache/cayenne/query/AbstractQueryTest.java
delete mode 100644 cayenne/src/test/java/org/apache/cayenne/query/MockAbstractQuery.java
(cayenne) 05/05: Cleanup: getting rid of obsolete TranslatableQueryWrapper
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 0daf3cc6c6495794ca273cbce58a8b33f5f28f0e
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Aug 30 14:33:45 2026 -0400
Cleanup: getting rid of obsolete TranslatableQueryWrapper
---
.../translator/select/DefaultSelectTranslator.java | 5 +-
.../select/DescriptorColumnExtractor.java | 8 +-
.../translator/select/FluentSelectWrapper.java | 77 -----------
.../translator/select/HavingTranslationStage.java | 2 +-
.../translator/select/IdColumnExtractor.java | 2 +-
.../translator/select/PrefetchNodeStage.java | 5 +-
.../select/QualifierTranslationStage.java | 2 +-
.../access/translator/select/SQLResultStage.java | 2 +-
.../translator/select/SelectTranslatorContext.java | 22 +++-
.../select/TranslatableQueryWrapper.java | 56 --------
.../org/apache/cayenne/exp/parser/ASTSubquery.java | 18 +--
.../select/ColumnDescriptorStageTest.java | 5 +-
.../select/CustomColumnSetExtractorTest.java | 14 +-
.../DbAdapterDelegatedSelectTranslatorIT.java | 8 +-
.../select/DbEntityColumnExtractorTest.java | 9 +-
.../select/DescriptorColumnExtractorIT.java | 4 +-
.../select/DescriptorColumnExtractorTest.java | 5 +-
.../translator/select/DistinctStageTest.java | 13 +-
.../access/translator/select/GroupByStageTest.java | 5 +-
.../select/HavingTranslationStageTest.java | 7 +-
.../translator/select/IdColumnExtractorTest.java | 9 +-
.../translator/select/LimitOffsetStageTest.java | 5 +-
.../translator/select/MockFluentSelectBuilder.java | 101 +++++++++++++++
.../translator/select/MockQueryWrapperBuilder.java | 141 ---------------------
.../select/MockSelectTranslatorContext.java | 5 +-
.../translator/select/ObjPathProcessorIT.java | 2 +-
.../translator/select/OrderingStageTest.java | 5 +-
.../select/QualifierTranslationStageTest.java | 7 +-
.../QualifierTranslatorExistExpressionIT.java | 24 ++--
.../translator/select/QualifierTranslatorIT.java | 6 +-
.../translator/select/QualifierTranslatorTest.java | 5 +-
.../cayenne/exp/property/SelfPropertyTest.java | 8 +-
32 files changed, 215 insertions(+), 372 deletions(-)
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
index 932aae46a..567e71b97 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
@@ -38,11 +38,10 @@ public class DefaultSelectTranslator implements SelectTranslator {
@Override
public TranslatedSelect translate(Select<?> query, DbAdapter adapter, EntityResolver resolver) {
- if (!(query instanceof FluentSelect)) {
+ if (!(query instanceof FluentSelect<?, ?> fluentSelect)) {
throw new CayenneRuntimeException("Unsupported type of Select query %s", query);
}
- SelectTranslatorContext context = new SelectTranslatorContext(
- new FluentSelectWrapper((FluentSelect<?, ?>) query), adapter, resolver, null);
+ SelectTranslatorContext context = new SelectTranslatorContext(fluentSelect, adapter, resolver, null);
context.translate();
return context.getTranslation();
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
index 173f78a49..86094a32a 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
@@ -66,14 +66,14 @@ class DescriptorColumnExtractor extends BaseColumnExtractor implements PropertyV
if(prefix != null && prefix.hasMarker(CayennePath.PREFETCH_MARKER)) {
type = SelectTranslatorContext.DescriptorType.PREFETCH;
labelPrefix = prefix;
- if(context.getQuery().needsResultSetMapping()) {
+ if(context.needsResultSetMapping()) {
entityResult = context.getRootEntityResult();
if (entityResult == null) {
throw new CayenneRuntimeException("Can't process prefetch descriptor without root.");
}
}
} else {
- if(context.getQuery().needsResultSetMapping()) {
+ if(context.needsResultSetMapping()) {
entityResult = new EntityResult(descriptor.getObjectClass());
newEntityResult = true;
}
@@ -175,13 +175,13 @@ class DescriptorColumnExtractor extends BaseColumnExtractor implements PropertyV
private void addEntityResultField(DbAttribute attribute) {
String name = labelPrefix.dot(attribute.getName()).value();
- if(context.getQuery().needsResultSetMapping()) {
+ if(context.needsResultSetMapping()) {
entityResult.addDbField(name, name);
}
}
private void addEntityResultField(CayennePath pathForFlattenedAttribute) {
- if (context.getQuery().needsResultSetMapping()) {
+ if (context.needsResultSetMapping()) {
String nameForFlattenedAttribute = pathForFlattenedAttribute.value();
entityResult.addDbField(nameForFlattenedAttribute, nameForFlattenedAttribute);
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
deleted file mode 100644
index 8eb442d9b..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.access.translator.select;
-
-import java.util.Collection;
-import java.util.Objects;
-
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.property.Property;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.FluentSelect;
-import org.apache.cayenne.query.Ordering;
-import org.apache.cayenne.query.QueryMetadata;
-
-/**
- * @since 4.2
- */
-public class FluentSelectWrapper implements TranslatableQueryWrapper {
-
- private final FluentSelect<?, ?> select;
-
- public FluentSelectWrapper(FluentSelect<?, ?> select) {
- this.select = Objects.requireNonNull(select);
- }
-
- @Override
- public boolean isDistinct() {
- return select.isDistinct();
- }
-
- @Override
- public QueryMetadata getMetaData(EntityResolver resolver) {
- return select.getMetaData(resolver);
- }
-
- @Override
- public Expression getQualifier() {
- return select.getWhere();
- }
-
- @Override
- public Collection<Ordering> getOrderings() {
- return select.getOrderings();
- }
-
- @Override
- public Collection<Property<?>> getColumns() {
- return select.getColumns();
- }
-
- @Override
- public Expression getHavingQualifier() {
- return select.getHaving();
- }
-
- @Override
- public FluentSelect<?, ?> unwrap() {
- return select;
- }
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/HavingTranslationStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/HavingTranslationStage.java
index bda51f784..637816796 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/HavingTranslationStage.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/HavingTranslationStage.java
@@ -29,7 +29,7 @@ class HavingTranslationStage implements TranslationStage {
@Override
public void perform(SelectTranslatorContext context) {
- Expression expression = context.getQuery().getHavingQualifier();
+ Expression expression = context.getQuery().getHaving();
QualifierTranslator translator = context.getQualifierTranslator();
Node qualifier = translator.translate(expression);
if(qualifier != null) {
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/IdColumnExtractor.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/IdColumnExtractor.java
index 8bc9cea29..d38b2bffe 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/IdColumnExtractor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/IdColumnExtractor.java
@@ -44,7 +44,7 @@ class IdColumnExtractor extends BaseColumnExtractor {
IdColumnExtractor(SelectTranslatorContext context, ObjEntity objEntity) {
this(context, objEntity.getDbEntity());
this.objEntity = objEntity;
- if(context.getQuery().needsResultSetMapping()) {
+ if(context.needsResultSetMapping()) {
this.result = new EntityResult(objEntity.getName());
}
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java
index 3717d68ae..0f263aaff 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java
@@ -37,7 +37,6 @@ import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.query.PrefetchSelectQuery;
import org.apache.cayenne.query.PrefetchTreeNode;
import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.Select;
import org.apache.cayenne.reflect.ClassDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -131,13 +130,11 @@ class PrefetchNodeStage implements TranslationStage {
}
private void processPrefetchQuery(SelectTranslatorContext context) {
- Select<?> select = context.getQuery().unwrap();
- if(!(select instanceof PrefetchSelectQuery)) {
+ if(!(context.getQuery() instanceof PrefetchSelectQuery<?> prefetchSelectQuery)) {
return;
}
PathTranslator pathTranslator = context.getPathTranslator();
- PrefetchSelectQuery<?> prefetchSelectQuery = (PrefetchSelectQuery<?>) select;
for(ASTPath prefetchPath: prefetchSelectQuery.getResultPaths()) {
ASTDbPath pathExp = (ASTDbPath) context.getMetadata()
.getClassDescriptor().getEntity().translateToDbPath(prefetchPath);
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslationStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslationStage.java
index 59082d996..c94e99700 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslationStage.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslationStage.java
@@ -33,7 +33,7 @@ class QualifierTranslationStage implements TranslationStage {
public void perform(SelectTranslatorContext context) {
QualifierTranslator translator = context.getQualifierTranslator();
- Expression expression = context.getQuery().getQualifier();
+ Expression expression = context.getQuery().getWhere();
// Attaching Obj entity's qualifier
ObjEntity entity = context.getMetadata().getObjEntity();
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SQLResultStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SQLResultStage.java
index 8a1dc9a27..1250bd2a2 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SQLResultStage.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SQLResultStage.java
@@ -28,7 +28,7 @@ public class SQLResultStage implements TranslationStage {
@Override
public void perform(SelectTranslatorContext context) {
- if(context.getParentContext() != null || !context.getQuery().needsResultSetMapping()) {
+ if(context.getParentContext() != null || !context.needsResultSetMapping()) {
return;
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslatorContext.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslatorContext.java
index a13d605d7..46f917b41 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslatorContext.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/SelectTranslatorContext.java
@@ -34,6 +34,7 @@ import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.EntityResult;
import org.apache.cayenne.map.SQLResult;
+import org.apache.cayenne.query.FluentSelect;
import org.apache.cayenne.query.Ordering;
import org.apache.cayenne.query.QueryMetadata;
@@ -95,8 +96,10 @@ class SelectTranslatorContext implements SQLGenerationContext {
private final List<PSParameter<?>> bindings;
// Translated query
- private final TranslatableQueryWrapper query;
+ private final FluentSelect<?, ?> query;
private final QueryMetadata metadata;
+ // whether the query result must be mapped explicitly, i.e. it selects a custom set of columns
+ private final boolean needsResultSetMapping;
private final EntityResolver resolver;
private final DbAdapter adapter;
@@ -131,7 +134,7 @@ class SelectTranslatorContext implements SQLGenerationContext {
private SQLResult sqlResult;
private EntityResult rootEntityResult;
- SelectTranslatorContext(TranslatableQueryWrapper query, DbAdapter adapter, EntityResolver resolver, SelectTranslatorContext parentContext) {
+ SelectTranslatorContext(FluentSelect<?, ?> query, DbAdapter adapter, EntityResolver resolver, SelectTranslatorContext parentContext) {
this.query = query;
this.adapter = adapter;
this.resolver = resolver;
@@ -144,7 +147,9 @@ class SelectTranslatorContext implements SQLGenerationContext {
this.pathTranslator = new PathTranslator(this);
this.qualifierTranslator = new QualifierTranslator(this);
this.resultNodeList = new LinkedList<>();
- if (query.needsResultSetMapping()) {
+ Collection<Property<?>> queryColumns = query.getColumns();
+ this.needsResultSetMapping = queryColumns != null && !queryColumns.isEmpty();
+ if (needsResultSetMapping) {
this.sqlResult = new SQLResult();
}
}
@@ -211,10 +216,17 @@ class SelectTranslatorContext implements SQLGenerationContext {
return tableTree.getNodeCount();
}
- TranslatableQueryWrapper getQuery() {
+ FluentSelect<?, ?> getQuery() {
return query;
}
+ /**
+ * @return whether the query selects a custom set of columns and thus needs an explicit result set mapping
+ */
+ boolean needsResultSetMapping() {
+ return needsResultSetMapping;
+ }
+
QueryMetadata getMetadata() {
return metadata;
}
@@ -243,7 +255,7 @@ class SelectTranslatorContext implements SQLGenerationContext {
return hasAggregate;
}
- if (getQuery().getHavingQualifier() != null) {
+ if (getQuery().getHaving() != null) {
return (hasAggregate = true);
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TranslatableQueryWrapper.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TranslatableQueryWrapper.java
deleted file mode 100644
index 2c9697827..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TranslatableQueryWrapper.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.access.translator.select;
-
-import java.util.Collection;
-
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.property.Property;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.Ordering;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.Select;
-
-/**
- * This interface allows transparently use different queries (namely SelectQuery, ObjectSelect and ColumnSelect)
- * in translator and as subqueries.
- *
- * @since 4.2
- */
-public interface TranslatableQueryWrapper {
-
- boolean isDistinct();
-
- QueryMetadata getMetaData(EntityResolver resolver);
-
- Expression getQualifier();
-
- Collection<Ordering> getOrderings();
-
- Collection<Property<?>> getColumns();
-
- Expression getHavingQualifier();
-
- Select<?> unwrap();
-
- default boolean needsResultSetMapping() {
- return getColumns() != null && !getColumns().isEmpty();
- }
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java b/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
index a736c5625..94f28f526 100644
--- a/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
@@ -23,8 +23,6 @@ import java.io.IOException;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.Persistent;
-import org.apache.cayenne.access.translator.select.FluentSelectWrapper;
-import org.apache.cayenne.access.translator.select.TranslatableQueryWrapper;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.TraversalHandler;
import org.apache.cayenne.query.FluentSelect;
@@ -46,13 +44,9 @@ public class ASTSubquery extends SimpleNode {
}
};
- private final TranslatableQueryWrapper query;
+ private final FluentSelect<?, ?> query;
public ASTSubquery(FluentSelect<?, ?> query) {
- this(new FluentSelectWrapper(query));
- }
-
- public ASTSubquery(TranslatableQueryWrapper query) {
super(0);
this.query = query;
}
@@ -71,15 +65,15 @@ public class ASTSubquery extends SimpleNode {
throw new UnsupportedOperationException("Can't evaluate subquery expression against non-persistent object");
}
validateForInmemory(query);
- return context.select(query.unwrap());
+ return context.select(query);
}
/**
* Check that we can execute this subquery directly
*/
- private void validateForInmemory(TranslatableQueryWrapper query) {
- query.getQualifier().traverse(IN_MEMORY_VALIDATOR);
- query.getHavingQualifier().traverse(IN_MEMORY_VALIDATOR);
+ private void validateForInmemory(FluentSelect<?, ?> query) {
+ query.getWhere().traverse(IN_MEMORY_VALIDATOR);
+ query.getHaving().traverse(IN_MEMORY_VALIDATOR);
for(Ordering ordering : query.getOrderings()) {
ordering.getSortSpec().traverse(IN_MEMORY_VALIDATOR);
}
@@ -100,7 +94,7 @@ public class ASTSubquery extends SimpleNode {
out.append("EXISTS");
}
- public TranslatableQueryWrapper getQuery() {
+ public FluentSelect<?, ?> getQuery() {
return query;
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ColumnDescriptorStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ColumnDescriptorStageTest.java
index 42bde85de..f5b611a30 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ColumnDescriptorStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ColumnDescriptorStageTest.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.access.jdbc.RSColumn;
import org.apache.cayenne.access.sqlbuilder.sqltree.EmptyNode;
import org.apache.cayenne.exp.path.CayennePath;
import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -31,13 +32,13 @@ public class ColumnDescriptorStageTest {
@Test
public void perform() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withDistinct(true)
.withMetaData(new MockQueryMetadataBuilder()
.withSuppressDistinct()
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
context.addResultNode(new EmptyNode());
context.addResultNode(new EmptyNode(), CayennePath.of("key"));
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/CustomColumnSetExtractorTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/CustomColumnSetExtractorTest.java
index a8bc03019..5ff0c641b 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/CustomColumnSetExtractorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/CustomColumnSetExtractorTest.java
@@ -33,6 +33,7 @@ import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -42,13 +43,17 @@ public class CustomColumnSetExtractorTest extends BaseColumnExtractorTest {
@Test
public void extractWithoutPrefix() {
DbEntity mockDbEntity = createMockDbEntity("mock");
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
- .withNeedsResultSetMapping(true)
+ BaseProperty<?> property0 = PropertyFactory.createBase(ExpressionFactory.dbPathExp("name"), String.class);
+ Collection<Property<?>> properties = Collections.singleton(property0);
+
+ // a query with an explicit column set is what triggers the result set mapping
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
+ .withColumns(properties)
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(mockDbEntity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DataMap dataMap = new DataMap();
dataMap.addDbEntity(mockDbEntity);
@@ -69,9 +74,6 @@ public class CustomColumnSetExtractorTest extends BaseColumnExtractorTest {
EntityResolver resolver = new EntityResolver();
resolver.addDataMap(dataMap);
- BaseProperty<?> property0 = PropertyFactory.createBase(ExpressionFactory.dbPathExp("name"), String.class);
- Collection<Property<?>> properties = Collections.singleton(property0);
-
CustomColumnSetExtractor extractor = new CustomColumnSetExtractor(context, properties);
extractor.extract();
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbAdapterDelegatedSelectTranslatorIT.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbAdapterDelegatedSelectTranslatorIT.java
index f9bb44035..98e17375d 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbAdapterDelegatedSelectTranslatorIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbAdapterDelegatedSelectTranslatorIT.java
@@ -781,7 +781,7 @@ public class DbAdapterDelegatedSelectTranslatorIT {
));
query.select(env.context());
- SelectTranslatorContext context = new SelectTranslatorContext(new FluentSelectWrapper(query), env.dataNode().getAdapter(),
+ SelectTranslatorContext context = new SelectTranslatorContext(query, env.dataNode().getAdapter(),
env.context().getEntityResolver(), null);
context.translate();
@@ -798,7 +798,7 @@ public class DbAdapterDelegatedSelectTranslatorIT {
));
query.select(env.context());
- SelectTranslatorContext context = new SelectTranslatorContext(new FluentSelectWrapper(query), env.dataNode().getAdapter(),
+ SelectTranslatorContext context = new SelectTranslatorContext(query, env.dataNode().getAdapter(),
env.context().getEntityResolver(), null);
context.translate();
@@ -815,7 +815,7 @@ public class DbAdapterDelegatedSelectTranslatorIT {
));
query.select(env.context());
- SelectTranslatorContext context = new SelectTranslatorContext(new FluentSelectWrapper(query), env.dataNode().getAdapter(),
+ SelectTranslatorContext context = new SelectTranslatorContext(query, env.dataNode().getAdapter(),
env.context().getEntityResolver(), null);
context.translate();
@@ -831,7 +831,7 @@ public class DbAdapterDelegatedSelectTranslatorIT {
));
query.select(env.context());
- SelectTranslatorContext context = new SelectTranslatorContext(new FluentSelectWrapper(query), env.dataNode().getAdapter(),
+ SelectTranslatorContext context = new SelectTranslatorContext(query, env.dataNode().getAdapter(),
env.context().getEntityResolver(), null);
context.translate();
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbEntityColumnExtractorTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbEntityColumnExtractorTest.java
index 8d589c69d..b7dda3819 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbEntityColumnExtractorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DbEntityColumnExtractorTest.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.JoinType;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.Test;
import java.sql.Types;
@@ -35,12 +36,12 @@ public class DbEntityColumnExtractorTest extends BaseColumnExtractorTest {
@Test
public void extractNoPrefix() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(createMockDbEntity("mock"))
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DbEntityColumnExtractor extractor = new DbEntityColumnExtractor(context);
extractor.extract(CayennePath.EMPTY_PATH);
@@ -79,12 +80,12 @@ public class DbEntityColumnExtractorTest extends BaseColumnExtractorTest {
dataMap.addDbEntity(mock2DbEntity);
mockDbEntity.setDataMap(dataMap);
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(mockDbEntity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DbRelationship relationship = new DbRelationship();
relationship.setSourceEntity(mockDbEntity);
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorIT.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorIT.java
index 32909592a..f77fb71a4 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorIT.java
@@ -54,8 +54,8 @@ public class DescriptorColumnExtractorIT {
ClassDescriptor classDescriptor = resolver.getClassDescriptor("CompoundPaintingLongNames");
SelectTranslatorContext translatorContext = new SelectTranslatorContext(
- new FluentSelectWrapper(ObjectSelect.query(CompoundPaintingLongNames.class)
- .column(CompoundPaintingLongNames.SELF)),
+ ObjectSelect.query(CompoundPaintingLongNames.class)
+ .column(CompoundPaintingLongNames.SELF),
Mockito.mock(DbAdapter.class),
resolver,
null);
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorTest.java
index b3b1b7ca4..93253d43e 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractorTest.java
@@ -30,6 +30,7 @@ import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.apache.cayenne.reflect.generic.DefaultValueComparisonStrategyFactory;
import org.junit.jupiter.api.Test;
@@ -41,13 +42,13 @@ public class DescriptorColumnExtractorTest extends BaseColumnExtractorTest {
@Test
public void extractNoPrefix() {
DbEntity mockDbEntity = createMockDbEntity("mock");
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(mockDbEntity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DataMap dataMap = new DataMap();
dataMap.addDbEntity(mockDbEntity);
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DistinctStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DistinctStageTest.java
index 985b7e51b..3cb0ff952 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DistinctStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/DistinctStageTest.java
@@ -24,6 +24,7 @@ import java.sql.Types;
import org.apache.cayenne.access.sqlbuilder.sqltree.ColumnNode;
import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -48,8 +49,8 @@ public class DistinctStageTest {
@Test
public void noSuppression() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder().withDistinct(true).build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder().withDistinct(true).build();
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
assertFalse(context.isDistinctSuppression());
@@ -61,13 +62,13 @@ public class DistinctStageTest {
@Test
public void explicitSuppression() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withDistinct(true)
.withMetaData(new MockQueryMetadataBuilder()
.withSuppressDistinct()
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
assertFalse(context.isDistinctSuppression());
@@ -79,11 +80,11 @@ public class DistinctStageTest {
@Test
public void suppressionByType() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withDistinct(true)
.withMetaData(new MockQueryMetadataBuilder().build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DbAttribute attribute = new DbAttribute();
attribute.setType(Types.LONGVARBINARY);
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/GroupByStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/GroupByStageTest.java
index d70822834..bdffc29d8 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/GroupByStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/GroupByStageTest.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.GroupByNode;
import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
import org.apache.cayenne.exp.path.CayennePath;
import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -36,8 +37,8 @@ public class GroupByStageTest {
@BeforeEach
public void prepareContext() {
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder().build();
- context = new MockSelectTranslatorContext(wrapper);
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder().build();
+ context = new MockSelectTranslatorContext(query);
}
// no result columns
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/HavingTranslationStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/HavingTranslationStageTest.java
index f6fde0f94..048a13e11 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/HavingTranslationStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/HavingTranslationStageTest.java
@@ -27,6 +27,7 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.ValueNode;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -44,13 +45,13 @@ public class HavingTranslationStageTest {
dbAttribute.setName("path");
dbEntity.addAttribute(dbAttribute);
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
- .withHavingQualifier(ExpressionFactory.greaterOrEqualDbExp("path", 10))
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
+ .withHaving(ExpressionFactory.greaterOrEqualDbExp("path", 10))
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(dbEntity)
.build())
.build();
- context = new MockSelectTranslatorContext(wrapper);
+ context = new MockSelectTranslatorContext(query);
}
@Test
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/IdColumnExtractorTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/IdColumnExtractorTest.java
index f1a166d25..388037faf 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/IdColumnExtractorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/IdColumnExtractorTest.java
@@ -26,6 +26,7 @@ import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.JoinType;
import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.Test;
import java.sql.Types;
@@ -37,12 +38,12 @@ public class IdColumnExtractorTest extends BaseColumnExtractorTest {
@Test
public void extractNoPrefix() {
DbEntity mockDbEntity = createMockDbEntity("mock");
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(mockDbEntity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
DataMap dataMap = new DataMap();
dataMap.addDbEntity(mockDbEntity);
@@ -73,12 +74,12 @@ public class IdColumnExtractorTest extends BaseColumnExtractorTest {
DbEntity mockDbEntity = createMockDbEntity("mock1");
DbEntity mock2DbEntity = createMockDbEntity("mock2");
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(mockDbEntity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query);
ObjEntity entity = new ObjEntity();
entity.setDbEntity(mockDbEntity);
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/LimitOffsetStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/LimitOffsetStageTest.java
index addb4f7bc..4f0407fb1 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/LimitOffsetStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/LimitOffsetStageTest.java
@@ -22,6 +22,7 @@ package org.apache.cayenne.access.translator.select;
import org.apache.cayenne.access.sqlbuilder.sqltree.LimitOffsetNode;
import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -36,13 +37,13 @@ public class LimitOffsetStageTest {
DbEntity entity = new DbEntity();
entity.setName("mock");
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(entity)
.withLimitOffset(123, 321)
.build())
.build();
- context = new MockSelectTranslatorContext(wrapper);
+ context = new MockSelectTranslatorContext(query);
}
@Test
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockFluentSelectBuilder.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockFluentSelectBuilder.java
new file mode 100644
index 000000000..608cc5363
--- /dev/null
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockFluentSelectBuilder.java
@@ -0,0 +1,101 @@
+/*****************************************************************
+ * 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
+ *
+ * https://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.cayenne.access.translator.select;
+
+import java.util.Collection;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.property.Property;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.FluentSelect;
+import org.apache.cayenne.query.MockQueryMetadata;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.query.Ordering;
+import org.apache.cayenne.query.QueryMetadata;
+
+/**
+ * Builds a {@link FluentSelect} whose metadata is supplied directly, so that translation stages can be unit-tested
+ * without a real {@link EntityResolver} behind the query.
+ */
+class MockFluentSelectBuilder {
+
+ private boolean distinct;
+
+ private QueryMetadata queryMetadata;
+
+ private Expression where;
+
+ private Collection<Ordering> orderings;
+
+ private Collection<Property<?>> queryColumns;
+
+ private Expression having;
+
+ MockFluentSelectBuilder withDistinct(boolean distinct) {
+ this.distinct = distinct;
+ return this;
+ }
+
+ MockFluentSelectBuilder withMetaData(QueryMetadata metaData) {
+ this.queryMetadata = metaData;
+ return this;
+ }
+
+ MockFluentSelectBuilder withWhere(Expression where) {
+ this.where = where;
+ return this;
+ }
+
+ MockFluentSelectBuilder withOrderings(Collection<Ordering> orderings) {
+ this.orderings = orderings;
+ return this;
+ }
+
+ MockFluentSelectBuilder withColumns(Collection<Property<?>> columns) {
+ this.queryColumns = columns;
+ return this;
+ }
+
+ MockFluentSelectBuilder withHaving(Expression having) {
+ this.having = having;
+ return this;
+ }
+
+ FluentSelect<?, ?> build() {
+ return new ObjectSelect<>() {
+ {
+ this.distinct = MockFluentSelectBuilder.this.distinct;
+ this.where = MockFluentSelectBuilder.this.where;
+ this.having = MockFluentSelectBuilder.this.having;
+ this.orderings = MockFluentSelectBuilder.this.orderings;
+ }
+
+ @Override
+ public QueryMetadata getMetaData(EntityResolver resolver) {
+ return queryMetadata != null ? queryMetadata : new MockQueryMetadata();
+ }
+
+ @Override
+ public Collection<Property<?>> getColumns() {
+ return queryColumns;
+ }
+ };
+ }
+}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockQueryWrapperBuilder.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockQueryWrapperBuilder.java
deleted file mode 100644
index d39f42709..000000000
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockQueryWrapperBuilder.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.access.translator.select;
-
-import java.util.Collection;
-
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.property.BaseProperty;
-import org.apache.cayenne.exp.property.Property;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.query.MockQueryMetadata;
-import org.apache.cayenne.query.Ordering;
-import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.Select;
-
-class MockQueryWrapperBuilder {
-
- private boolean distinct;
-
- private QueryMetadata metaData;
-
- private PrefetchTreeNode prefetchTreeNode;
-
- private Expression qualifier;
-
- private Collection<Ordering> orderings;
-
- private Collection<Property<?>> columns;
-
- private Expression havingQualifier;
-
- private Select<?> mockSelect;
- private boolean needsResultSetMapping;
-
- MockQueryWrapperBuilder withDistinct(boolean distinct) {
- this.distinct = distinct;
- return this;
- }
-
- MockQueryWrapperBuilder withMetaData(QueryMetadata metaData) {
- this.metaData = metaData;
- return this;
- }
-
- MockQueryWrapperBuilder withPrefetchTreeNode(PrefetchTreeNode prefetchTreeNode) {
- this.prefetchTreeNode = prefetchTreeNode;
- return this;
- }
-
- MockQueryWrapperBuilder withQualifier(Expression qualifier) {
- this.qualifier = qualifier;
- return this;
- }
-
- MockQueryWrapperBuilder withOrderings(Collection<Ordering> orderings) {
- this.orderings = orderings;
- return this;
- }
-
- MockQueryWrapperBuilder withColumns(Collection<Property<?>> columns) {
- this.columns = columns;
- return this;
- }
-
- MockQueryWrapperBuilder withHavingQualifier(Expression havingQualifier) {
- this.havingQualifier = havingQualifier;
- return this;
- }
-
- MockQueryWrapperBuilder withSelect(Select<?> select) {
- this.mockSelect = select;
- return this;
- }
-
- MockQueryWrapperBuilder withNeedsResultSetMapping(boolean needsResultSetMapping) {
- this.needsResultSetMapping = needsResultSetMapping;
- return this;
- }
-
- TranslatableQueryWrapper build() {
- return new TranslatableQueryWrapper() {
- @Override
- public boolean isDistinct() {
- return distinct;
- }
-
- @Override
- public QueryMetadata getMetaData(EntityResolver resolver) {
- return metaData != null ? metaData : new MockQueryMetadata();
- }
-
- @Override
- public Expression getQualifier() {
- return qualifier;
- }
-
- @Override
- public Collection<Ordering> getOrderings() {
- return orderings;
- }
-
- @Override
- public Collection<Property<?>> getColumns() {
- return columns;
- }
-
- @Override
- public Expression getHavingQualifier() {
- return havingQualifier;
- }
-
- @Override
- public Select<?> unwrap() {
- return mockSelect;
- }
-
- @Override
- public boolean needsResultSetMapping() {
- return needsResultSetMapping;
- }
- };
- }
-}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockSelectTranslatorContext.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockSelectTranslatorContext.java
index e7cb994bf..66793b2a7 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockSelectTranslatorContext.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/MockSelectTranslatorContext.java
@@ -22,16 +22,17 @@ package org.apache.cayenne.access.translator.select;
import org.apache.cayenne.access.types.ExtendedTypeMap;
import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.FluentSelect;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MockSelectTranslatorContext extends SelectTranslatorContext {
- MockSelectTranslatorContext(TranslatableQueryWrapper query) {
+ MockSelectTranslatorContext(FluentSelect<?, ?> query) {
super(query, mockAdapter(), null, null);
}
- MockSelectTranslatorContext(TranslatableQueryWrapper query, EntityResolver resolver) {
+ MockSelectTranslatorContext(FluentSelect<?, ?> query, EntityResolver resolver) {
super(query, mockAdapter(), resolver, null);
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ObjPathProcessorIT.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ObjPathProcessorIT.java
index eaf8ae1fc..f644990a2 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ObjPathProcessorIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/ObjPathProcessorIT.java
@@ -41,7 +41,7 @@ public class ObjPathProcessorIT {
@BeforeEach
public void prepareTranslationContext() {
SelectTranslatorContext translatorContext = new SelectTranslatorContext(
- new FluentSelectWrapper(ObjectSelect.query(Object.class)),
+ ObjectSelect.query(Object.class),
Mockito.mock(DbAdapter.class),
env.context().getEntityResolver(),
null
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/OrderingStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/OrderingStageTest.java
index 17280fbdb..a16516d7f 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/OrderingStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/OrderingStageTest.java
@@ -31,6 +31,7 @@ import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.apache.cayenne.query.Ordering;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -65,7 +66,7 @@ public class OrderingStageTest {
Ordering ordering = new Ordering("path");
ordering.setDescending();
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withOrderings(Collections.singleton(ordering))
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(dbEntity)
@@ -73,7 +74,7 @@ public class OrderingStageTest {
.build())
.withDistinct( true )
.build();
- context = new MockSelectTranslatorContext(wrapper);
+ context = new MockSelectTranslatorContext(query);
}
@Test
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslationStageTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslationStageTest.java
index ccaa3a98c..6201825b4 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslationStageTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslationStageTest.java
@@ -26,6 +26,7 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.ValueNode;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.query.FluentSelect;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -43,13 +44,13 @@ public class QualifierTranslationStageTest {
dbAttribute.setName("path");
dbEntity.addAttribute(dbAttribute);
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
- .withQualifier(ExpressionFactory.greaterOrEqualDbExp("path", 10))
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
+ .withWhere(ExpressionFactory.greaterOrEqualDbExp("path", 10))
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(dbEntity)
.build())
.build();
- context = new MockSelectTranslatorContext(wrapper);
+ context = new MockSelectTranslatorContext(query);
}
@Test
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
index fd9501537..45531b527 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
@@ -47,7 +47,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -66,7 +66,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -87,7 +87,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -105,7 +105,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -126,7 +126,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -147,7 +147,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -170,7 +170,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -192,7 +192,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -214,7 +214,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -237,7 +237,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -264,7 +264,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -297,7 +297,7 @@ public class QualifierTranslatorExistExpressionIT {
ObjectSelect<Artist> query = ObjectSelect.query(Artist.class, exp);
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, env.runtime().getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
index 8c2c51ec1..9191ab9bb 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
@@ -64,7 +64,7 @@ public class QualifierTranslatorIT {
.and(CompoundFkTestEntity.NAME.contains("a"));
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -89,7 +89,7 @@ public class QualifierTranslatorIT {
.or(CompoundFkTestEntity.TO_COMPOUND_PK.eq(testEntity.get(1)));
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
@@ -107,7 +107,7 @@ public class QualifierTranslatorIT {
.where(ExpressionFactory.exp("name = -1"));
SelectTranslatorContext context
- = new SelectTranslatorContext(new FluentSelectWrapper(query), runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
+ = new SelectTranslatorContext(query, runtime.getDataDomain().getDefaultNode().getAdapter(), env.context().getEntityResolver(), null);
QualifierTranslator qualifierTranslator = context.getQualifierTranslator();
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
index f3b74a989..eef9a80bd 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
@@ -29,6 +29,7 @@ import org.apache.cayenne.exp.parser.ASTAsterisk;
import org.apache.cayenne.exp.parser.ASTScalar;
import org.apache.cayenne.exp.property.BaseProperty;
import org.apache.cayenne.map.*;
+import org.apache.cayenne.query.FluentSelect;
import org.apache.cayenne.query.ObjectSelect;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -78,13 +79,13 @@ public class QualifierTranslatorTest {
EntityResolver resolver = new EntityResolver();
resolver.addDataMap(dataMap);
- TranslatableQueryWrapper wrapper = new MockQueryWrapperBuilder()
+ FluentSelect<?, ?> query = new MockFluentSelectBuilder()
.withMetaData(new MockQueryMetadataBuilder()
.withDbEntity(dbEntity)
.withObjEntity(entity)
.build())
.build();
- SelectTranslatorContext context = new MockSelectTranslatorContext(wrapper, resolver);
+ SelectTranslatorContext context = new MockSelectTranslatorContext(query, resolver);
translator = new QualifierTranslator(context);
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/exp/property/SelfPropertyTest.java b/cayenne/src/test/java/org/apache/cayenne/exp/property/SelfPropertyTest.java
index 0cdedb94e..9518b70b6 100644
--- a/cayenne/src/test/java/org/apache/cayenne/exp/property/SelfPropertyTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/exp/property/SelfPropertyTest.java
@@ -99,9 +99,9 @@ public class SelfPropertyTest {
assertTrue(node instanceof ASTSubquery);
ASTSubquery subquery = (ASTSubquery) node;
- assertTrue(subquery.getQuery().unwrap() instanceof ObjectSelect);
+ assertTrue(subquery.getQuery() instanceof ObjectSelect);
- ObjectSelect<?> subSelect = (ObjectSelect<?>) subquery.getQuery().unwrap();
+ ObjectSelect<?> subSelect = (ObjectSelect<?>) subquery.getQuery();
assertEquals(Artist.class, subSelect.getEntityType());
assertEquals(ExpressionFactory.exp("artistName = 'test'"), subSelect.getWhere());
}
@@ -118,9 +118,9 @@ public class SelfPropertyTest {
assertTrue(node instanceof ASTSubquery);
ASTSubquery subquery = (ASTSubquery) node;
- assertTrue(subquery.getQuery().unwrap() instanceof ObjectSelect);
+ assertTrue(subquery.getQuery() instanceof ObjectSelect);
- ObjectSelect<?> subSelect = (ObjectSelect<?>) subquery.getQuery().unwrap();
+ ObjectSelect<?> subSelect = (ObjectSelect<?>) subquery.getQuery();
assertEquals(Artist.class, subSelect.getEntityType());
assertEquals(ExpressionFactory.exp("artistName = 'test'"), subSelect.getWhere());
}
(cayenne) 03/05: Query cleanup... Unwinding CacheableQuery
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 34aaa780edd30f1d30c0c7a5f21f41cb3864f54f
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Aug 30 13:44:28 2026 -0400
Query cleanup... Unwinding CacheableQuery
also some reformatting
---
.../org/apache/cayenne/query/CacheableQuery.java | 5 -
.../org/apache/cayenne/query/FluentSelect.java | 83 +-
.../org/apache/cayenne/query/MappedSelect.java | 16 +-
.../java/org/apache/cayenne/query/SelectById.java | 1473 ++++++++++----------
.../cayenne/access/DataContextQueryCachingIT.java | 6 +-
5 files changed, 821 insertions(+), 762 deletions(-)
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java
index 970f98a8c..b2fd54b1a 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java
@@ -19,9 +19,6 @@
package org.apache.cayenne.query;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* Shared functionality for cacheable queries.
*
@@ -29,8 +26,6 @@ import org.slf4j.LoggerFactory;
*/
public abstract class CacheableQuery implements Query {
- protected static final Logger LOGGER = LoggerFactory.getLogger(CacheableQuery.class);
-
abstract protected BaseQueryMetadata getBaseMetaData();
/**
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
index 73d2517d7..1b1c2ef9d 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -41,7 +41,7 @@ import org.apache.cayenne.map.ObjEntity;
*
* @since 4.0
*/
-public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends CacheableQuery implements Select<T> {
+public abstract class FluentSelect<T, S extends FluentSelect<T, S>> implements Select<T> {
// root
protected Class<?> entityType;
@@ -63,6 +63,8 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach
protected abstract ObjectSelectMetadata createMetadata();
+ protected abstract ObjectSelectMetadata getBaseMetaData();
+
protected Object resolveRoot(EntityResolver resolver) {
Object root;
if (entityType != null) {
@@ -346,8 +348,8 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach
}
public S cacheStrategy(QueryCacheStrategy strategy) {
- setCacheStrategy(strategy);
- setCacheGroup(null);
+ getBaseMetaData().setCacheStrategy(strategy);
+ getBaseMetaData().setCacheGroup(null);
return castSelf();
}
@@ -356,7 +358,7 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach
}
public S cacheGroup(String cacheGroup) {
- setCacheGroup(cacheGroup);
+ getBaseMetaData().setCacheGroup(cacheGroup);
return castSelf();
}
@@ -408,6 +410,79 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach
return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
}
+ /**
+ * @since 3.0
+ */
+ public QueryCacheStrategy getCacheStrategy() {
+ return getBaseMetaData().getCacheStrategy();
+ }
+
+ /**
+ * @since 4.0
+ */
+ public String getCacheGroup() {
+ return getBaseMetaData().getCacheGroup();
+ }
+
+ /**
+ * Note that unlike {@link #cacheStrategy(QueryCacheStrategy)} this method preserves the
+ * existing cache group. To reset it, use {@link #cacheStrategy(QueryCacheStrategy, String)}.
+ *
+ * @since 3.0
+ * @deprecated use {@link #cacheStrategy(QueryCacheStrategy, String)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void setCacheStrategy(QueryCacheStrategy strategy) {
+ getBaseMetaData().setCacheStrategy(strategy);
+ }
+
+ /**
+ * @since 4.0
+ * @deprecated use {@link #cacheGroup(String)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void setCacheGroup(String cacheGroup) {
+ getBaseMetaData().setCacheGroup(cacheGroup);
+ }
+
+ /**
+ * @since 4.0
+ * @deprecated use {@link #localCache()}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void useLocalCache() {
+ getBaseMetaData().setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ }
+
+ /**
+ * @since 4.0
+ * @deprecated use {@link #localCache(String)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void useLocalCache(String cacheGroup) {
+ getBaseMetaData().setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ getBaseMetaData().setCacheGroup(cacheGroup);
+ }
+
+ /**
+ * @since 4.0
+ * @deprecated use {@link #sharedCache()}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void useSharedCache() {
+ getBaseMetaData().setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ }
+
+ /**
+ * @since 4.0
+ * @deprecated use {@link #sharedCache(String)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public void useSharedCache(String cacheGroup) {
+ getBaseMetaData().setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ getBaseMetaData().setCacheGroup(cacheGroup);
+ }
+
public int getStatementFetchSize() {
return getBaseMetaData().getStatementFetchSize();
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
index f87518113..e6062bc25 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
@@ -18,15 +18,14 @@
****************************************************************/
package org.apache.cayenne.query;
-import java.sql.Statement;
-import java.util.List;
-import java.util.Map;
-
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.QueryDescriptor;
+import java.sql.Statement;
+import java.util.Map;
+
/**
* A query that represents a named parameterized selecting query stored in the mapping. The
* actual query is resolved during execution.
@@ -147,17 +146,12 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> {
public MappedSelect<T> param(String name, Object value) {
return (MappedSelect<T>) super.param(name, value);
}
-
-
-
+
@Override
public T selectFirst(ObjectContext context) {
return context.selectFirst(limit(1));
}
-
-
-
@Override
protected Query createReplacementQuery(EntityResolver resolver) {
QueryDescriptor descriptor = resolver.getQueryDescriptor(queryName);
@@ -191,7 +185,7 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> {
selectQuery.pageSize(pageSize);
}
if (cacheStrategyOverride != null) {
- selectQuery.setCacheStrategy(cacheStrategyOverride);
+ selectQuery.cacheStrategy(cacheStrategyOverride, selectQuery.getCacheGroup());
}
}
case QueryDescriptor.SQL_TEMPLATE -> {
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
index d5e11659e..532942134 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
@@ -38,748 +38,743 @@ import static org.apache.cayenne.exp.ExpressionFactory.*;
/**
* A query to select objects by id.
- *
+ *
* @since 4.0
*/
public class SelectById<T> extends IndirectQuery implements Select<T> {
- private static final long serialVersionUID = -6589464349051607583L;
-
- final QueryRoot root;
- final IdSpec idSpec;
- final boolean fetchingDataRows;
-
- QueryCacheStrategy cacheStrategy;
- String cacheGroup;
- PrefetchTreeNode prefetches;
-
- /* Object query factory methods */
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryId(Class<T> entityType, Object id) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new SingleScalarIdSpec(id);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryMap(Class<T> entityType, Map<String, ?> id) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id));
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryObjectId(Class<T> entityType, ObjectId id) {
- checkObjectId(id);
- QueryRoot root = new ByEntityNameResolver(id.getEntityName());
- IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryIds(Class<T> entityType, Object... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryIdsCollection(Class<T> entityType, Collection<Object> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- @SafeVarargs
- public static <T> SelectById<T> queryMaps(Class<T> entityType, Map<String, ?>... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
-
- for(Map<String, ?> id : ids) {
- checkIdMap(id);
- }
-
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryMapsCollection(Class<T> entityType, Collection<Map<String, ?>> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
-
- ids.forEach(SelectById::checkIdMap);
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryObjectIds(Class<T> entityType, ObjectId... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- String entityName = ids[0].getEntityName();
- for(ObjectId id : ids) {
- checkObjectId(id, entityName);
- }
-
- QueryRoot root = new ByEntityNameResolver(entityName);
- IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 5.0
- */
- public static <T> SelectById<T> queryObjectIdsCollection(Class<T> entityType, Collection<ObjectId> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- String entityName = ids.iterator().next().getEntityName();
- for(ObjectId id : ids) {
- checkObjectId(id, entityName);
- }
-
- QueryRoot root = new ByEntityNameResolver(entityName);
- IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /* Deprecated since 5.0 factory methods */
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryId(Class, Object)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, Object id) {
- return queryId(entityType, id);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryMap(Class, Map)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> id) {
- return queryMap(entityType, id);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryObjectId(Class, ObjectId)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, ObjectId id) {
- return queryObjectId(entityType, id);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryIds(Class, Object...)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, Object firstId, Object... otherIds) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryIdsCollection(Class, Collection)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, Collection<Object> ids) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(ids);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryMaps(Class, Map[])}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- @SafeVarargs
- public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
- return new SelectById<>(root, idSpec);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #queryObjectIds(Class, ObjectId...)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static <T> SelectById<T> query(Class<T> entityType, ObjectId firstId, ObjectId... otherIds) {
- checkObjectId(firstId);
- for(ObjectId id : otherIds) {
- checkObjectId(id, firstId.getEntityName());
- }
-
- QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
- IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
- return new SelectById<>(root, idSpec);
- }
-
-
- /* DataRow factory methods */
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryId(Class<?> entityType, Object id) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new SingleScalarIdSpec(id);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryMap(Class<?> entityType, Map<String, ?> id) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id));
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryObjectId(ObjectId id) {
- checkObjectId(id);
- QueryRoot root = new ByEntityNameResolver(id.getEntityName());
- IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryIds(Class<?> entityType, Object... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryIdsCollection(Class<?> entityType, Collection<Object> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(ids);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- @SafeVarargs
- public static SelectById<DataRow> dataRowQueryMaps(Class<?> entityType, Map<String, ?>... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
-
- for(Map<String, ?> id : ids) {
- checkIdMap(id);
- }
-
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryMapsCollection(Class<?> entityType, Collection<Map<String, ?>> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
-
- ids.forEach(SelectById::checkIdMap);
-
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryObjectIds(ObjectId... ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- String entityName = ids[0].getEntityName();
- for(ObjectId id : ids) {
- checkObjectId(id, entityName);
- }
-
- QueryRoot root = new ByEntityNameResolver(entityName);
- IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 5.0
- */
- public static SelectById<DataRow> dataRowQueryObjectIdsCollection(Collection<ObjectId> ids) {
- if(ids == null) {
- throw new CayenneRuntimeException("Null ids");
- }
- String entityName = ids.iterator().next().getEntityName();
- for(ObjectId id : ids) {
- checkObjectId(id, entityName);
- }
-
- QueryRoot root = new ByEntityNameResolver(entityName);
- IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
- return new SelectById<>(root, idSpec, true);
- }
-
- /* Deprecated since 5.0 DataRow factory methods */
-
- /**
- * @deprecated use {@link #dataRowQueryId(Class, Object)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) {
- return dataRowQueryId(entityType, id);
- }
-
- /**
- * @deprecated use {@link #dataRowQueryMap(Class, Map)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> id) {
- return dataRowQueryMap(entityType, id);
- }
-
- /**
- * @deprecated use {@link #dataRowQueryObjectId(ObjectId)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static SelectById<DataRow> dataRowQuery(ObjectId id) {
- return dataRowQueryObjectId(id);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #dataRowQueryIds(Class, Object...)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object firstId, Object... otherIds) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #dataRowQueryMaps(Class, Map[])}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- @SafeVarargs
- public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
- QueryRoot root = new ByEntityTypeResolver(entityType);
- IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
- return new SelectById<>(root, idSpec, true);
- }
-
- /**
- * @since 4.2
- * @deprecated use {@link #dataRowQueryObjectIds(ObjectId...)}
- */
- @Deprecated(since = "5.0", forRemoval = true)
- public static SelectById<DataRow> dataRowQuery(ObjectId firstId, ObjectId... otherIds) {
- checkObjectId(firstId);
- for(ObjectId id : otherIds) {
- checkObjectId(id, firstId.getEntityName());
- }
-
- QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
- IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
- return new SelectById<>(root, idSpec, true);
- }
-
- protected SelectById(QueryRoot root, IdSpec idSpec, boolean fetchingDataRows) {
- this.root = root;
- this.idSpec = idSpec;
- this.fetchingDataRows = fetchingDataRows;
- }
-
- protected SelectById(QueryRoot root, IdSpec idSpec) {
- this(root, idSpec, false);
- }
-
-
-
- @Override
- public T selectFirst(ObjectContext context) {
- return context.selectFirst(this);
- }
-
-
-
-
- /**
- * Instructs Cayenne to look for query results in the "local" cache when
- * running the query. This is a short-hand notation for:
- *
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
- * </pre>
- */
- public SelectById<T> localCache(String cacheGroup) {
- return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
- }
-
- /**
- * Instructs Cayenne to look for query results in the "local" cache when
- * running the query. This is a short-hand notation for:
- *
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
- * </pre>
- */
- public SelectById<T> localCache() {
- return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
- }
-
- /**
- * Instructs Cayenne to look for query results in the "shared" cache when
- * running the query. This is a short-hand notation for:
- *
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
- * </pre>
- */
- public SelectById<T> sharedCache(String cacheGroup) {
- return cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
- }
-
- /**
- * Instructs Cayenne to look for query results in the "shared" cache when
- * running the query. This is a short-hand notation for:
- *
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
- * </pre>
- */
- public SelectById<T> sharedCache() {
- return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
- }
-
- public QueryCacheStrategy getCacheStrategy() {
- return cacheStrategy;
- }
-
- public SelectById<T> cacheStrategy(QueryCacheStrategy strategy) {
- if (this.cacheStrategy != strategy) {
- this.cacheStrategy = strategy;
- this.replacementQuery = null;
- }
-
- return this;
- }
-
- public SelectById<T> cacheStrategy(QueryCacheStrategy strategy, String cacheGroup) {
- return cacheStrategy(strategy).cacheGroup(cacheGroup);
- }
-
- public String getCacheGroup() {
- return cacheGroup;
- }
-
- public SelectById<T> cacheGroup(String cacheGroup) {
- this.cacheGroup = cacheGroup;
- this.replacementQuery = null;
- return this;
- }
-
- public boolean isFetchingDataRows() {
- return fetchingDataRows;
- }
-
- /**
- * Merges prefetch into the query prefetch tree.
- *
- * @return this object
- */
- public SelectById<T> prefetch(PrefetchTreeNode prefetch) {
-
- if (prefetch == null) {
- return this;
- }
-
- if (prefetches == null) {
- prefetches = new PrefetchTreeNode();
- }
-
- prefetches.merge(prefetch);
- return this;
- }
-
- /**
- * Merges a prefetch path with specified semantics into the query prefetch
- * tree.
- *
- * @return this object
- */
- public SelectById<T> prefetch(String path, int semantics) {
-
- if (path == null) {
- return this;
- }
-
- if (prefetches == null) {
- prefetches = new PrefetchTreeNode();
- }
-
- prefetches.addPath(path).setSemantics(semantics);
- return this;
- }
-
- public PrefetchTreeNode getPrefetches() {
- return prefetches;
- }
-
- @Override
- protected Query createReplacementQuery(EntityResolver resolver) {
- ObjEntity entity = root.resolve(resolver);
-
- ObjectSelect<?> query = new ObjectSelect<>()
- .entityName(entity.getName())
- .where(idSpec.getQualifier(entity))
- .cacheStrategy(cacheStrategy, cacheGroup);
- if(prefetches != null) {
- query.prefetch(prefetches);
- }
- if(fetchingDataRows) {
- query.fetchDataRows();
- }
- return query;
- }
-
- private static String resolveSinglePkName(ObjEntity entity) {
- Collection<String> pkAttributes = entity.getPrimaryKeyNames();
- if(pkAttributes.size() == 1) {
- return pkAttributes.iterator().next();
- }
- throw new CayenneRuntimeException("PK contains %d columns, expected 1.", pkAttributes.size());
- }
-
- private static void checkObjectId(ObjectId id) {
- if (id.isTemporary() && !id.isReplacementIdAttached()) {
- throw new CayenneRuntimeException("Can't build a query for a temporary id: %s", id);
- }
- }
-
- private static void checkObjectId(ObjectId id, String entityName) {
- checkObjectId(id);
- if(!entityName.equals(id.getEntityName())) {
- throw new CayenneRuntimeException("Can't build a query with mixed object types for given ObjectIds");
- }
- }
-
- private static Map<String, ?> checkIdMap(Map<String, ?> id) {
- if(id == null || id.isEmpty()) {
- throw new CayenneRuntimeException("Null or empty id map");
- }
-
- return id;
- }
-
- @SafeVarargs
- private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E first, E... other) {
- List<R> result = new ArrayList<>(1 + other.length);
- result.add(mapper.apply(first));
- for(E next : other) {
- result.add(mapper.apply(next));
- }
- return result;
- }
-
- @SafeVarargs
- private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E... other) {
- List<R> result = new ArrayList<>(other.length);
- for(E next : other) {
- result.add(mapper.apply(next));
- }
- return result;
- }
-
- private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, Collection<E> other) {
- List<R> result = new ArrayList<>(other.size());
- for(E next : other) {
- result.add(mapper.apply(next));
- }
- return result;
- }
-
- protected interface QueryRoot extends Serializable {
- ObjEntity resolve(EntityResolver resolver);
- }
-
- protected interface IdSpec extends Serializable{
- Expression getQualifier(ObjEntity entity);
- }
-
- protected static class SingleScalarIdSpec implements IdSpec {
-
- private final Object id;
-
- protected SingleScalarIdSpec(Object id) {
- this.id = id;
- }
-
- @Override
- public Expression getQualifier(ObjEntity entity) {
- return matchDbExp(resolveSinglePkName(entity), id);
- }
- }
-
- protected static class MultiScalarIdSpec implements IdSpec {
-
- private final Collection<Object> ids;
-
- protected MultiScalarIdSpec(Object firstId, Object... otherIds) {
- this.ids = foldArguments(Function.identity(), firstId, otherIds);
- }
-
- protected MultiScalarIdSpec(Collection<Object> ids) {
- this.ids = ids;
- }
-
- @Override
- public Expression getQualifier(ObjEntity entity) {
- return inDbExp(resolveSinglePkName(entity), ids);
- }
- }
-
- protected static class SingleMapIdSpec implements IdSpec {
-
- private final Map<String, ?> id;
-
- protected SingleMapIdSpec(Map<String, ?> id) {
- this.id = id;
- }
-
- @Override
- public Expression getQualifier(ObjEntity entity) {
- Expression expression = matchAllDbExp(id, Expression.EQUAL_TO);
- return expression == null ? expFalse() : expression;
- }
- }
-
- protected static class MultiMapIdSpec implements IdSpec {
-
- private final Collection<Map<String, ?>> ids;
-
- @SafeVarargs
+ private static final long serialVersionUID = -6589464349051607583L;
+
+ final QueryRoot root;
+ final IdSpec idSpec;
+ final boolean fetchingDataRows;
+
+ QueryCacheStrategy cacheStrategy;
+ String cacheGroup;
+ PrefetchTreeNode prefetches;
+
+ /* Object query factory methods */
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryId(Class<T> entityType, Object id) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new SingleScalarIdSpec(id);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryMap(Class<T> entityType, Map<String, ?> id) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id));
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryObjectId(Class<T> entityType, ObjectId id) {
+ checkObjectId(id);
+ QueryRoot root = new ByEntityNameResolver(id.getEntityName());
+ IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryIds(Class<T> entityType, Object... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryIdsCollection(Class<T> entityType, Collection<Object> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ @SafeVarargs
+ public static <T> SelectById<T> queryMaps(Class<T> entityType, Map<String, ?>... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+
+ for (Map<String, ?> id : ids) {
+ checkIdMap(id);
+ }
+
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryMapsCollection(Class<T> entityType, Collection<Map<String, ?>> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+
+ ids.forEach(SelectById::checkIdMap);
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryObjectIds(Class<T> entityType, ObjectId... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ String entityName = ids[0].getEntityName();
+ for (ObjectId id : ids) {
+ checkObjectId(id, entityName);
+ }
+
+ QueryRoot root = new ByEntityNameResolver(entityName);
+ IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static <T> SelectById<T> queryObjectIdsCollection(Class<T> entityType, Collection<ObjectId> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ String entityName = ids.iterator().next().getEntityName();
+ for (ObjectId id : ids) {
+ checkObjectId(id, entityName);
+ }
+
+ QueryRoot root = new ByEntityNameResolver(entityName);
+ IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /* Deprecated since 5.0 factory methods */
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryId(Class, Object)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, Object id) {
+ return queryId(entityType, id);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryMap(Class, Map)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> id) {
+ return queryMap(entityType, id);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryObjectId(Class, ObjectId)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, ObjectId id) {
+ return queryObjectId(entityType, id);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryIds(Class, Object...)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, Object firstId, Object... otherIds) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryIdsCollection(Class, Collection)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, Collection<Object> ids) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(ids);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryMaps(Class, Map[])}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ @SafeVarargs
+ public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
+ return new SelectById<>(root, idSpec);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #queryObjectIds(Class, ObjectId...)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static <T> SelectById<T> query(Class<T> entityType, ObjectId firstId, ObjectId... otherIds) {
+ checkObjectId(firstId);
+ for (ObjectId id : otherIds) {
+ checkObjectId(id, firstId.getEntityName());
+ }
+
+ QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
+ IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
+ return new SelectById<>(root, idSpec);
+ }
+
+
+ /* DataRow factory methods */
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryId(Class<?> entityType, Object id) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new SingleScalarIdSpec(id);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryMap(Class<?> entityType, Map<String, ?> id) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id));
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryObjectId(ObjectId id) {
+ checkObjectId(id);
+ QueryRoot root = new ByEntityNameResolver(id.getEntityName());
+ IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryIds(Class<?> entityType, Object... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryIdsCollection(Class<?> entityType, Collection<Object> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(ids);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ @SafeVarargs
+ public static SelectById<DataRow> dataRowQueryMaps(Class<?> entityType, Map<String, ?>... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+
+ for (Map<String, ?> id : ids) {
+ checkIdMap(id);
+ }
+
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryMapsCollection(Class<?> entityType, Collection<Map<String, ?>> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+
+ ids.forEach(SelectById::checkIdMap);
+
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryObjectIds(ObjectId... ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ String entityName = ids[0].getEntityName();
+ for (ObjectId id : ids) {
+ checkObjectId(id, entityName);
+ }
+
+ QueryRoot root = new ByEntityNameResolver(entityName);
+ IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public static SelectById<DataRow> dataRowQueryObjectIdsCollection(Collection<ObjectId> ids) {
+ if (ids == null) {
+ throw new CayenneRuntimeException("Null ids");
+ }
+ String entityName = ids.iterator().next().getEntityName();
+ for (ObjectId id : ids) {
+ checkObjectId(id, entityName);
+ }
+
+ QueryRoot root = new ByEntityNameResolver(entityName);
+ IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /* Deprecated since 5.0 DataRow factory methods */
+
+ /**
+ * @deprecated use {@link #dataRowQueryId(Class, Object)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) {
+ return dataRowQueryId(entityType, id);
+ }
+
+ /**
+ * @deprecated use {@link #dataRowQueryMap(Class, Map)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> id) {
+ return dataRowQueryMap(entityType, id);
+ }
+
+ /**
+ * @deprecated use {@link #dataRowQueryObjectId(ObjectId)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static SelectById<DataRow> dataRowQuery(ObjectId id) {
+ return dataRowQueryObjectId(id);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #dataRowQueryIds(Class, Object...)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object firstId, Object... otherIds) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #dataRowQueryMaps(Class, Map[])}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ @SafeVarargs
+ public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
+ QueryRoot root = new ByEntityTypeResolver(entityType);
+ IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ /**
+ * @since 4.2
+ * @deprecated use {@link #dataRowQueryObjectIds(ObjectId...)}
+ */
+ @Deprecated(since = "5.0", forRemoval = true)
+ public static SelectById<DataRow> dataRowQuery(ObjectId firstId, ObjectId... otherIds) {
+ checkObjectId(firstId);
+ for (ObjectId id : otherIds) {
+ checkObjectId(id, firstId.getEntityName());
+ }
+
+ QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
+ IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
+ return new SelectById<>(root, idSpec, true);
+ }
+
+ protected SelectById(QueryRoot root, IdSpec idSpec, boolean fetchingDataRows) {
+ this.root = root;
+ this.idSpec = idSpec;
+ this.fetchingDataRows = fetchingDataRows;
+ }
+
+ protected SelectById(QueryRoot root, IdSpec idSpec) {
+ this(root, idSpec, false);
+ }
+
+ @Override
+ public T selectFirst(ObjectContext context) {
+ return context.selectFirst(this);
+ }
+
+ /**
+ * Instructs Cayenne to look for query results in the "local" cache when
+ * running the query. This is a short-hand notation for:
+ *
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
+ * </pre>
+ */
+ public SelectById<T> localCache(String cacheGroup) {
+ return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
+ }
+
+ /**
+ * Instructs Cayenne to look for query results in the "local" cache when
+ * running the query. This is a short-hand notation for:
+ *
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ * </pre>
+ */
+ public SelectById<T> localCache() {
+ return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ }
+
+ /**
+ * Instructs Cayenne to look for query results in the "shared" cache when
+ * running the query. This is a short-hand notation for:
+ *
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
+ * </pre>
+ */
+ public SelectById<T> sharedCache(String cacheGroup) {
+ return cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
+ }
+
+ /**
+ * Instructs Cayenne to look for query results in the "shared" cache when
+ * running the query. This is a short-hand notation for:
+ *
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ * </pre>
+ */
+ public SelectById<T> sharedCache() {
+ return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ }
+
+ public QueryCacheStrategy getCacheStrategy() {
+ return cacheStrategy;
+ }
+
+ public SelectById<T> cacheStrategy(QueryCacheStrategy strategy) {
+ if (this.cacheStrategy != strategy) {
+ this.cacheStrategy = strategy;
+ this.replacementQuery = null;
+ }
+
+ return this;
+ }
+
+ public SelectById<T> cacheStrategy(QueryCacheStrategy strategy, String cacheGroup) {
+ return cacheStrategy(strategy).cacheGroup(cacheGroup);
+ }
+
+ public String getCacheGroup() {
+ return cacheGroup;
+ }
+
+ public SelectById<T> cacheGroup(String cacheGroup) {
+ this.cacheGroup = cacheGroup;
+ this.replacementQuery = null;
+ return this;
+ }
+
+ public boolean isFetchingDataRows() {
+ return fetchingDataRows;
+ }
+
+ /**
+ * Merges prefetch into the query prefetch tree.
+ *
+ * @return this object
+ */
+ public SelectById<T> prefetch(PrefetchTreeNode prefetch) {
+
+ if (prefetch == null) {
+ return this;
+ }
+
+ if (prefetches == null) {
+ prefetches = new PrefetchTreeNode();
+ }
+
+ prefetches.merge(prefetch);
+ return this;
+ }
+
+ /**
+ * Merges a prefetch path with specified semantics into the query prefetch
+ * tree.
+ *
+ * @return this object
+ */
+ public SelectById<T> prefetch(String path, int semantics) {
+
+ if (path == null) {
+ return this;
+ }
+
+ if (prefetches == null) {
+ prefetches = new PrefetchTreeNode();
+ }
+
+ prefetches.addPath(path).setSemantics(semantics);
+ return this;
+ }
+
+ public PrefetchTreeNode getPrefetches() {
+ return prefetches;
+ }
+
+ @Override
+ protected Query createReplacementQuery(EntityResolver resolver) {
+ ObjEntity entity = root.resolve(resolver);
+
+ ObjectSelect<?> query = new ObjectSelect<>()
+ .entityName(entity.getName())
+ .where(idSpec.getQualifier(entity))
+ .cacheStrategy(cacheStrategy, cacheGroup);
+ if (prefetches != null) {
+ query.prefetch(prefetches);
+ }
+ if (fetchingDataRows) {
+ query.fetchDataRows();
+ }
+ return query;
+ }
+
+ private static String resolveSinglePkName(ObjEntity entity) {
+ Collection<String> pkAttributes = entity.getPrimaryKeyNames();
+ if (pkAttributes.size() == 1) {
+ return pkAttributes.iterator().next();
+ }
+ throw new CayenneRuntimeException("PK contains %d columns, expected 1.", pkAttributes.size());
+ }
+
+ private static void checkObjectId(ObjectId id) {
+ if (id.isTemporary() && !id.isReplacementIdAttached()) {
+ throw new CayenneRuntimeException("Can't build a query for a temporary id: %s", id);
+ }
+ }
+
+ private static void checkObjectId(ObjectId id, String entityName) {
+ checkObjectId(id);
+ if (!entityName.equals(id.getEntityName())) {
+ throw new CayenneRuntimeException("Can't build a query with mixed object types for given ObjectIds");
+ }
+ }
+
+ private static Map<String, ?> checkIdMap(Map<String, ?> id) {
+ if (id == null || id.isEmpty()) {
+ throw new CayenneRuntimeException("Null or empty id map");
+ }
+
+ return id;
+ }
+
+ @SafeVarargs
+ private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E first, E... other) {
+ List<R> result = new ArrayList<>(1 + other.length);
+ result.add(mapper.apply(first));
+ for (E next : other) {
+ result.add(mapper.apply(next));
+ }
+ return result;
+ }
+
+ @SafeVarargs
+ private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E... other) {
+ List<R> result = new ArrayList<>(other.length);
+ for (E next : other) {
+ result.add(mapper.apply(next));
+ }
+ return result;
+ }
+
+ private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, Collection<E> other) {
+ List<R> result = new ArrayList<>(other.size());
+ for (E next : other) {
+ result.add(mapper.apply(next));
+ }
+ return result;
+ }
+
+ protected interface QueryRoot extends Serializable {
+ ObjEntity resolve(EntityResolver resolver);
+ }
+
+ protected interface IdSpec extends Serializable {
+ Expression getQualifier(ObjEntity entity);
+ }
+
+ protected static class SingleScalarIdSpec implements IdSpec {
+
+ private final Object id;
+
+ protected SingleScalarIdSpec(Object id) {
+ this.id = id;
+ }
+
+ @Override
+ public Expression getQualifier(ObjEntity entity) {
+ return matchDbExp(resolveSinglePkName(entity), id);
+ }
+ }
+
+ protected static class MultiScalarIdSpec implements IdSpec {
+
+ private final Collection<Object> ids;
+
+ protected MultiScalarIdSpec(Object firstId, Object... otherIds) {
+ this.ids = foldArguments(Function.identity(), firstId, otherIds);
+ }
+
+ protected MultiScalarIdSpec(Collection<Object> ids) {
+ this.ids = ids;
+ }
+
+ @Override
+ public Expression getQualifier(ObjEntity entity) {
+ return inDbExp(resolveSinglePkName(entity), ids);
+ }
+ }
+
+ protected static class SingleMapIdSpec implements IdSpec {
+
+ private final Map<String, ?> id;
+
+ protected SingleMapIdSpec(Map<String, ?> id) {
+ this.id = id;
+ }
+
+ @Override
+ public Expression getQualifier(ObjEntity entity) {
+ Expression expression = matchAllDbExp(id, Expression.EQUAL_TO);
+ return expression == null ? expFalse() : expression;
+ }
+ }
+
+ protected static class MultiMapIdSpec implements IdSpec {
+
+ private final Collection<Map<String, ?>> ids;
+
+ @SafeVarargs
static MultiMapIdSpec ofMap(Map<String, ?> firstId, Map<String, ?>... otherIds) {
- return new MultiMapIdSpec(foldArguments(Function.identity(), firstId, otherIds));
- }
-
- @SafeVarargs
- static MultiMapIdSpec ofMap(Map<String, ?>... ids) {
- return new MultiMapIdSpec(foldArguments(Function.identity(), ids));
- }
-
- static MultiMapIdSpec ofObjectId(ObjectId firstId, ObjectId... otherIds) {
- return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, firstId, otherIds));
- }
-
- static MultiMapIdSpec ofObjectId(ObjectId... ids) {
- return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
- }
-
- static MultiMapIdSpec ofObjectIdCollection(Collection<ObjectId> ids) {
- return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
- }
-
- static MultiMapIdSpec ofMapCollection(Collection<Map<String, ?>> ids) {
- return new MultiMapIdSpec(ids);
- }
-
- protected MultiMapIdSpec(Collection<Map<String, ?>> ids) {
- this.ids = ids;
- }
-
- @Override
- public Expression getQualifier(ObjEntity entity) {
- List<Expression> expressions = new ArrayList<>();
- for(Map<String, ?> id : ids) {
- Expression expression = matchAllDbExp(id, Expression.EQUAL_TO);
- if(expression != null) {
- expressions.add(expression);
- }
- }
-
- return expressions.isEmpty() ? expFalse() : or(expressions);
- }
- }
-
- private static class ByEntityTypeResolver implements QueryRoot {
- private final Class<?> entityType;
-
- public ByEntityTypeResolver(Class<?> entityType) {
- this.entityType = entityType;
- }
-
- @Override
- public ObjEntity resolve(EntityResolver resolver) {
- return resolver.getObjEntity(entityType);
- }
- }
-
- private static class ByEntityNameResolver implements QueryRoot {
- private final String entityName;
-
- public ByEntityNameResolver(String entityName) {
- this.entityName = entityName;
- }
-
- @Override
- public ObjEntity resolve(EntityResolver resolver) {
- return resolver.getObjEntity(entityName);
- }
- }
+ return new MultiMapIdSpec(foldArguments(Function.identity(), firstId, otherIds));
+ }
+
+ @SafeVarargs
+ static MultiMapIdSpec ofMap(Map<String, ?>... ids) {
+ return new MultiMapIdSpec(foldArguments(Function.identity(), ids));
+ }
+
+ static MultiMapIdSpec ofObjectId(ObjectId firstId, ObjectId... otherIds) {
+ return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, firstId, otherIds));
+ }
+
+ static MultiMapIdSpec ofObjectId(ObjectId... ids) {
+ return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
+ }
+
+ static MultiMapIdSpec ofObjectIdCollection(Collection<ObjectId> ids) {
+ return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
+ }
+
+ static MultiMapIdSpec ofMapCollection(Collection<Map<String, ?>> ids) {
+ return new MultiMapIdSpec(ids);
+ }
+
+ protected MultiMapIdSpec(Collection<Map<String, ?>> ids) {
+ this.ids = ids;
+ }
+
+ @Override
+ public Expression getQualifier(ObjEntity entity) {
+ List<Expression> expressions = new ArrayList<>();
+ for (Map<String, ?> id : ids) {
+ Expression expression = matchAllDbExp(id, Expression.EQUAL_TO);
+ if (expression != null) {
+ expressions.add(expression);
+ }
+ }
+
+ return expressions.isEmpty() ? expFalse() : or(expressions);
+ }
+ }
+
+ private static class ByEntityTypeResolver implements QueryRoot {
+ private final Class<?> entityType;
+
+ public ByEntityTypeResolver(Class<?> entityType) {
+ this.entityType = entityType;
+ }
+
+ @Override
+ public ObjEntity resolve(EntityResolver resolver) {
+ return resolver.getObjEntity(entityType);
+ }
+ }
+
+ private static class ByEntityNameResolver implements QueryRoot {
+ private final String entityName;
+
+ public ByEntityNameResolver(String entityName) {
+ this.entityName = entityName;
+ }
+
+ @Override
+ public ObjEntity resolve(EntityResolver resolver) {
+ return resolver.getObjEntity(entityName);
+ }
+ }
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java
index 608f06efc..57514bf0a 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java
@@ -103,7 +103,7 @@ public class DataContextQueryCachingIT {
List<?> rows2 = mockupDataRows(4);
engine.reset();
engine.addExpectedResult(select, rows2);
- select.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH);
+ select.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH);
List<?> freshResultRows = context.performQuery(select);
assertEquals(1, engine.getRunCount());
assertEquals(rows2, freshResultRows);
@@ -141,7 +141,7 @@ public class DataContextQueryCachingIT {
List<?> rows2 = mockupDataRows(5);
engine.reset();
engine.addExpectedResult(select, rows2);
- select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE_REFRESH);
+ select.cacheStrategy(QueryCacheStrategy.SHARED_CACHE_REFRESH);
List<?> freshResultRows = context.performQuery(select);
assertEquals(1, engine.getRunCount());
assertEquals(rows2, freshResultRows);
@@ -178,7 +178,7 @@ public class DataContextQueryCachingIT {
List<?> rows2 = mockupDataRows(4);
engine.reset();
engine.addExpectedResult(select, rows2);
- select.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH);
+ select.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH);
List<?> freshResultRows = context.performQuery(select);
assertEquals(1, engine.getRunCount());
(cayenne) 04/05: Query cleanup: QueryChain is deprecated
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit f357868ddf1d7c884491bd6671e287dec5b8ae2c
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Aug 30 14:17:47 2026 -0400
Query cleanup: QueryChain is deprecated
---
.../apache/cayenne/lifecycle/id/StringIdQuery.java | 19 +++++++++----------
.../java/org/apache/cayenne/query/MappedSelect.java | 2 +-
.../java/org/apache/cayenne/query/QueryChain.java | 4 ++++
.../main/java/org/apache/cayenne/query/package.html | 1 -
.../DataContextEJBQLFunctionalExpressionsIT.java | 21 ++++++++-------------
.../_cayenne-guide/part2/objectContext.adoc | 13 +++++++++++--
6 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/id/StringIdQuery.java b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/id/StringIdQuery.java
index 946874628..7fce7f88e 100644
--- a/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/id/StringIdQuery.java
+++ b/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/id/StringIdQuery.java
@@ -18,14 +18,6 @@
****************************************************************/
package org.apache.cayenne.lifecycle.id;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
@@ -38,13 +30,20 @@ import org.apache.cayenne.query.ObjectSelect;
import org.apache.cayenne.query.PrefetchTreeNode;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.QueryCacheStrategy;
-import org.apache.cayenne.query.QueryChain;
import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.query.QueryRouter;
import org.apache.cayenne.query.SQLAction;
import org.apache.cayenne.query.SQLActionVisitor;
import org.apache.cayenne.reflect.ClassDescriptor;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
/**
* A query that allows to fetch objects based on one or more String IDs. The returned
* objects do not have to be of the same type, be related via inheritance, or come from
@@ -53,7 +52,7 @@ import org.apache.cayenne.reflect.ClassDescriptor;
* contain separate lists of DataRows for each type in no particular order.
* <p>
* As of this writing, a limitation of this query is that it returns DataRows that need to
- * be manually converted to objects if needed. In that it is similar to {@link QueryChain}.
+ * be manually converted to objects if needed.
*
* @since 3.1
*/
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
index e6062bc25..a9deacadd 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java
@@ -146,7 +146,7 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> {
public MappedSelect<T> param(String name, Object value) {
return (MappedSelect<T>) super.param(name, value);
}
-
+
@Override
public T selectFirst(ObjectContext context) {
return context.selectFirst(limit(1));
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java b/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
index 3f701abf5..df5dd9449 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
@@ -32,7 +32,11 @@ import java.util.List;
* convert the results to objects.
*
* @since 1.2
+ * @deprecated to run multiple queries together, execute them inside an explicit
+ * transaction, e.g. via
+ * {@link org.apache.cayenne.runtime.CayenneRuntime#performInTransaction(org.apache.cayenne.tx.TransactionalOperation)}
*/
+@Deprecated(since = "5.0", forRemoval = true)
public class QueryChain implements Query {
protected Collection<Query> chain;
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/package.html b/cayenne/src/main/java/org/apache/cayenne/query/package.html
index 2d1e5503c..e39f417f3 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/package.html
+++ b/cayenne/src/main/java/org/apache/cayenne/query/package.html
@@ -30,7 +30,6 @@ Normally users would only care about these general query classes:
and sometimes - these specialized queries:
<ul>
- <li>QueryChain</li>
<li>RelationshipQuery</li>
<li>SingleObjectQuery</li>
</ul>
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressionsIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressionsIT.java
index 6a90f6414..3e8964bef 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressionsIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressionsIT.java
@@ -20,8 +20,7 @@ package org.apache.cayenne.access;
import org.apache.cayenne.Cayenne;
import org.apache.cayenne.query.EJBQLQuery;
-import org.apache.cayenne.query.QueryChain;
-import org.apache.cayenne.query.SQLTemplate;
+import org.apache.cayenne.test.jdbc.TableHelper;
import org.apache.cayenne.testdo.testmap.Artist;
import org.apache.cayenne.testdo.testmap.Painting;
import org.apache.cayenne.unit.CayenneProjects;
@@ -29,6 +28,7 @@ import org.apache.cayenne.unit.CayenneTestsEnv;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
+import java.sql.SQLException;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -189,17 +189,12 @@ public class DataContextEJBQLFunctionalExpressionsIT {
}
@Test
- public void tRIM() {
-
- // insert via a SQL template to prevent adapter trimming and such...
- QueryChain inserts = new QueryChain();
- inserts.addQuery(new SQLTemplate(
- Artist.class,
- "INSERT INTO ARTIST (ARTIST_ID,ARTIST_NAME) VALUES(1, ' A')"));
- inserts.addQuery(new SQLTemplate(
- Artist.class,
- "INSERT INTO ARTIST (ARTIST_ID,ARTIST_NAME) VALUES(2, 'A ')"));
- env.context().performGenericQuery(inserts);
+ public void tRIM() throws SQLException {
+
+ // insert via raw JDBC to prevent adapter trimming and such...
+ TableHelper tArtist = env.table("ARTIST", "ARTIST_ID", "ARTIST_NAME");
+ tArtist.insert(1, " A");
+ tArtist.insert(2, "A ");
Artist a1 = Cayenne.objectForPK(env.context(), Artist.class, 1);
Artist a2 = Cayenne.objectForPK(env.context(), Artist.class, 2);
diff --git a/docs/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc b/docs/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
index 8e85c47e0..4fec460a0 100644
--- a/docs/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
+++ b/docs/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
@@ -82,12 +82,21 @@ Some queries can be quite complex, returning multiple result sets or even updati
For such queries, ObjectContext provides the `performGenericQuery()` method.
While not commonly used, it is nevertheless important in some situations. E.g.:
+[source, java]
+----
+QueryResponse response = context.performGenericQuery(query);
+----
+
+When multiple such queries need to run together, execute them inside an explicit transaction:
+
[source, java]
----
Collection<Query> queries = ... // multiple queries that need to be run together
-QueryChain query = new QueryChain(queries);
-QueryResponse response = context.performGenericQuery(query);
+runtime.performInTransaction(() -> {
+ queries.forEach(context::performGenericQuery);
+ return null;
+});
----
(cayenne) 02/05: Query cleanup... AbstractQuery is uneeded
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit d86f8be720b2eefc018ea256204c2c90358e96a9
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Aug 30 13:44:28 2026 -0400
Query cleanup... AbstractQuery is uneeded
---
.../apache/cayenne/map/SelectQueryDescriptor.java | 1 -
.../org/apache/cayenne/query/AbstractQuery.java | 100 ---------------------
.../org/apache/cayenne/query/FluentSelect.java | 2 +-
.../org/apache/cayenne/query/ProcedureQuery.java | 49 +++++++++-
.../java/org/apache/cayenne/query/SQLTemplate.java | 49 ++++++++--
.../cayenne/map/SelectQueryDescriptorTest.java | 2 +-
.../apache/cayenne/query/AbstractQueryTest.java | 65 --------------
.../apache/cayenne/query/MockAbstractQuery.java | 38 --------
.../apache/cayenne/query/ProcedureQueryTest.java | 22 +++++
.../org/apache/cayenne/query/SQLTemplateTest.java | 46 ++++++++++
10 files changed, 160 insertions(+), 214 deletions(-)
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java b/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
index 0c0ba5684..1422c418e 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
@@ -163,7 +163,6 @@ public class SelectQueryDescriptor extends QueryDescriptor {
ObjectSelect<?> query = ObjectSelect.query(Object.class, qualifier);
query.entityName(rootEntityName);
- query.setRoot(root);
List<Ordering> orderings = this.getOrderings();
if (orderings != null && !orderings.isEmpty()) {
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
deleted file mode 100644
index f3dfa8fa5..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.query;
-
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.Procedure;
-import org.apache.cayenne.util.ToStringBuilder;
-
-/**
- * A common superclass of Cayenne queries.
- */
-public abstract class AbstractQuery extends CacheableQuery {
-
- /**
- * The root object this query. May be an entity name, Java class, ObjEntity or
- * DbEntity, depending on the specific query and how it was constructed.
- */
- protected Object root;
-
- /**
- * Returns default select parameters.
- *
- * @since 1.2
- */
- public QueryMetadata getMetaData(EntityResolver resolver) {
- BaseQueryMetadata md = new BaseQueryMetadata();
- md.resolve(getRoot(), resolver);
- return md;
- }
-
- /**
- * Returns the root of this query.
- */
- public Object getRoot() {
- return root;
- }
-
- /**
- * Sets the root of the query
- *
- * @param value The new root
- * @throws IllegalArgumentException if value is not a String, ObjEntity, DbEntity,
- * Procedure, DataMap, Class or null.
- */
- public void setRoot(Object value) {
- if (value == null) {
- this.root = null;
- }
-
- // sanity check
- if (!((value instanceof String)
- || (value instanceof ObjEntity)
- || (value instanceof DbEntity)
- || (value instanceof Class)
- || (value instanceof Procedure) || (value instanceof DataMap))) {
-
- String rootClass = (value != null) ? value.getClass().getName() : "null";
-
- throw new IllegalArgumentException(
- getClass().getName()
- + ": \"setRoot(..)\" takes a DataMap, String, ObjEntity, DbEntity, Procedure, "
- + "or Class. It was passed a "
- + rootClass);
- }
-
- this.root = value;
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .append("root", root)
- .toString();
- }
-
- /**
- * @since 1.2
- */
- public abstract SQLAction createSQLAction(SQLActionVisitor visitor);
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
index e7cfb1512..73d2517d7 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -41,7 +41,7 @@ import org.apache.cayenne.map.ObjEntity;
*
* @since 4.0
*/
-public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends AbstractQuery implements Select<T> {
+public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends CacheableQuery implements Select<T> {
// root
protected Class<?> entityType;
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java
index 5e07d4bee..3d30c1358 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java
@@ -19,8 +19,12 @@
package org.apache.cayenne.query;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.util.ToStringBuilder;
import java.util.ArrayList;
import java.util.Collection;
@@ -50,7 +54,7 @@ import java.util.Map;
* {@link org.apache.cayenne.access.DataContext#performGenericQuery(Query)}.
* </p>
*/
-public class ProcedureQuery extends AbstractQuery {
+public class ProcedureQuery extends CacheableQuery {
public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.ProcedureQuery.columnNameCapitalization";
@@ -61,6 +65,49 @@ public class ProcedureQuery extends AbstractQuery {
ProcedureQueryMetadata metaData = new ProcedureQueryMetadata();
protected List<ProcedureColumn[]> resultDescriptors;
+ /**
+ * The root object of this query. May be an entity name, Java class, ObjEntity or
+ * DbEntity, depending on the specific query and how it was constructed.
+ */
+ protected Object root;
+
+ /**
+ * Returns the root of this query.
+ */
+ public Object getRoot() {
+ return root;
+ }
+
+ /**
+ * Sets the root of the query.
+ *
+ * @param value The new root
+ * @throws IllegalArgumentException if value is not a String, ObjEntity, DbEntity,
+ * Procedure, DataMap, Class or null.
+ */
+ public void setRoot(Object value) {
+ if (value != null && !(value instanceof String
+ || value instanceof ObjEntity
+ || value instanceof DbEntity
+ || value instanceof Class
+ || value instanceof Procedure
+ || value instanceof DataMap)) {
+
+ throw new IllegalArgumentException(("%s: \"setRoot(..)\" takes a DataMap, String, ObjEntity, DbEntity, "
+ + "Procedure, or Class. It was passed a %s")
+ .formatted(getClass().getName(), value.getClass().getName()));
+ }
+
+ this.root = value;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .append("root", root)
+ .toString();
+ }
+
/**
* Creates an empty procedure query. The query would fetch DataRows. Fetching
* Persistent objects can be achieved either by using
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java b/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
index 157541adb..980bcd34f 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
@@ -25,7 +25,9 @@ import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.Procedure;
import org.apache.cayenne.map.SQLResult;
+import org.apache.cayenne.util.ToStringBuilder;
import java.util.ArrayList;
import java.util.Arrays;
@@ -65,7 +67,7 @@ import java.util.stream.Stream;
*
* @since 1.1
*/
-public class SQLTemplate extends AbstractQuery {
+public class SQLTemplate extends CacheableQuery {
private static final long serialVersionUID = -3073521388289663641L;
@@ -116,14 +118,47 @@ public class SQLTemplate extends AbstractQuery {
Collections.addAll(resultColumnsTypes, types);
}
- @Override
+ /**
+ * The root object of this query. May be an entity name, Java class, ObjEntity or
+ * DbEntity, depending on how the query was constructed. Null root is allowed.
+ */
+ protected Object root;
+
+ /**
+ * Returns the root of this query.
+ */
+ public Object getRoot() {
+ return root;
+ }
+
+ /**
+ * Sets the root of the query.
+ *
+ * @param value The new root
+ * @throws IllegalArgumentException if value is not a String, ObjEntity, DbEntity,
+ * Procedure, DataMap, Class or null.
+ */
public void setRoot(Object value) {
- // allow null root...
- if (value == null) {
- this.root = null;
- } else {
- super.setRoot(value);
+ if (value != null && !(value instanceof String
+ || value instanceof ObjEntity
+ || value instanceof DbEntity
+ || value instanceof Class
+ || value instanceof Procedure
+ || value instanceof DataMap)) {
+
+ throw new IllegalArgumentException(("%s: \"setRoot(..)\" takes a DataMap, String, ObjEntity, DbEntity, "
+ + "Procedure, or Class. It was passed a %s")
+ .formatted(getClass().getName(), value.getClass().getName()));
}
+
+ this.root = value;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .append("root", root)
+ .toString();
}
@Override
diff --git a/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java b/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
index 92ba8fa45..69815aac9 100644
--- a/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
@@ -47,7 +47,7 @@ public class SelectQueryDescriptorTest {
builder.setRoot(entity);
assertTrue(builder.buildQuery() instanceof ObjectSelect);
- assertSame(entity, builder.buildQuery().getRoot());
+ assertEquals(entity.getName(), builder.buildQuery().getEntityName());
}
@Test
diff --git a/cayenne/src/test/java/org/apache/cayenne/query/AbstractQueryTest.java b/cayenne/src/test/java/org/apache/cayenne/query/AbstractQueryTest.java
deleted file mode 100644
index e260d91df..000000000
--- a/cayenne/src/test/java/org/apache/cayenne/query/AbstractQueryTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.query;
-
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.testdo.testmap.Artist;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class AbstractQueryTest {
-
- @Test
- public void setRootEntityName() {
- AbstractQuery query = new MockAbstractQuery();
- assertNull(query.getRoot());
- query.setRoot("SomeEntity");
- assertSame("SomeEntity", query.getRoot());
- }
-
- @Test
- public void setRootObjEntity() {
- AbstractQuery query = new MockAbstractQuery();
-
- assertNull(query.getRoot());
- ObjEntity e = new ObjEntity("ABC");
- query.setRoot(e);
- assertSame(e, query.getRoot());
- }
-
- @Test
- public void setRootClass() {
- AbstractQuery query = new MockAbstractQuery();
- assertNull(query.getRoot());
- query.setRoot(Artist.class);
- assertSame(Artist.class, query.getRoot());
- }
-
- @Test
- public void setInvalidRoot() {
- AbstractQuery query = new MockAbstractQuery();
- assertNull(query.getRoot());
- assertThrows(IllegalArgumentException.class, () -> query.setRoot(1));
- }
-}
diff --git a/cayenne/src/test/java/org/apache/cayenne/query/MockAbstractQuery.java b/cayenne/src/test/java/org/apache/cayenne/query/MockAbstractQuery.java
deleted file mode 100644
index c56510665..000000000
--- a/cayenne/src/test/java/org/apache/cayenne/query/MockAbstractQuery.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*****************************************************************
- * 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
- *
- * https://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.cayenne.query;
-
-
-public class MockAbstractQuery extends AbstractQuery {
-
- public MockAbstractQuery() {
-
- }
-
- @Override
- public SQLAction createSQLAction(SQLActionVisitor visitor) {
- return null;
- }
-
- @Override
- protected BaseQueryMetadata getBaseMetaData() {
- return null;
- }
-}
diff --git a/cayenne/src/test/java/org/apache/cayenne/query/ProcedureQueryTest.java b/cayenne/src/test/java/org/apache/cayenne/query/ProcedureQueryTest.java
index 167e75895..e37b3a26b 100644
--- a/cayenne/src/test/java/org/apache/cayenne/query/ProcedureQueryTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/query/ProcedureQueryTest.java
@@ -19,16 +19,38 @@
package org.apache.cayenne.query;
+import org.apache.cayenne.map.Procedure;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ProcedureQueryTest {
+ @Test
+ public void setRootProcedureName() {
+ ProcedureQuery query = new ProcedureQuery("SomeProcedure");
+ assertSame("SomeProcedure", query.getRoot());
+ }
+
+ @Test
+ public void setRootProcedure() {
+ Procedure procedure = new Procedure("ABC");
+ ProcedureQuery query = new ProcedureQuery(procedure);
+ assertSame(procedure, query.getRoot());
+ }
+
+ @Test
+ public void setInvalidRoot() {
+ ProcedureQuery query = new ProcedureQuery();
+ assertNull(query.getRoot());
+ assertThrows(IllegalArgumentException.class, () -> query.setRoot(1));
+ }
+
@Test
public void columnNameCapitalization() {
ProcedureQuery q1 = new ProcedureQuery();
diff --git a/cayenne/src/test/java/org/apache/cayenne/query/SQLTemplateTest.java b/cayenne/src/test/java/org/apache/cayenne/query/SQLTemplateTest.java
index 95d1212e7..0cdbd4c83 100644
--- a/cayenne/src/test/java/org/apache/cayenne/query/SQLTemplateTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/query/SQLTemplateTest.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -32,11 +33,56 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.testdo.testmap.Artist;
import org.apache.cayenne.util.Util;
import org.junit.jupiter.api.Test;
public class SQLTemplateTest {
+ @Test
+ public void setRootEntityName() {
+ SQLTemplate query = new SQLTemplate();
+ assertNull(query.getRoot());
+
+ query.setRoot("SomeEntity");
+ assertSame("SomeEntity", query.getRoot());
+ }
+
+ @Test
+ public void setRootObjEntity() {
+ SQLTemplate query = new SQLTemplate();
+ assertNull(query.getRoot());
+
+ ObjEntity e = new ObjEntity("ABC");
+ query.setRoot(e);
+ assertSame(e, query.getRoot());
+ }
+
+ @Test
+ public void setRootClass() {
+ SQLTemplate query = new SQLTemplate();
+ assertNull(query.getRoot());
+
+ query.setRoot(Artist.class);
+ assertSame(Artist.class, query.getRoot());
+ }
+
+ @Test
+ public void setRootNull() {
+ SQLTemplate query = new SQLTemplate();
+ query.setRoot("SomeEntity");
+
+ query.setRoot(null);
+ assertNull(query.getRoot());
+ }
+
+ @Test
+ public void setInvalidRoot() {
+ SQLTemplate query = new SQLTemplate();
+ assertThrows(IllegalArgumentException.class, () -> query.setRoot(1));
+ }
+
@Test
public void setParams() throws Exception {
SQLTemplate query = new SQLTemplate();
(cayenne) 01/05: Query cleanup .. route() can be implemented at the top
Posted by aa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 8ba638365c6475e137a3a103a515ed1f8fb3f164
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Aug 30 13:34:02 2026 -0400
Query cleanup .. route() can be implemented at the top
---
.../org/apache/cayenne/query/AbstractQuery.java | 18 ----------------
.../java/org/apache/cayenne/query/BatchQuery.java | 8 --------
.../java/org/apache/cayenne/query/EJBQLQuery.java | 12 -----------
.../org/apache/cayenne/query/FluentSelect.java | 2 +-
.../main/java/org/apache/cayenne/query/Query.java | 15 +++++++++++++-
.../java/org/apache/cayenne/query/SQLTemplate.java | 24 +++++++++++-----------
6 files changed, 27 insertions(+), 52 deletions(-)
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
index 71d5401cc..f3dfa8fa5 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/AbstractQuery.java
@@ -19,7 +19,6 @@
package org.apache.cayenne.query;
-import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
@@ -98,21 +97,4 @@ public abstract class AbstractQuery extends CacheableQuery {
* @since 1.2
*/
public abstract SQLAction createSQLAction(SQLActionVisitor visitor);
-
- /**
- * Implements default routing mechanism relying on the EntityResolver to find DataMap
- * based on the query root. This mechanism should be sufficient for most queries that
- * "know" their root.
- *
- * @since 1.2
- */
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- DataMap map = getMetaData(resolver).getDataMap();
-
- if (map == null) {
- throw new CayenneRuntimeException("No DataMap found, can't route query %s", this);
- }
-
- router.route(router.nodeForDataMap(map), this, substitutedQuery);
- }
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/BatchQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/BatchQuery.java
index 43cff829b..a4e7cfe32 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/BatchQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/BatchQuery.java
@@ -71,14 +71,6 @@ public abstract class BatchQuery implements Query {
};
}
- /**
- * @since 1.2
- */
- @Override
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- router.route(router.nodeForDataMap(dbEntity.getDataMap()), this, substitutedQuery);
- }
-
/**
* Calls "batchAction" on the visitor.
*
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
index dd5a06dcb..f49436d7b 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
@@ -22,11 +22,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLParserFactory;
-import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.EntityResolver;
/**
@@ -78,16 +76,6 @@ public class EJBQLQuery extends CacheableQuery {
return metadata;
}
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- DataMap map = getMetaData(resolver).getDataMap();
-
- if (map == null) {
- throw new CayenneRuntimeException("No DataMap found, can't route query %s", this);
- }
-
- router.route(router.nodeForDataMap(map), this, substitutedQuery);
- }
-
public SQLAction createSQLAction(SQLActionVisitor visitor) {
return visitor.ejbqlAction(this);
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
index 093fc2731..e7cfb1512 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -493,7 +493,7 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Abst
@Override
public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- super.route(router, resolver, substitutedQuery);
+ Select.super.route(router, resolver, substitutedQuery);
// suppress prefetches for paginated queries.. instead prefetches will be resolved per row...
if (getPageSize() <= 0) {
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/Query.java b/cayenne/src/main/java/org/apache/cayenne/query/Query.java
index 423f83319..aae9a33e4 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/Query.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/Query.java
@@ -19,7 +19,9 @@
package org.apache.cayenne.query;
+import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.EntityResolver;
import java.io.Serializable;
@@ -45,10 +47,21 @@ public interface Query extends Serializable {
* {@link QueryRouter#route(DataNode, Query, Query)} callback method to route
* itself. Query can create one or more substitute queries or even provide its own
* DataNode to execute itself.
+ * <p>
+ * The default implementation relies on the EntityResolver to find the DataMap based on
+ * the query metadata. This mechanism is sufficient for most queries that "know" their root.
*
* @since 1.2
*/
- void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery);
+ default void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
+ DataMap map = getMetaData(resolver).getDataMap();
+
+ if (map == null) {
+ throw new CayenneRuntimeException("No DataMap found, can't route query %s", this);
+ }
+
+ router.route(router.nodeForDataMap(map), this, substitutedQuery);
+ }
/**
* A callback method invoked by Cayenne during the final execution phase of the query
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java b/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
index dadbeafca..157541adb 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
@@ -19,6 +19,14 @@
package org.apache.cayenne.query;
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.SQLResult;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -30,14 +38,6 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataNode;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.SQLResult;
-
/**
* A query that executes unchanged (except for template preprocessing) "raw" SQL
* specified by the user. <h3>Template Script</h3>
@@ -130,14 +130,14 @@ public class SQLTemplate extends AbstractQuery {
public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
DataMap map = getMetaData(resolver).getDataMap();
- DataNode engine;
+ DataNode dataNode;
if (map != null) {
- engine = router.nodeForDataMap(map);
+ dataNode = router.nodeForDataMap(map);
} else {
- engine = router.nodeForName(getDataNodeName());
+ dataNode = router.nodeForName(getDataNodeName());
}
- router.route(engine, this, substitutedQuery);
+ router.route(dataNode, this, substitutedQuery);
}
/**