This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new ab7fddb8a Add generics to FluentSelect to merge identical code in
ObjectSelect and ColumnSelect
ab7fddb8a is described below
commit ab7fddb8a04eb06cbe79e50ca41a72a0159858de
Author: Nikita Timofeev <[email protected]>
AuthorDate: Fri Jul 15 18:46:37 2022 +0300
Add generics to FluentSelect to merge identical code in ObjectSelect and
ColumnSelect
---
.../translator/select/DefaultSelectTranslator.java | 2 +-
.../select/DefaultSelectTranslatorFactory.java | 2 +-
.../translator/select/FluentSelectWrapper.java | 6 +-
.../java/org/apache/cayenne/dba/AutoAdapter.java | 2 +-
.../java/org/apache/cayenne/dba/DbAdapter.java | 2 +-
.../org/apache/cayenne/dba/JdbcActionBuilder.java | 2 +-
.../java/org/apache/cayenne/dba/JdbcAdapter.java | 2 +-
.../apache/cayenne/dba/db2/DB2ActionBuilder.java | 2 +-
.../cayenne/dba/derby/DerbyActionBuilder.java | 2 +-
.../dba/firebird/FirebirdActionBuilder.java | 2 +-
.../org/apache/cayenne/dba/h2/H2ActionBuilder.java | 2 +-
.../cayenne/dba/hsqldb/HSQLActionBuilder.java | 2 +-
.../cayenne/dba/ingres/IngresActionBuilder.java | 2 +-
.../cayenne/dba/mysql/MySQLActionBuilder.java | 2 +-
.../cayenne/dba/oracle/OracleActionBuilder.java | 2 +-
.../dba/postgres/PostgresActionBuilder.java | 2 +-
.../cayenne/dba/sqlite/SQLiteActionBuilder.java | 2 +-
.../dba/sqlserver/SQLServerActionBuilder.java | 4 +-
.../org/apache/cayenne/exp/ExpressionFactory.java | 4 +-
.../org/apache/cayenne/exp/parser/ASTSubquery.java | 2 +-
.../org/apache/cayenne/query/ColumnSelect.java | 361 +--------------------
.../apache/cayenne/query/ColumnSelectMetadata.java | 4 +-
.../org/apache/cayenne/query/FluentSelect.java | 357 +++++++++++++++++++-
.../query/FluentSelectPrefetchRouterAction.java | 4 +-
.../org/apache/cayenne/query/ObjectSelect.java | 354 +-------------------
.../apache/cayenne/query/ObjectSelectMetadata.java | 10 +-
.../org/apache/cayenne/query/SQLActionVisitor.java | 2 +-
.../org/apache/cayenne/query/ColumnSelectTest.java | 11 +-
28 files changed, 408 insertions(+), 743 deletions(-)
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
index 203d1c1af..0aacf108f 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslator.java
@@ -76,7 +76,7 @@ public class DefaultSelectTranslator implements
SelectTranslator {
this.context = new TranslatorContext(query, adapter, entityResolver,
null);
}
- public DefaultSelectTranslator(FluentSelect<?> query, DbAdapter adapter,
EntityResolver entityResolver) {
+ public DefaultSelectTranslator(FluentSelect<?, ?> query, DbAdapter
adapter, EntityResolver entityResolver) {
this(new FluentSelectWrapper(query), adapter, entityResolver);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslatorFactory.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslatorFactory.java
index e429b27f0..0c38c9ab0 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslatorFactory.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DefaultSelectTranslatorFactory.java
@@ -35,7 +35,7 @@ public class DefaultSelectTranslatorFactory implements
SelectTranslatorFactory {
@Override
public SelectTranslator translator(Select<?> query, DbAdapter adapter,
EntityResolver entityResolver) {
if(query instanceof FluentSelect) {
- return
adapter.getSelectTranslator((FluentSelect<?>)query, entityResolver);
+ return adapter.getSelectTranslator((FluentSelect<?,
?>)query, entityResolver);
}
throw new CayenneRuntimeException("Unsupported type of Select
query %s", query);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
index 3c4bed7a3..8eb442d9b 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/FluentSelectWrapper.java
@@ -34,9 +34,9 @@ import org.apache.cayenne.query.QueryMetadata;
*/
public class FluentSelectWrapper implements TranslatableQueryWrapper {
- private final FluentSelect<?> select;
+ private final FluentSelect<?, ?> select;
- public FluentSelectWrapper(FluentSelect<?> select) {
+ public FluentSelectWrapper(FluentSelect<?, ?> select) {
this.select = Objects.requireNonNull(select);
}
@@ -71,7 +71,7 @@ public class FluentSelectWrapper implements
TranslatableQueryWrapper {
}
@Override
- public FluentSelect<?> unwrap() {
+ public FluentSelect<?, ?> unwrap() {
return select;
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
index 45a374ce4..845154bfa 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
@@ -101,7 +101,7 @@ public class AutoAdapter implements DbAdapter {
* @since 4.2
*/
@Override
- public SelectTranslator getSelectTranslator(FluentSelect<?> query,
EntityResolver entityResolver) {
+ public SelectTranslator getSelectTranslator(FluentSelect<?, ?> query,
EntityResolver entityResolver) {
return getAdapter().getSelectTranslator(query, entityResolver);
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
index c6bc77394..aa4ba1c18 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
@@ -56,7 +56,7 @@ public interface DbAdapter {
/**
* @since 4.2
*/
- SelectTranslator getSelectTranslator(FluentSelect<?> query,
EntityResolver entityResolver);
+ SelectTranslator getSelectTranslator(FluentSelect<?, ?> query,
EntityResolver entityResolver);
/**
* @since 4.2
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcActionBuilder.java
index 8433e6cd6..2542931d2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcActionBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcActionBuilder.java
@@ -70,7 +70,7 @@ public class JdbcActionBuilder implements SQLActionVisitor {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new SelectAction(query, dataNode);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
index 479b9da6c..06451fd6f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
@@ -508,7 +508,7 @@ public class JdbcAdapter implements DbAdapter {
}
@Override
- public SelectTranslator getSelectTranslator(FluentSelect<?> query,
EntityResolver entityResolver) {
+ public SelectTranslator getSelectTranslator(FluentSelect<?, ?> query,
EntityResolver entityResolver) {
return new DefaultSelectTranslator(query, this, entityResolver);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2ActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2ActionBuilder.java
index 5ef0f5216..46f29ac07 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2ActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2ActionBuilder.java
@@ -42,7 +42,7 @@ public class DB2ActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new DB2SelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyActionBuilder.java
index 46ea873a5..15801be22 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyActionBuilder.java
@@ -37,7 +37,7 @@ public class DerbyActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new DerbySelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdActionBuilder.java
index eca046e53..fb5b306ab 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdActionBuilder.java
@@ -37,7 +37,7 @@ public class FirebirdActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new FirebirdSelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2ActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2ActionBuilder.java
index 37c0a2187..36be4d966 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2ActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2ActionBuilder.java
@@ -36,7 +36,7 @@ public class H2ActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new H2SelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLActionBuilder.java
index 75aea976f..6a83b0b30 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLActionBuilder.java
@@ -39,7 +39,7 @@ class HSQLActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new HSQLSelectAction(query, dataNode);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresActionBuilder.java
index 76b874121..7efae8dca 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresActionBuilder.java
@@ -36,7 +36,7 @@ public class IngresActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new IngresSelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java
index d446ce35b..b55f488fa 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java
@@ -38,7 +38,7 @@ class MySQLActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new MySQLSelectAction(query, dataNode);
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleActionBuilder.java
index bb033f973..94fa21547 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleActionBuilder.java
@@ -62,7 +62,7 @@ class OracleActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new OracleSelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresActionBuilder.java
index 3051c0eb1..191be3e4b 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresActionBuilder.java
@@ -55,7 +55,7 @@ class PostgresActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new PostgresSelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteActionBuilder.java
index c2be85d8b..74e25fd97 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteActionBuilder.java
@@ -42,7 +42,7 @@ class SQLiteActionBuilder extends JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new SQLiteSelectAction(query, dataNode);
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
index f7d78452a..ce806a5f6 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerActionBuilder.java
@@ -75,11 +75,11 @@ public class SQLServerActionBuilder extends
JdbcActionBuilder {
* @since 4.2
*/
@Override
- public <T> SQLAction objectSelectAction(FluentSelect<T> query) {
+ public <T> SQLAction objectSelectAction(FluentSelect<T, ?> query) {
return new SQLServerSelectAction(query, dataNode,
needInMemoryOffset(query));
}
- private boolean needInMemoryOffset(FluentSelect<?> query) {
+ private boolean needInMemoryOffset(FluentSelect<?, ?> query) {
return query.getOrderings() == null ||
query.getOrderings().size() == 0
|| version == null || version < 12;
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
index 7d3b207ac..094e352e4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
@@ -1437,7 +1437,7 @@ public class ExpressionFactory {
* @param subQuery {@link org.apache.cayenne.query.ObjectSelect} or
{@link ColumnSelect}
* @since 4.2
*/
- public static Expression exists(FluentSelect<?> subQuery) {
+ public static Expression exists(FluentSelect<?, ?> subQuery) {
return new ASTExists(new ASTSubquery(subQuery));
}
@@ -1445,7 +1445,7 @@ public class ExpressionFactory {
* @param subQuery {@link org.apache.cayenne.query.ObjectSelect} or
{@link ColumnSelect}
* @since 4.2
*/
- public static Expression notExists(FluentSelect<?> subQuery) {
+ public static Expression notExists(FluentSelect<?, ?> subQuery) {
return new ASTNotExists(new ASTSubquery(subQuery));
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
index 32b5d7582..c2aa5fc9d 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubquery.java
@@ -35,7 +35,7 @@ public class ASTSubquery extends SimpleNode {
private final TranslatableQueryWrapper query;
- public ASTSubquery(FluentSelect<?> query) {
+ public ASTSubquery(FluentSelect<?, ?> query) {
this(new FluentSelectWrapper(query));
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
index dd74e6063..8af55e47d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
@@ -19,9 +19,7 @@
package org.apache.cayenne.query;
-import java.sql.Statement;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Function;
@@ -34,9 +32,7 @@ import org.apache.cayenne.exp.property.ComparableProperty;
import org.apache.cayenne.exp.property.NumericProperty;
import org.apache.cayenne.exp.property.Property;
import org.apache.cayenne.exp.property.PropertyFactory;
-import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
/**
* <p>A helper builder for queries selecting individual properties based on
the root object.</p>
@@ -65,13 +61,10 @@ import org.apache.cayenne.map.ObjEntity;
*
* @since 4.0
*/
-public class ColumnSelect<T> extends FluentSelect<T> {
+public class ColumnSelect<T> extends FluentSelect<T, ColumnSelect<T>> {
- private Collection<Property<?>> columns;
- // package private for tests
- boolean singleColumn = true;
-
- ColumnSelectMetadata metaData = new ColumnSelectMetadata();
+ protected Collection<Property<?>> columns;
+ protected boolean singleColumn = true;
protected ColumnSelect() {
}
@@ -89,286 +82,9 @@ public class ColumnSelect<T> extends FluentSelect<T> {
this.metaData.copyFromInfo(select.metaData);
}
- /**
- * Sets the type of the entity to fetch without changing the return type of
- * the query.
- *
- * @return this object
- */
- public ColumnSelect<T> entityType(Class<?> entityType) {
- return resetEntity(entityType, null, null);
- }
-
- /**
- * Sets the {@link ObjEntity} name to fetch without changing the return
type
- * of the query. This form is most often used for generic entities that
- * don't map to a distinct class.
- *
- * @return this object
- */
- public ColumnSelect<T> entityName(String entityName) {
- return resetEntity(null, entityName, null);
- }
-
- /**
- * Sets the {@link DbEntity} name to fetch without changing the return type
- * of the query. This form is most often used for generic entities that
- * don't map to a distinct class.
- *
- * @return this object
- */
- public ColumnSelect<T> dbEntityName(String dbEntityName) {
- return resetEntity(null, null, dbEntityName);
- }
-
- private ColumnSelect<T> resetEntity(Class<?> entityType, String
entityName, String dbEntityName) {
- this.entityType = entityType;
- this.entityName = entityName;
- this.dbEntityName = dbEntityName;
- return this;
- }
-
- /**
- * Appends a qualifier expression of this query. An equivalent to
- * {@link #and(Expression...)} that can be used a syntactic sugar.
- *
- * @return this object
- */
- public ColumnSelect<T> where(Expression expression) {
- return and(expression);
- }
-
- /**
- * Appends a qualifier expression of this query, using provided expression
- * String and an array of position parameters. This is an equivalent to
- * calling "and".
- *
- * @return this object
- */
- public ColumnSelect<T> where(String expressionString, Object...
parameters) {
- return and(ExpressionFactory.exp(expressionString, parameters));
- }
-
- /**
- * AND's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ColumnSelect<T> and(Expression... expressions) {
- if (expressions == null || expressions.length == 0) {
- return this;
- }
-
- return and(Arrays.asList(expressions));
- }
-
- /**
- * OR's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ColumnSelect<T> or(Expression... expressions) {
- if (expressions == null || expressions.length == 0) {
- return this;
- }
-
- return or(Arrays.asList(expressions));
- }
-
- /**
- * Add an ascending ordering on the given property. If there is already an
ordering
- * on this query then add this ordering with a lower priority.
- *
- * @param property the property to sort on
- * @return this object
- */
- public ColumnSelect<T> orderBy(String property) {
- return orderBy(new Ordering(property));
- }
-
- /**
- * Add an ordering on the given property. If there is already an ordering
- * on this query then add this ordering with a lower priority.
- *
- * @param property the property to sort on
- * @param sortOrder the direction of the ordering
- * @return this object
- */
- public ColumnSelect<T> orderBy(String property, SortOrder sortOrder) {
- return orderBy(new Ordering(property, sortOrder));
- }
-
- /**
- * Add one or more orderings to this query.
- *
- * @return this object
- */
- public ColumnSelect<T> orderBy(Ordering... orderings) {
-
- if (orderings == null) {
- return this;
- }
-
- if (this.orderings == null) {
- this.orderings = new ArrayList<>(orderings.length);
- }
-
- Collections.addAll(this.orderings, orderings);
- return this;
- }
-
- /**
- * Adds a list of orderings to this query.
- *
- * @return this object
- */
- public ColumnSelect<T> orderBy(Collection<Ordering> orderings) {
-
- if (orderings == null) {
- return this;
- }
-
- if (this.orderings == null) {
- this.orderings = new ArrayList<>(orderings.size());
- }
-
- this.orderings.addAll(orderings);
- return this;
- }
-
- /**
- * Merges prefetch into the query prefetch tree.
- *
- * @return this object
- */
- public ColumnSelect<T> prefetch(PrefetchTreeNode prefetch) {
- metaData.mergePrefetch(prefetch);
- return this;
- }
-
- /**
- * Merges a prefetch path with specified semantics into the query prefetch
- * tree.
- *
- * @return this object
- */
- public ColumnSelect<T> prefetch(String path, int semantics) {
- if (path == null) {
- return this;
- }
- metaData.addPrefetch(path, semantics);
- return this;
- }
-
- /**
- * Resets query fetch limit - a parameter that defines max number of
objects
- * that should be ever be fetched from the database.
- */
- public ColumnSelect<T> limit(int fetchLimit) {
- this.metaData.setFetchLimit(fetchLimit);
- return this;
- }
-
- /**
- * Resets query fetch offset - a parameter that defines how many objects
- * should be skipped when reading data from the database.
- */
- public ColumnSelect<T> offset(int fetchOffset) {
- this.metaData.setFetchOffset(fetchOffset);
- return this;
- }
-
- /**
- * Resets query page size. A non-negative page size enables query result
- * pagination that saves memory and processing time for large lists if only
- * parts of the result are ever going to be accessed.
- */
- public ColumnSelect<T> pageSize(int pageSize) {
- this.metaData.setPageSize(pageSize);
- return this;
- }
-
- /**
- * Sets fetch size of the PreparedStatement generated for this query. Only
- * non-negative values would change the default size.
- *
- * @see Statement#setFetchSize(int)
- */
- public ColumnSelect<T> statementFetchSize(int size) {
- this.metaData.setStatementFetchSize(size);
- return this;
- }
-
- /**
- * Sets query timeout of PreparedStatement generated for this query.
- * @see Statement#setQueryTimeout(int)
- */
- public ColumnSelect<T> queryTimeout(int timeout) {
- this.metaData.setQueryTimeout(timeout);
- return this;
- }
-
- public ColumnSelect<T> cacheStrategy(QueryCacheStrategy strategy) {
- setCacheStrategy(strategy);
- setCacheGroup(null);
- return this;
- }
-
- public ColumnSelect<T> cacheStrategy(QueryCacheStrategy strategy, String
cacheGroup) {
- return cacheStrategy(strategy).cacheGroup(cacheGroup);
- }
-
- public ColumnSelect<T> cacheGroup(String cacheGroup) {
- setCacheGroup(cacheGroup);
- return this;
- }
-
- /**
- * Instructs Cayenne to look for query results in the "local" cache when
- * running the query. This is a short-hand notation for:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
- * </pre>
- */
- public ColumnSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
- * </pre>
- */
- public ColumnSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
- * </pre>
- */
- public ColumnSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
- * </pre>
- */
- public ColumnSelect<T> sharedCache() {
- return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ @Override
+ protected ColumnSelectMetadata createMetadata() {
+ return new ColumnSelectMetadata();
}
/**
@@ -428,7 +144,7 @@ public class ColumnSelect<T> extends FluentSelect<T> {
}
@SuppressWarnings("unchecked")
- protected <E> ColumnSelect<E> column(Property<E> property) {
+ protected <E> ColumnSelect<E> column(Property<E> property) {
if (this.columns == null) {
this.columns = new ArrayList<>(1);
} else {
@@ -509,62 +225,11 @@ public class ColumnSelect<T> extends FluentSelect<T> {
return and(ExpressionFactory.exp(expressionString, parameters));
}
- /**
- * AND's provided expressions to the existing WHERE or HAVING clause
expression.
- *
- * @return this object
- */
- public ColumnSelect<T> and(Collection<Expression> expressions) {
-
- if (expressions == null || expressions.isEmpty()) {
- return this;
- }
-
- Collection<Expression> all;
- Expression activeExpression = getActiveExpression();
-
- if (activeExpression != null) {
- all = new ArrayList<>(expressions.size() + 1);
- all.add(activeExpression);
- all.addAll(expressions);
- } else {
- all = expressions;
- }
-
- setActiveExpression(ExpressionFactory.and(all));
- return this;
- }
-
- /**
- * OR's provided expressions to the existing WHERE or HAVING clause
expression.
- *
- * @return this object
- */
- public ColumnSelect<T> or(Collection<Expression> expressions) {
- if (expressions == null || expressions.isEmpty()) {
- return this;
- }
-
- Collection<Expression> all;
- Expression activeExpression = getActiveExpression();
-
- if (activeExpression != null) {
- all = new ArrayList<>(expressions.size() + 1);
- all.add(activeExpression);
- all.addAll(expressions);
- } else {
- all = expressions;
- }
-
- setActiveExpression(ExpressionFactory.or(all));
- return this;
- }
-
/**
* Explicitly request distinct in query.
*/
public ColumnSelect<T> distinct() {
- metaData.setSuppressingDistinct(false);
+ getBaseMetaData().setSuppressingDistinct(false);
this.distinct = true;
return this;
}
@@ -573,7 +238,7 @@ public class ColumnSelect<T> extends FluentSelect<T> {
* Explicitly suppress distinct in query.
*/
public ColumnSelect<T> suppressDistinct() {
- metaData.setSuppressingDistinct(true);
+ getBaseMetaData().setSuppressingDistinct(true);
this.distinct = false;
return this;
}
@@ -595,13 +260,13 @@ public class ColumnSelect<T> extends FluentSelect<T> {
@Override
public QueryMetadata getMetaData(EntityResolver resolver) {
Object root = resolveRoot(resolver);
- metaData.resolve(root, resolver, this);
+ getBaseMetaData().resolve(root, resolver, this);
return metaData;
}
@Override
- protected BaseQueryMetadata getBaseMetaData() {
- return metaData;
+ protected ColumnSelectMetadata getBaseMetaData() {
+ return (ColumnSelectMetadata) metaData;
}
/**
@@ -618,7 +283,7 @@ public class ColumnSelect<T> extends FluentSelect<T> {
*/
@SuppressWarnings("unchecked")
public <E> ColumnSelect<E> map(Function<T, E> mapper) {
- this.metaData.setResultMapper(mapper);
+ getBaseMetaData().setResultMapper(mapper);
return (ColumnSelect<E>)this;
}
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelectMetadata.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelectMetadata.java
index 365853dce..76b780cdb 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelectMetadata.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelectMetadata.java
@@ -65,12 +65,12 @@ class ColumnSelectMetadata extends ObjectSelectMetadata {
}
@Override
- protected void resolveAutoAliases(FluentSelect<?> query) {
+ protected void resolveAutoAliases(FluentSelect<?, ?> query) {
super.resolveAutoAliases(query);
resolveColumnsAliases(query);
}
- protected void resolveColumnsAliases(FluentSelect<?> query) {
+ protected void resolveColumnsAliases(FluentSelect<?, ?> query) {
Collection<Property<?>> columns = query.getColumns();
if(columns != null) {
for(Property<?> property : columns) {
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
index 8dad2deb0..cf024f309 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -19,9 +19,14 @@
package org.apache.cayenne.query;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.ObjectContext;
@@ -29,6 +34,7 @@ import org.apache.cayenne.ResultBatchIterator;
import org.apache.cayenne.ResultIterator;
import org.apache.cayenne.ResultIteratorCallback;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.exp.property.Property;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
@@ -39,7 +45,7 @@ import org.apache.cayenne.map.ObjEntity;
*
* @since 4.0
*/
-public abstract class FluentSelect<T> extends AbstractQuery implements
Select<T> {
+public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends
AbstractQuery implements Select<T> {
// root
protected Class<?> entityType;
@@ -48,14 +54,19 @@ public abstract class FluentSelect<T> extends AbstractQuery
implements Select<T>
protected Expression where;
protected Expression having;
- boolean havingExpressionIsActive = false;
+ protected boolean havingExpressionIsActive = false;
protected Collection<Ordering> orderings;
- boolean distinct;
+ protected boolean distinct;
+
+ protected ObjectSelectMetadata metaData;
protected FluentSelect() {
+ metaData = createMetadata();
}
+ protected abstract ObjectSelectMetadata createMetadata();
+
protected Object resolveRoot(EntityResolver resolver) {
Object root;
if (entityType != null) {
@@ -82,6 +93,340 @@ public abstract class FluentSelect<T> extends AbstractQuery
implements Select<T>
return root;
}
+ /**
+ * Sets the type of the entity to fetch without changing the return type of
+ * the query.
+ *
+ * @return this object
+ */
+ public S entityType(Class<?> entityType) {
+ return resetEntity(entityType, null, null);
+ }
+
+ /**
+ * Sets the {@link ObjEntity} name to fetch without changing the return
type
+ * of the query. This form is most often used for generic entities that
+ * don't map to a distinct class.
+ *
+ * @return this object
+ */
+ public S entityName(String entityName) {
+ return resetEntity(null, entityName, null);
+ }
+
+ /**
+ * Sets the {@link DbEntity} name to fetch without changing the return type
+ * of the query. This form is most often used for generic entities that
+ * don't map to a distinct class.
+ *
+ * @return this object
+ */
+ public S dbEntityName(String dbEntityName) {
+ return resetEntity(null, null, dbEntityName);
+ }
+
+ @SuppressWarnings("unchecked")
+ private S resetEntity(Class<?> entityType, String entityName, String
dbEntityName) {
+ this.entityType = entityType;
+ this.entityName = entityName;
+ this.dbEntityName = dbEntityName;
+ return (S)this;
+ }
+
+ /**
+ * Appends a qualifier expression of this query. An equivalent to
+ * {@link #and(Expression...)} that can be used a syntactic sugar.
+ *
+ * @return this object
+ */
+ public S where(Expression expression) {
+ return and(expression);
+ }
+
+ /**
+ * Appends a qualifier expression of this query, using provided expression
+ * String and an array of position parameters. This is an equivalent to
+ * calling "and".
+ *
+ * @return this object
+ */
+ public S where(String expressionString, Object... parameters) {
+ return and(ExpressionFactory.exp(expressionString, parameters));
+ }
+
+ /**
+ * AND's provided expressions to the existing WHERE clause expression.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S and(Expression... expressions) {
+ if (expressions == null || expressions.length == 0) {
+ return (S)this;
+ }
+ return and(Arrays.asList(expressions));
+ }
+
+ /**
+ * AND's provided expressions to the existing WHERE clause expression.
+ *
+ * @return this object
+ */
+
+ public S and(Collection<Expression> expressions) {
+ return joinExpression(expressions, ExpressionFactory::and);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected S joinExpression(Collection<Expression> expressions,
Function<Collection<Expression>, Expression> joiner) {
+ if (expressions == null || expressions.isEmpty()) {
+ return (S)this;
+ }
+
+ Collection<Expression> all;
+ Expression activeExpression = getActiveExpression();
+ if (activeExpression != null) {
+ all = new ArrayList<>(expressions.size() + 1);
+ all.add(activeExpression);
+ all.addAll(expressions);
+ } else {
+ all = expressions;
+ }
+
+ setActiveExpression(joiner.apply(all));
+ return (S)this;
+ }
+
+ /**
+ * OR's provided expressions to the existing WHERE clause expression.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S or(Expression... expressions) {
+ if (expressions == null || expressions.length == 0) {
+ return (S)this;
+ }
+ return or(Arrays.asList(expressions));
+ }
+
+ /**
+ * OR's provided expressions to the existing WHERE clause expression.
+ *
+ * @return this object
+ */
+ public S or(Collection<Expression> expressions) {
+ return joinExpression(expressions, ExpressionFactory::or);
+ }
+
+ /**
+ * Add an ascending ordering on the given property. If there is already an
ordering
+ * on this query then add this ordering with a lower priority.
+ *
+ * @param property the property to sort on
+ * @return this object
+ */
+ public S orderBy(String property) {
+ return orderBy(new Ordering(property));
+ }
+
+ /**
+ * Add an ordering on the given property. If there is already an ordering
+ * on this query then add this ordering with a lower priority.
+ *
+ * @param property the property to sort on
+ * @param sortOrder the direction of the ordering
+ * @return this object
+ */
+ public S orderBy(String property, SortOrder sortOrder) {
+ return orderBy(new Ordering(property, sortOrder));
+ }
+
+ /**
+ * Add one or more orderings to this query.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S orderBy(Ordering... orderings) {
+
+ if (orderings == null) {
+ return (S)this;
+ }
+
+ if (this.orderings == null) {
+ this.orderings = new ArrayList<>(orderings.length);
+ }
+
+ Collections.addAll(this.orderings, orderings);
+
+ return (S)this;
+ }
+
+ /**
+ * Adds a list of orderings to this query.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S orderBy(Collection<Ordering> orderings) {
+
+ if (orderings == null) {
+ return (S)this;
+ }
+
+ if (this.orderings == null) {
+ this.orderings = new ArrayList<>(orderings.size());
+ }
+
+ this.orderings.addAll(orderings);
+
+ return (S)this;
+ }
+
+ /**
+ * Merges prefetch into the query prefetch tree.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S prefetch(PrefetchTreeNode prefetch) {
+ getBaseMetaData().mergePrefetch(prefetch);
+ return (S)this;
+ }
+
+ /**
+ * Merges a prefetch path with specified semantics into the query prefetch
tree.
+ *
+ * @return this object
+ */
+ @SuppressWarnings("unchecked")
+ public S prefetch(String path, int semantics) {
+ if (path == null) {
+ return (S)this;
+ }
+ getBaseMetaData().addPrefetch(path, semantics);
+ return (S)this;
+ }
+
+ /**
+ * Resets query fetch limit - a parameter that defines max number of
objects
+ * that should be ever be fetched from the database.
+ */
+ @SuppressWarnings("unchecked")
+ public S limit(int fetchLimit) {
+ this.getBaseMetaData().setFetchLimit(fetchLimit);
+ return (S)this;
+ }
+
+ /**
+ * Resets query fetch offset - a parameter that defines how many objects
+ * should be skipped when reading data from the database.
+ */
+ @SuppressWarnings("unchecked")
+ public S offset(int fetchOffset) {
+ this.getBaseMetaData().setFetchOffset(fetchOffset);
+ return (S)this;
+ }
+
+ /**
+ * Resets query page size. A non-negative page size enables query result
+ * pagination that saves memory and processing time for large lists if only
+ * parts of the result are ever going to be accessed.
+ */
+ @SuppressWarnings("unchecked")
+ public S pageSize(int pageSize) {
+ this.getBaseMetaData().setPageSize(pageSize);
+ return (S)this;
+ }
+
+ /**
+ * Sets fetch size of the PreparedStatement generated for this query. Only
+ * non-negative values would change the default size.
+ *
+ * @see Statement#setFetchSize(int)
+ */
+ @SuppressWarnings("unchecked")
+ public S statementFetchSize(int size) {
+ this.getBaseMetaData().setStatementFetchSize(size);
+ return (S)this;
+ }
+
+ /**
+ * Sets query timeout of PreparedStatement generated for this query.
+ * @see Statement#setQueryTimeout(int)
+ */
+ @SuppressWarnings("unchecked")
+ public S queryTimeout(int timeout) {
+ this.getBaseMetaData().setQueryTimeout(timeout);
+ return (S)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public S cacheStrategy(QueryCacheStrategy strategy) {
+ setCacheStrategy(strategy);
+ setCacheGroup(null);
+ return (S)this;
+ }
+
+ public S cacheStrategy(QueryCacheStrategy strategy, String cacheGroup) {
+ return cacheStrategy(strategy).cacheGroup(cacheGroup);
+ }
+
+ @SuppressWarnings("unchecked")
+ public S cacheGroup(String cacheGroup) {
+ setCacheGroup(cacheGroup);
+ return (S)this;
+ }
+
+ /**
+ * Instructs Cayenne to look for query results in the "local" cache when
+ * running the query. This is a short-hand notation for:
+ * <p>
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
+ * </pre>
+ */
+ public S 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:
+ * <p>
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ * </pre>
+ */
+ public S 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:
+ * <p>
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
+ * </pre>
+ */
+ public S 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:
+ * <p>
+ * <pre>
+ * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ * </pre>
+ */
+ public S sharedCache() {
+ return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ }
+
public int getStatementFetchSize() {
return getBaseMetaData().getStatementFetchSize();
}
@@ -139,7 +484,7 @@ public abstract class FluentSelect<T> extends AbstractQuery
implements Select<T>
return getBaseMetaData().getPrefetchTree();
}
- void setActiveExpression(Expression exp) {
+ protected void setActiveExpression(Expression exp) {
if(havingExpressionIsActive) {
having = exp;
} else {
@@ -147,7 +492,7 @@ public abstract class FluentSelect<T> extends AbstractQuery
implements Select<T>
}
}
- Expression getActiveExpression() {
+ protected Expression getActiveExpression() {
if(havingExpressionIsActive) {
return having;
} else {
@@ -196,7 +541,7 @@ public abstract class FluentSelect<T> extends AbstractQuery
implements Select<T>
}
public boolean isFetchingDataRows() {
- return false;
+ return getBaseMetaData().isFetchingDataRows();
}
protected void routePrefetches(QueryRouter router, EntityResolver
resolver) {
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelectPrefetchRouterAction.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelectPrefetchRouterAction.java
index f72895ac6..7da944e4c 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelectPrefetchRouterAction.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelectPrefetchRouterAction.java
@@ -35,7 +35,7 @@ import org.apache.cayenne.util.CayenneMapEntry;
*/
class FluentSelectPrefetchRouterAction implements PrefetchProcessor {
- FluentSelect<?> query;
+ FluentSelect<?, ?> query;
QueryRouter router;
EntityResolver resolver;
ClassDescriptor classDescriptor;
@@ -43,7 +43,7 @@ class FluentSelectPrefetchRouterAction implements
PrefetchProcessor {
/**
* Routes query prefetches, but not the query itself.
*/
- void route(FluentSelect<?> query, QueryRouter router, EntityResolver
resolver) {
+ void route(FluentSelect<?, ?> query, QueryRouter router, EntityResolver
resolver) {
if (!query.isFetchingDataRows() && query.getPrefetches() != null) {
this.query = query;
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
index 58f65624c..bea18d1f3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
@@ -18,11 +18,6 @@
****************************************************************/
package org.apache.cayenne.query;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -54,12 +49,10 @@ import org.apache.cayenne.map.ObjEntity;
*
* @since 4.0
*/
-public class ObjectSelect<T> extends FluentSelect<T> implements
ParameterizedQuery {
+public class ObjectSelect<T> extends FluentSelect<T, ObjectSelect<T>>
implements ParameterizedQuery {
private static final long serialVersionUID = -156124021150949227L;
- protected ObjectSelectMetadata metaData = new ObjectSelectMetadata();
-
/**
* Creates a ObjectSelect that selects objects of a given persistent class.
*/
@@ -153,64 +146,9 @@ public class ObjectSelect<T> extends FluentSelect<T>
implements ParameterizedQue
protected ObjectSelect() {
}
- /**
- * Sets the type of the entity to fetch without changing the return type of
- * the query.
- *
- * @return this object
- */
- public ObjectSelect<T> entityType(Class<?> entityType) {
- return resetEntity(entityType, null, null);
- }
-
- /**
- * Sets the {@link ObjEntity} name to fetch without changing the return
type
- * of the query. This form is most often used for generic entities that
- * don't map to a distinct class.
- *
- * @return this object
- */
- public ObjectSelect<T> entityName(String entityName) {
- return resetEntity(null, entityName, null);
- }
-
- /**
- * Sets the {@link DbEntity} name to fetch without changing the return type
- * of the query. This form is most often used for generic entities that
- * don't map to a distinct class.
- *
- * @return this object
- */
- public ObjectSelect<T> dbEntityName(String dbEntityName) {
- return resetEntity(null, null, dbEntityName);
- }
-
- private ObjectSelect<T> resetEntity(Class<?> entityType, String
entityName, String dbEntityName) {
- this.entityType = entityType;
- this.entityName = entityName;
- this.dbEntityName = dbEntityName;
- return this;
- }
-
- /**
- * Appends a qualifier expression of this query. An equivalent to
- * {@link #and(Expression...)} that can be used a syntactic sugar.
- *
- * @return this object
- */
- public ObjectSelect<T> where(Expression expression) {
- return and(expression);
- }
-
- /**
- * Appends a qualifier expression of this query, using provided expression
- * String and an array of position parameters. This is an equivalent to
- * calling "and".
- *
- * @return this object
- */
- public ObjectSelect<T> where(String expressionString, Object...
parameters) {
- return and(ExpressionFactory.exp(expressionString, parameters));
+ @Override
+ protected ObjectSelectMetadata createMetadata() {
+ return new ObjectSelectMetadata();
}
/**
@@ -238,283 +176,6 @@ public class ObjectSelect<T> extends FluentSelect<T>
implements ParameterizedQue
return and(ExpressionFactory.exp(expressionString, parameters));
}
- /**
- * AND's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ObjectSelect<T> and(Expression... expressions) {
- if (expressions == null || expressions.length == 0) {
- return this;
- }
-
- return and(Arrays.asList(expressions));
- }
-
- /**
- * AND's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ObjectSelect<T> and(Collection<Expression> expressions) {
-
- if (expressions == null || expressions.isEmpty()) {
- return this;
- }
-
- Collection<Expression> all;
- Expression activeExpression = getActiveExpression();
-
- if(activeExpression != null) {
- all = new ArrayList<>(expressions.size() + 1);
- all.add(activeExpression);
- all.addAll(expressions);
- } else {
- all = expressions;
- }
-
- setActiveExpression(ExpressionFactory.and(all));
- return this;
- }
-
- /**
- * OR's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ObjectSelect<T> or(Expression... expressions) {
- if (expressions == null || expressions.length == 0) {
- return this;
- }
-
- return or(Arrays.asList(expressions));
- }
-
- /**
- * OR's provided expressions to the existing WHERE clause expression.
- *
- * @return this object
- */
- public ObjectSelect<T> or(Collection<Expression> expressions) {
- if (expressions == null || expressions.isEmpty()) {
- return this;
- }
-
- Collection<Expression> all;
- Expression activeExpression = getActiveExpression();
-
- if(activeExpression != null) {
- all = new ArrayList<>(expressions.size() + 1);
- all.add(activeExpression);
- all.addAll(expressions);
- } else {
- all = expressions;
- }
-
- setActiveExpression(ExpressionFactory.or(all));
- return this;
- }
-
- /**
- * Add an ascending ordering on the given property. If there is already an
ordering
- * on this query then add this ordering with a lower priority.
- *
- * @param property the property to sort on
- * @return this object
- */
- public ObjectSelect<T> orderBy(String property) {
- return orderBy(new Ordering(property));
- }
-
- /**
- * Add an ordering on the given property. If there is already an ordering
- * on this query then add this ordering with a lower priority.
- *
- * @param property the property to sort on
- * @param sortOrder the direction of the ordering
- * @return this object
- */
- public ObjectSelect<T> orderBy(String property, SortOrder sortOrder) {
- return orderBy(new Ordering(property, sortOrder));
- }
-
- /**
- * Add one or more orderings to this query.
- *
- * @return this object
- */
- public ObjectSelect<T> orderBy(Ordering... orderings) {
-
- if (orderings == null) {
- return this;
- }
-
- if (this.orderings == null) {
- this.orderings = new ArrayList<>(orderings.length);
- }
-
- Collections.addAll(this.orderings, orderings);
-
- return this;
- }
-
- /**
- * Adds a list of orderings to this query.
- *
- * @return this object
- */
- public ObjectSelect<T> orderBy(Collection<Ordering> orderings) {
-
- if (orderings == null) {
- return this;
- }
-
- if (this.orderings == null) {
- this.orderings = new ArrayList<>(orderings.size());
- }
-
- this.orderings.addAll(orderings);
-
- return this;
- }
-
- /**
- * Merges prefetch into the query prefetch tree.
- *
- * @return this object
- */
- public ObjectSelect<T> prefetch(PrefetchTreeNode prefetch) {
- metaData.mergePrefetch(prefetch);
- return this;
- }
-
- /**
- * Merges a prefetch path with specified semantics into the query prefetch
- * tree.
- *
- * @return this object
- */
- public ObjectSelect<T> prefetch(String path, int semantics) {
- if (path == null) {
- return this;
- }
- metaData.addPrefetch(path, semantics);
- return this;
- }
-
- /**
- * Resets query fetch limit - a parameter that defines max number of
objects
- * that should be ever be fetched from the database.
- */
- public ObjectSelect<T> limit(int fetchLimit) {
- this.metaData.setFetchLimit(fetchLimit);
- return this;
- }
-
- /**
- * Resets query fetch offset - a parameter that defines how many objects
- * should be skipped when reading data from the database.
- */
- public ObjectSelect<T> offset(int fetchOffset) {
- this.metaData.setFetchOffset(fetchOffset);
- return this;
- }
-
- /**
- * Resets query page size. A non-negative page size enables query result
- * pagination that saves memory and processing time for large lists if only
- * parts of the result are ever going to be accessed.
- */
- public ObjectSelect<T> pageSize(int pageSize) {
- this.metaData.setPageSize(pageSize);
- return this;
- }
-
- /**
- * Sets fetch size of the PreparedStatement generated for this query. Only
- * non-negative values would change the default size.
- *
- * @see Statement#setFetchSize(int)
- */
- public ObjectSelect<T> statementFetchSize(int size) {
- this.metaData.setStatementFetchSize(size);
- return this;
- }
-
- /**
- * Sets query timeout for PreparedStatement generated for this query.
- *
- * @see Statement#setQueryTimeout(int)
- * @since 4.2
- */
- public ObjectSelect<T> queryTimeout(int timeout) {
- this.metaData.setQueryTimeout(timeout);
- return this;
- }
-
- public ObjectSelect<T> cacheStrategy(QueryCacheStrategy strategy) {
- setCacheStrategy(strategy);
- setCacheGroup(null);
- return this;
- }
-
- public ObjectSelect<T> cacheStrategy(QueryCacheStrategy strategy, String
cacheGroup) {
- return cacheStrategy(strategy).cacheGroup(cacheGroup);
- }
-
- public ObjectSelect<T> cacheGroup(String cacheGroup) {
- setCacheGroup(cacheGroup);
- return this;
- }
-
- /**
- * Instructs Cayenne to look for query results in the "local" cache when
- * running the query. This is a short-hand notation for:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup);
- * </pre>
- */
- public ObjectSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
- * </pre>
- */
- public ObjectSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup);
- * </pre>
- */
- public ObjectSelect<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:
- * <p>
- * <pre>
- * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
- * </pre>
- */
- public ObjectSelect<T> sharedCache() {
- return cacheStrategy(QueryCacheStrategy.SHARED_CACHE);
- }
-
/**
* Forces query to fetch DataRows. This automatically changes whatever
* result type was set previously to "DataRow".
@@ -666,11 +327,6 @@ public class ObjectSelect<T> extends FluentSelect<T>
implements ParameterizedQue
return context.selectFirst(limit(1));
}
- @Override
- public boolean isFetchingDataRows() {
- return metaData.isFetchingDataRows();
- }
-
@Override
public QueryMetadata getMetaData(EntityResolver resolver) {
Object root = resolveRoot(resolver);
@@ -679,7 +335,7 @@ public class ObjectSelect<T> extends FluentSelect<T>
implements ParameterizedQue
}
@Override
- protected BaseQueryMetadata getBaseMetaData() {
+ protected ObjectSelectMetadata getBaseMetaData() {
return metaData;
}
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelectMetadata.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelectMetadata.java
index 164a7afb8..451480ea7 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelectMetadata.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelectMetadata.java
@@ -60,7 +60,7 @@ class ObjectSelectMetadata extends BaseQueryMetadata {
return false;
}
- protected String makeCacheKey(FluentSelect<?> query, EntityResolver
resolver) {
+ protected String makeCacheKey(FluentSelect<?, ?> query, EntityResolver
resolver) {
// create a unique key based on entity or columns, qualifier,
ordering, fetch offset and limit
@@ -128,27 +128,27 @@ class ObjectSelectMetadata extends BaseQueryMetadata {
return key.toString();
}
- protected void resolveAutoAliases(FluentSelect<?> query) {
+ protected void resolveAutoAliases(FluentSelect<?, ?> query) {
resolveQualifierAliases(query);
resolveOrderingAliases(query);
resolveHavingQualifierAliases(query);
}
- protected void resolveQualifierAliases(FluentSelect<?> query) {
+ protected void resolveQualifierAliases(FluentSelect<?, ?> query) {
Expression qualifier = query.getWhere();
if (qualifier != null) {
resolveAutoAliases(qualifier);
}
}
- protected void resolveHavingQualifierAliases(FluentSelect<?> query) {
+ protected void resolveHavingQualifierAliases(FluentSelect<?, ?> query) {
Expression havingQualifier = query.getHaving();
if(havingQualifier != null) {
resolveAutoAliases(havingQualifier);
}
}
- protected void resolveOrderingAliases(FluentSelect<?> query) {
+ protected void resolveOrderingAliases(FluentSelect<?, ?> query) {
Collection<Ordering> orderings = query.getOrderings();
if(orderings != null) {
for(Ordering ordering : orderings) {
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLActionVisitor.java
b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLActionVisitor.java
index 02c586b13..e2f423f98 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLActionVisitor.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLActionVisitor.java
@@ -41,7 +41,7 @@ public interface SQLActionVisitor {
* Creates an action to execute a FluentSelect.
* @since 4.2
*/
- <T> SQLAction objectSelectAction(FluentSelect<T> query);
+ <T> SQLAction objectSelectAction(FluentSelect<T,?> query);
/**
* Creates an action to execute a SQLTemplate.
diff --git
a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
index ad336d041..2da4f1a11 100644
---
a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
+++
b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectTest.java
@@ -107,10 +107,9 @@ public class ColumnSelectTest {
assertNull(q.getWhere());
}
- @SuppressWarnings("unchecked")
@Test
public void columns() {
- ColumnSelect q = new ColumnSelect();
+ ColumnSelect<?> q = new ColumnSelect<>();
assertNull(q.getColumns());
q.columns(Artist.ARTIST_NAME, Artist.PAINTING_ARRAY);
assertEquals(Arrays.asList(Artist.ARTIST_NAME, Artist.PAINTING_ARRAY),
q.getColumns());
@@ -124,7 +123,7 @@ public class ColumnSelectTest {
@Test
public void havingExpression() {
- ColumnSelect q = new ColumnSelect();
+ ColumnSelect<?> q = new ColumnSelect<>();
assertNull(q.getHaving());
assertNull(q.getWhere());
@@ -141,7 +140,7 @@ public class ColumnSelectTest {
@Test
public void havingString() {
- ColumnSelect q = new ColumnSelect();
+ ColumnSelect<?> q = new ColumnSelect<>();
assertNull(q.getHaving());
assertNull(q.getWhere());
@@ -158,7 +157,7 @@ public class ColumnSelectTest {
@Test
public void and() {
- ColumnSelect q = new ColumnSelect();
+ ColumnSelect<?> q = new ColumnSelect<>();
assertNull(q.getHaving());
assertNull(q.getWhere());
@@ -177,7 +176,7 @@ public class ColumnSelectTest {
@Test
public void or() {
- ColumnSelect q = new ColumnSelect();
+ ColumnSelect<?> q = new ColumnSelect<>();
assertNull(q.getHaving());
assertNull(q.getWhere());