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/09/13 14:37:21 UTC
(cayenne) 03/03: Query API cleanup - XML property parsing moved to
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 607cb15a7d1584e1f66c49b91704614f7189488b
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Sep 13 10:36:09 2026 -0400
Query API cleanup - XML property parsing moved to
descriptors where it belongs. Descriptors now init queries
---
.../editor/procedure/ProcedureQueryView.java | 8 +-
.../editor/query/ObjectQueryPropertiesPanel.java | 5 +-
.../editor/query/RawQueryPropertiesPanel.java | 5 +-
.../editor/query/SelectPropertiesPanel.java | 43 ++---
.../query/selectquery/SelectQueryMainTab.java | 6 +-
.../query/sqltemplate/SQLTemplateMainTab.java | 9 +-
.../project/validation/BaseQueryValidator.java | 3 +-
.../apache/cayenne/wocompat/EOModelProcessor.java | 13 +-
.../apache/cayenne/map/EJBQLQueryDescriptor.java | 8 +-
.../cayenne/map/ProcedureQueryDescriptor.java | 36 +++-
.../org/apache/cayenne/map/QueryDescriptor.java | 198 ++++++++++++++++++++-
.../apache/cayenne/map/SQLTemplateDescriptor.java | 36 +++-
.../apache/cayenne/map/SelectQueryDescriptor.java | 14 +-
.../apache/cayenne/query/BaseQueryMetadata.java | 50 ------
.../java/org/apache/cayenne/query/EJBQLQuery.java | 9 -
.../org/apache/cayenne/query/FluentSelect.java | 7 -
.../org/apache/cayenne/query/ProcedureQuery.java | 23 ---
.../org/apache/cayenne/query/QueryMetadata.java | 42 +----
.../java/org/apache/cayenne/query/SQLTemplate.java | 20 ---
.../cayenne/map/EJBQLQueryDescriptorTest.java | 25 +++
.../cayenne/map/ProcedureQueryDescriptorTest.java | 54 ++++++
.../apache/cayenne/map/QueryDescriptorTest.java | 107 +++++++++++
.../cayenne/map/SQLTemplateDescriptorTest.java | 40 ++++-
.../cayenne/map/SelectQueryDescriptorTest.java | 51 +++++-
24 files changed, 586 insertions(+), 226 deletions(-)
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureQueryView.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureQueryView.java
index b2ce9e375..d6fb56530 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureQueryView.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureQueryView.java
@@ -42,7 +42,6 @@ import org.apache.cayenne.modeler.toolkit.text.CMUndoableTextField;
import org.apache.cayenne.modeler.project.ProjectComparators;
import org.apache.cayenne.project.extension.info.ObjectInfo;
import org.apache.cayenne.query.CapsStrategy;
-import org.apache.cayenne.query.ProcedureQuery;
import java.util.Objects;
import org.apache.cayenne.validation.ValidationException;
@@ -291,7 +290,7 @@ public class ProcedureQueryView extends ProjectPanel {
labelCase.setRenderer(new LabelCapsRenderer());
labelCase.addActionListener(event -> {
String value = labelCase.getModel().getSelectedItem().toString();
- setQueryProperty(ProcedureQuery.COLUMN_NAME_CAPITALIZATION_PROPERTY, value);
+ setQueryProperty(ProcedureQueryDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY, value);
});
PanelBuilder builder = super.createPanelBuilder();
@@ -313,9 +312,10 @@ public class ProcedureQueryView extends ProjectPanel {
if (query != null && QueryDescriptor.PROCEDURE_QUERY.equals(query.getType())) {
DefaultComboBoxModel<CapsStrategy> labelCaseModel = new DefaultComboBoxModel<>(LABEL_CAPITALIZATION);
- String columnNameCapitalization = query.getProperty(ProcedureQuery.COLUMN_NAME_CAPITALIZATION_PROPERTY);
+ ProcedureQueryDescriptor procedureQuery = (ProcedureQueryDescriptor) query;
+ CapsStrategy columnNameCapitalization = procedureQuery.getColumnNamesCapitalization();
labelCaseModel.setSelectedItem(columnNameCapitalization != null ?
- CapsStrategy.valueOf(columnNameCapitalization) : CapsStrategy.DEFAULT);
+ columnNameCapitalization : CapsStrategy.DEFAULT);
labelCase.setModel(labelCaseModel);
}
}
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/ObjectQueryPropertiesPanel.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/ObjectQueryPropertiesPanel.java
index 3bc6ccd85..407cc3512 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/ObjectQueryPropertiesPanel.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/ObjectQueryPropertiesPanel.java
@@ -27,7 +27,6 @@ import org.apache.cayenne.modeler.toolkit.checkbox.CMCheckBox;
import org.apache.cayenne.modeler.project.ProjectSession;
import org.apache.cayenne.map.QueryDescriptor;
import org.apache.cayenne.modeler.ui.project.editor.EditorForm;
-import org.apache.cayenne.query.QueryMetadata;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
@@ -80,7 +79,7 @@ public class ObjectQueryPropertiesPanel extends SelectPropertiesPanel {
dataRows.addItemListener(e -> {
Boolean b = dataRows.isSelected() ? Boolean.TRUE : Boolean.FALSE;
- setQueryProperty(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY, String.valueOf(b));
+ setQueryProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY, String.valueOf(b));
});
}
@@ -91,6 +90,6 @@ public class ObjectQueryPropertiesPanel extends SelectPropertiesPanel {
public void initFromModel(QueryDescriptor query) {
super.initFromModel(query);
- dataRows.setSelected(Boolean.valueOf(query.getProperty(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY)));
+ dataRows.setSelected(query.isFetchingDataRows());
}
}
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/RawQueryPropertiesPanel.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/RawQueryPropertiesPanel.java
index eee5afd5c..a340cf977 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/RawQueryPropertiesPanel.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/RawQueryPropertiesPanel.java
@@ -40,7 +40,6 @@ import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.apache.cayenne.map.QueryDescriptor;
import org.apache.cayenne.modeler.ui.project.editor.EditorForm;
-import org.apache.cayenne.query.QueryMetadata;
/**
* A panel that supports editing the properties a query not based on ObjEntity, but still
@@ -112,7 +111,7 @@ public abstract class RawQueryPropertiesPanel extends SelectPropertiesPanel {
public void initFromModel(QueryDescriptor query) {
super.initFromModel(query);
- boolean fetchingDO = !Boolean.valueOf(query.getProperties().get(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY));
+ boolean fetchingDO = !query.isFetchingDataRows();
persistentObjects.setSelected(fetchingDO);
// TODO: now we only allow ObjEntities from the current map,
@@ -143,7 +142,7 @@ public abstract class RawQueryPropertiesPanel extends SelectPropertiesPanel {
entities.getModel().setSelectedItem(null);
}
- setQueryProperty(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY,
+ setQueryProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY,
fetchingPersistentObjects ? Boolean.FALSE.toString() : Boolean.TRUE.toString());
}
}
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/SelectPropertiesPanel.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/SelectPropertiesPanel.java
index 2e295a07a..a9f3298ca 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/SelectPropertiesPanel.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/SelectPropertiesPanel.java
@@ -37,7 +37,6 @@ import org.apache.cayenne.modeler.toolkit.text.CMUndoableTextField;
import org.apache.cayenne.modeler.project.ProjectSession;
import org.apache.cayenne.query.QueryCacheStrategy;
import org.apache.cayenne.map.QueryDescriptor;
-import org.apache.cayenne.query.QueryMetadata;
import java.util.Objects;
import org.apache.cayenne.validation.ValidationException;
@@ -104,7 +103,7 @@ public abstract class SelectPropertiesPanel extends ProjectPanel {
protected void initController() {
cacheStrategy.addActionListener(event -> {
QueryCacheStrategy strategy = (QueryCacheStrategy) cacheStrategy.getModel().getSelectedItem();
- setQueryProperty(QueryMetadata.CACHE_STRATEGY_PROPERTY, strategy.name());
+ setQueryProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, strategy.name());
setCacheGroupsEnabled(strategy != QueryCacheStrategy.NO_CACHE);
});
}
@@ -116,35 +115,27 @@ public abstract class SelectPropertiesPanel extends ProjectPanel {
public void initFromModel(QueryDescriptor query) {
DefaultComboBoxModel<QueryCacheStrategy> cacheModel = new DefaultComboBoxModel<>(CACHE_POLICIES);
- String selectedStrategyString = query.getProperty(QueryMetadata.CACHE_STRATEGY_PROPERTY);
-
- QueryCacheStrategy selectedStrategy = selectedStrategyString != null ?
- QueryCacheStrategy.valueOf(selectedStrategyString) : null;
-
- cacheModel.setSelectedItem(selectedStrategy != null ?
- selectedStrategy : QueryCacheStrategy.getDefaultStrategy());
-
+ QueryCacheStrategy selectedStrategy = query.getCacheStrategy();
+ cacheModel.setSelectedItem(selectedStrategy);
cacheStrategy.setModel(cacheModel);
- cacheGroups.setText(query.getProperty(QueryMetadata.CACHE_GROUPS_PROPERTY));
- setCacheGroupsEnabled(selectedStrategy != null && selectedStrategy != QueryCacheStrategy.NO_CACHE);
-
- String fetchOffsetStr = query.getProperty(QueryMetadata.FETCH_OFFSET_PROPERTY);
- String fetchLimitStr = query.getProperty(QueryMetadata.FETCH_LIMIT_PROPERTY);
- String pageSizeStr = query.getProperty(QueryMetadata.PAGE_SIZE_PROPERTY);
+ // showing the raw property rather than QueryDescriptor.getCacheGroup(), so that a legacy comma-separated
+ // list of groups stays visible (and fixable) to the user
+ cacheGroups.setText(query.getProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY));
+ setCacheGroupsEnabled(selectedStrategy != QueryCacheStrategy.NO_CACHE);
- fetchOffset.setText(fetchOffsetStr != null ? fetchOffsetStr : ZERO.toString());
- fetchLimit.setText(fetchLimitStr != null ? fetchLimitStr : ZERO.toString());
- pageSize.setText(pageSizeStr != null ? pageSizeStr : ZERO.toString());
+ fetchOffset.setText(String.valueOf(query.getFetchOffset()));
+ fetchLimit.setText(String.valueOf(query.getFetchLimit()));
+ pageSize.setText(String.valueOf(query.getPageSize()));
}
void setFetchOffset(String string) {
string = string == null ? "" : string.trim();
if (string.length() == 0) {
- setQueryProperty(QueryMetadata.FETCH_OFFSET_PROPERTY, ZERO.toString());
+ setQueryProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, ZERO.toString());
} else {
if (isNumeric(string)) {
- setQueryProperty(QueryMetadata.FETCH_OFFSET_PROPERTY, string);
+ setQueryProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, string);
} else {
throw new ValidationException("Fetch offset must be an integer: %s", string);
}
@@ -154,10 +145,10 @@ public abstract class SelectPropertiesPanel extends ProjectPanel {
void setFetchLimit(String string) {
string = (string == null) ? "" : string.trim();
if (string.length() == 0) {
- setQueryProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, ZERO.toString());
+ setQueryProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, ZERO.toString());
} else {
if (isNumeric(string)) {
- setQueryProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, string);
+ setQueryProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, string);
} else {
throw new ValidationException("Fetch limit must be an integer: %s", string);
}
@@ -167,10 +158,10 @@ public abstract class SelectPropertiesPanel extends ProjectPanel {
void setPageSize(String string) {
string = (string == null) ? "" : string.trim();
if (string.length() == 0) {
- setQueryProperty(QueryMetadata.PAGE_SIZE_PROPERTY, ZERO.toString());
+ setQueryProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, ZERO.toString());
} else {
if (isNumeric(string)) {
- setQueryProperty(QueryMetadata.PAGE_SIZE_PROPERTY, string);
+ setQueryProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, string);
} else {
throw new ValidationException("Page size must be an integer: %s", string);
}
@@ -179,7 +170,7 @@ public abstract class SelectPropertiesPanel extends ProjectPanel {
void setCacheGroups(String string) {
string = (string == null) ? "" : string.trim();
- setQueryProperty(QueryMetadata.CACHE_GROUPS_PROPERTY, string);
+ setQueryProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, string);
}
QueryDescriptor getQuery() {
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryMainTab.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryMainTab.java
index 2dec4af64..897440cb1 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryMainTab.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/selectquery/SelectQueryMainTab.java
@@ -124,8 +124,8 @@ public class SelectQueryMainTab extends BaseQueryMainTab {
private void initController() {
distinct.addItemListener(e -> {
QueryDescriptor query = getQuery();
- if (query != null) {
- query.setProperty(SelectQueryDescriptor.DISTINCT_PROPERTY, Boolean.toString(distinct.isSelected()));
+ if (query instanceof SelectQueryDescriptor selectQuery) {
+ selectQuery.setDistinct(distinct.isSelected());
session.fireQueryEvent(QueryEvent.ofChange(this, query));
}
});
@@ -146,7 +146,7 @@ public class SelectQueryMainTab extends BaseQueryMainTab {
SelectQueryDescriptor query = (SelectQueryDescriptor) descriptor;
name.setText(query.getName());
- distinct.setSelected(Boolean.parseBoolean(query.getProperties().get(SelectQueryDescriptor.DISTINCT_PROPERTY)));
+ distinct.setSelected(query.isDistinct());
qualifier.setText(query.getQualifier() != null ? query
.getQualifier()
.toString() : null);
diff --git a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplateMainTab.java b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplateMainTab.java
index db594fc44..23df502af 100644
--- a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplateMainTab.java
+++ b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/query/sqltemplate/SQLTemplateMainTab.java
@@ -32,13 +32,13 @@ import org.apache.cayenne.modeler.event.model.QueryEvent;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.QueryDescriptor;
+import org.apache.cayenne.map.SQLTemplateDescriptor;
import org.apache.cayenne.modeler.toolkit.combobox.CMUndoableComboBox;
import org.apache.cayenne.modeler.toolkit.text.CMUndoableTextField;
import org.apache.cayenne.modeler.project.ProjectSession;
import org.apache.cayenne.modeler.project.ProjectComparators;
import org.apache.cayenne.project.extension.info.ObjectInfo;
import org.apache.cayenne.query.CapsStrategy;
-import org.apache.cayenne.query.SQLTemplate;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
@@ -223,7 +223,7 @@ public class SQLTemplateMainTab extends BaseQueryMainTab {
labelCase.addActionListener(event -> {
CapsStrategy value = (CapsStrategy) labelCase.getModel().getSelectedItem();
- setQueryProperty(SQLTemplate.COLUMN_NAME_CAPITALIZATION_PROPERTY, value.name());
+ setQueryProperty(SQLTemplateDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY, value.name());
});
PanelBuilder builder = super.createPanelBuilder();
@@ -246,10 +246,9 @@ public class SQLTemplateMainTab extends BaseQueryMainTab {
if (query != null && QueryDescriptor.SQL_TEMPLATE.equals(query.getType())) {
DefaultComboBoxModel<CapsStrategy> labelCaseModel = new DefaultComboBoxModel<>(LABEL_CAPITALIZATION);
- String columnNameCapitalization = query.getProperty(SQLTemplate.COLUMN_NAME_CAPITALIZATION_PROPERTY);
-
+ CapsStrategy columnNameCapitalization = ((SQLTemplateDescriptor) query).getColumnNamesCapitalization();
labelCaseModel.setSelectedItem(columnNameCapitalization != null
- ? CapsStrategy.valueOf(columnNameCapitalization)
+ ? columnNameCapitalization
: CapsStrategy.DEFAULT);
labelCase.setModel(labelCaseModel);
}
diff --git a/cayenne-project/src/main/java/org/apache/cayenne/project/validation/BaseQueryValidator.java b/cayenne-project/src/main/java/org/apache/cayenne/project/validation/BaseQueryValidator.java
index 3c21ba8d8..1a7be0b2b 100644
--- a/cayenne-project/src/main/java/org/apache/cayenne/project/validation/BaseQueryValidator.java
+++ b/cayenne-project/src/main/java/org/apache/cayenne/project/validation/BaseQueryValidator.java
@@ -21,7 +21,6 @@ package org.apache.cayenne.project.validation;
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.QueryDescriptor;
-import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.validation.ValidationResult;
@@ -94,7 +93,7 @@ abstract class BaseQueryValidator<T extends QueryDescriptor> extends Configurati
}
void checkForMultiCacheGroup(T query, ValidationResult validationResult) {
- String cacheGroup = query.getProperty(QueryMetadata.CACHE_GROUPS_PROPERTY);
+ String cacheGroup = query.getProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY);
if (cacheGroup != null && cacheGroup.contains(",")) {
addFailure(validationResult, query, "Invalid cache group '%s', multiple groups are deprecated",
cacheGroup);
diff --git a/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index 079ccf07b..3b158a9f7 100644
--- a/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -33,7 +33,6 @@ import org.apache.cayenne.map.SQLTemplateDescriptor;
import org.apache.cayenne.map.SelectQueryDescriptor;
import org.apache.cayenne.query.Ordering;
import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.query.SortOrder;
import org.apache.cayenne.wocompat.parser.Parser;
import org.slf4j.Logger;
@@ -238,10 +237,9 @@ public class EOModelProcessor {
if (fetchLimit != null) {
try {
if (fetchLimit instanceof Number n) {
- descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY,
- String.valueOf(n.intValue()));
+ descriptor.setFetchLimit(n.intValue());
} else if (isNumeric(fetchLimit.toString())) {
- descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, fetchLimit.toString());
+ descriptor.setFetchLimit(Integer.parseInt(fetchLimit.toString()));
}
} catch (NumberFormatException nfex) {
// ignoring...
@@ -279,7 +277,7 @@ public class EOModelProcessor {
// in the
// modeler...
if (plistMap.containsKey("rawRowKeyPaths")) {
- descriptor.setProperty(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY, String.valueOf(true));
+ descriptor.setFetchingDataRows(true);
}
return descriptor;
@@ -293,10 +291,9 @@ public class EOModelProcessor {
if (fetchLimit != null) {
try {
if (fetchLimit instanceof Number n) {
- descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY,
- String.valueOf(n.intValue()));
+ descriptor.setFetchLimit(n.intValue());
} else if (isNumeric(fetchLimit.toString())) {
- descriptor.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, fetchLimit.toString());
+ descriptor.setFetchLimit(Integer.parseInt(fetchLimit.toString()));
}
} catch (NumberFormatException nfex) {
// ignoring...
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/EJBQLQueryDescriptor.java b/cayenne/src/main/java/org/apache/cayenne/map/EJBQLQueryDescriptor.java
index 367495576..e769a4ea8 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/EJBQLQueryDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/EJBQLQueryDescriptor.java
@@ -52,7 +52,13 @@ public class EJBQLQueryDescriptor extends QueryDescriptor {
@Override
public EJBQLQuery<?> buildQuery() {
EJBQLQuery<?> ejbqlQuery = new EJBQLQuery<>(this.getEjbql());
- ejbqlQuery.initWithProperties(this.getProperties());
+ ejbqlQuery.setFetchLimit(getFetchLimit());
+ ejbqlQuery.setFetchOffset(getFetchOffset());
+ ejbqlQuery.setPageSize(getPageSize());
+ ejbqlQuery.setStatementFetchSize(getStatementFetchSize());
+ ejbqlQuery.setFetchingDataRows(isFetchingDataRows());
+ ejbqlQuery.setCacheStrategy(getCacheStrategy());
+ ejbqlQuery.setCacheGroup(getCacheGroup());
return ejbqlQuery;
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/ProcedureQueryDescriptor.java b/cayenne/src/main/java/org/apache/cayenne/map/ProcedureQueryDescriptor.java
index d4d784a6b..acac93e63 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/ProcedureQueryDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/ProcedureQueryDescriptor.java
@@ -19,6 +19,7 @@
package org.apache.cayenne.map;
import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.query.CapsStrategy;
import org.apache.cayenne.query.ProcedureQuery;
import org.apache.cayenne.util.XMLEncoder;
@@ -29,6 +30,14 @@ import java.util.Map;
*/
public class ProcedureQueryDescriptor extends QueryDescriptor {
+ /**
+ * Name of the descriptor property holding the {@link #getColumnNamesCapitalization() column name
+ * capitalization} of the query.
+ *
+ * @since 5.0
+ */
+ public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.ProcedureQuery.columnNameCapitalization";
+
protected String resultEntityName;
public ProcedureQueryDescriptor() {
@@ -49,6 +58,24 @@ public class ProcedureQueryDescriptor extends QueryDescriptor {
this.resultEntityName = resultEntityName;
}
+ /**
+ * Returns the capitalization strategy applied to the column names of the query result, or null if none is set.
+ *
+ * @since 5.0
+ */
+ public CapsStrategy getColumnNamesCapitalization() {
+ String value = getProperty(COLUMN_NAME_CAPITALIZATION_PROPERTY);
+ return value != null ? CapsStrategy.valueOf(value.toUpperCase()) : null;
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setColumnNamesCapitalization(CapsStrategy columnNamesCapitalization) {
+ setProperty(COLUMN_NAME_CAPITALIZATION_PROPERTY,
+ columnNamesCapitalization != null ? columnNamesCapitalization.name() : null);
+ }
+
@Override
public ProcedureQuery<?> buildQuery() {
ProcedureQuery<?> procedureQuery = new ProcedureQuery<>();
@@ -58,7 +85,14 @@ public class ProcedureQueryDescriptor extends QueryDescriptor {
}
procedureQuery.setResultEntityName(this.getResultEntityName());
- procedureQuery.initWithProperties(this.getProperties());
+ procedureQuery.setFetchLimit(getFetchLimit());
+ procedureQuery.setFetchOffset(getFetchOffset());
+ procedureQuery.setPageSize(getPageSize());
+ procedureQuery.setStatementFetchSize(getStatementFetchSize());
+ procedureQuery.setFetchingDataRows(isFetchingDataRows());
+ procedureQuery.setCacheStrategy(getCacheStrategy());
+ procedureQuery.setCacheGroup(getCacheGroup());
+ procedureQuery.setColumnNamesCapitalization(getColumnNamesCapitalization());
return procedureQuery;
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/QueryDescriptor.java b/cayenne/src/main/java/org/apache/cayenne/map/QueryDescriptor.java
index 63343d272..e58bb8ee5 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/QueryDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/QueryDescriptor.java
@@ -22,6 +22,8 @@ import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.configuration.ConfigurationNode;
import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
import org.apache.cayenne.query.Query;
+import org.apache.cayenne.query.QueryCacheStrategy;
+import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.util.XMLEncoder;
import org.apache.cayenne.util.XMLSerializable;
@@ -65,6 +67,56 @@ public class QueryDescriptor implements ConfigurationNode, XMLSerializable {
*/
public static final String JAVA_CLASS_ROOT = "java-class";
+ /**
+ * Name of the descriptor property holding the query {@link #getFetchLimit() fetch limit}.
+ *
+ * @since 5.0
+ */
+ public static final String FETCH_LIMIT_PROPERTY = "cayenne.GenericSelectQuery.fetchLimit";
+
+ /**
+ * Name of the descriptor property holding the query {@link #getFetchOffset() fetch offset}.
+ *
+ * @since 5.0
+ */
+ public static final String FETCH_OFFSET_PROPERTY = "cayenne.GenericSelectQuery.fetchOffset";
+
+ /**
+ * Name of the descriptor property holding the query {@link #getPageSize() page size}.
+ *
+ * @since 5.0
+ */
+ public static final String PAGE_SIZE_PROPERTY = "cayenne.GenericSelectQuery.pageSize";
+
+ /**
+ * Name of the descriptor property holding the query {@link #isFetchingDataRows() data rows} flag.
+ *
+ * @since 5.0
+ */
+ public static final String FETCHING_DATA_ROWS_PROPERTY = "cayenne.GenericSelectQuery.fetchingDataRows";
+
+ /**
+ * Name of the descriptor property holding the query {@link #getCacheStrategy() cache strategy}.
+ *
+ * @since 5.0
+ */
+ public static final String CACHE_STRATEGY_PROPERTY = "cayenne.GenericSelectQuery.cacheStrategy";
+
+ /**
+ * Name of the descriptor property holding the query {@link #getCacheGroup() cache group}. The plural name is
+ * historical: older projects could store a comma-separated list of groups under this property.
+ *
+ * @since 5.0
+ */
+ public static final String CACHE_GROUPS_PROPERTY = "cayenne.GenericSelectQuery.cacheGroups";
+
+ /**
+ * Name of the descriptor property holding the query {@link #getStatementFetchSize() statement fetch size}.
+ *
+ * @since 5.0
+ */
+ public static final String STATEMENT_FETCH_SIZE_PROPERTY = "cayenne.GenericSelectQuery.statementFetchSize";
+
/**
* Creates new SelectQuery query descriptor.
*/
@@ -173,7 +225,9 @@ public class QueryDescriptor implements ConfigurationNode, XMLSerializable {
}
/**
- * Returns map of query properties set up for this query.
+ * Returns map of query properties set up for this query. Properties are the raw String values stored in the
+ * project XML. Typed accessors like {@link #getFetchLimit()} or {@link #getCacheStrategy()} interpret the
+ * well-known properties.
*/
public Map<String, String> getProperties() {
return properties;
@@ -194,10 +248,148 @@ public class QueryDescriptor implements ConfigurationNode, XMLSerializable {
}
/**
- * Sets single query property.
+ * Sets single query property. A null value removes the property.
*/
public void setProperty(String name, String value) {
- this.properties.put(name, value);
+ if (value == null) {
+ this.properties.remove(name);
+ } else {
+ this.properties.put(name, value);
+ }
+ }
+
+ /**
+ * Returns the fetch limit of the query, or {@link QueryMetadata#FETCH_LIMIT_DEFAULT} if it is not set.
+ *
+ * @since 5.0
+ */
+ public int getFetchLimit() {
+ return intProperty(FETCH_LIMIT_PROPERTY, QueryMetadata.FETCH_LIMIT_DEFAULT);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setFetchLimit(int fetchLimit) {
+ setProperty(FETCH_LIMIT_PROPERTY, String.valueOf(fetchLimit));
+ }
+
+ /**
+ * Returns the fetch offset of the query, or {@link QueryMetadata#FETCH_OFFSET_DEFAULT} if it is not set.
+ *
+ * @since 5.0
+ */
+ public int getFetchOffset() {
+ return intProperty(FETCH_OFFSET_PROPERTY, QueryMetadata.FETCH_OFFSET_DEFAULT);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setFetchOffset(int fetchOffset) {
+ setProperty(FETCH_OFFSET_PROPERTY, String.valueOf(fetchOffset));
+ }
+
+ /**
+ * Returns the page size of the query, or {@link QueryMetadata#PAGE_SIZE_DEFAULT} if it is not set.
+ *
+ * @since 5.0
+ */
+ public int getPageSize() {
+ return intProperty(PAGE_SIZE_PROPERTY, QueryMetadata.PAGE_SIZE_DEFAULT);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setPageSize(int pageSize) {
+ setProperty(PAGE_SIZE_PROPERTY, String.valueOf(pageSize));
+ }
+
+ /**
+ * Returns the JDBC statement fetch size of the query, or {@link QueryMetadata#STATEMENT_FETCH_SIZE_DEFAULT} if
+ * it is not set.
+ *
+ * @since 5.0
+ */
+ public int getStatementFetchSize() {
+ return intProperty(STATEMENT_FETCH_SIZE_PROPERTY, QueryMetadata.STATEMENT_FETCH_SIZE_DEFAULT);
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setStatementFetchSize(int statementFetchSize) {
+ setProperty(STATEMENT_FETCH_SIZE_PROPERTY, String.valueOf(statementFetchSize));
+ }
+
+ /**
+ * Returns whether the query fetches DataRows instead of Persistent objects. Defaults to
+ * {@link QueryMetadata#FETCHING_DATA_ROWS_DEFAULT} if the property is not set.
+ *
+ * @since 5.0
+ */
+ public boolean isFetchingDataRows() {
+ String value = getProperty(FETCHING_DATA_ROWS_PROPERTY);
+ return value != null ? Boolean.parseBoolean(value) : QueryMetadata.FETCHING_DATA_ROWS_DEFAULT;
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setFetchingDataRows(boolean fetchingDataRows) {
+ setProperty(FETCHING_DATA_ROWS_PROPERTY, String.valueOf(fetchingDataRows));
+ }
+
+ /**
+ * Returns the cache strategy of the query. Defaults to {@link QueryCacheStrategy#getDefaultStrategy()} if the
+ * property is not set or holds an unknown value.
+ *
+ * @since 5.0
+ */
+ public QueryCacheStrategy getCacheStrategy() {
+ String value = getProperty(CACHE_STRATEGY_PROPERTY);
+ return value != null ? QueryCacheStrategy.safeValueOf(value) : QueryCacheStrategy.getDefaultStrategy();
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setCacheStrategy(QueryCacheStrategy cacheStrategy) {
+ setProperty(CACHE_STRATEGY_PROPERTY, cacheStrategy != null ? cacheStrategy.name() : null);
+ }
+
+ /**
+ * Returns the cache group of the query, or null if none is set. If the underlying property holds a legacy
+ * comma-separated list of groups, only the first non-empty group is returned.
+ *
+ * @since 5.0
+ */
+ public String getCacheGroup() {
+ String value = getProperty(CACHE_GROUPS_PROPERTY);
+ if (value == null) {
+ return null;
+ }
+
+ for (String group : value.split(",")) {
+ if (!group.isEmpty()) {
+ return group;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setCacheGroup(String cacheGroup) {
+ setProperty(CACHE_GROUPS_PROPERTY, cacheGroup);
+ }
+
+ private int intProperty(String name, int defaultValue) {
+ String value = getProperty(name);
+ return value != null ? Integer.parseInt(value) : defaultValue;
}
/**
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/SQLTemplateDescriptor.java b/cayenne/src/main/java/org/apache/cayenne/map/SQLTemplateDescriptor.java
index d6be245b8..68a49e8ec 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/SQLTemplateDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/SQLTemplateDescriptor.java
@@ -19,6 +19,7 @@
package org.apache.cayenne.map;
import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
+import org.apache.cayenne.query.CapsStrategy;
import org.apache.cayenne.query.PrefetchTreeNode;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.util.XMLEncoder;
@@ -32,6 +33,14 @@ import java.util.TreeSet;
*/
public class SQLTemplateDescriptor extends QueryDescriptor {
+ /**
+ * Name of the descriptor property holding the {@link #getColumnNamesCapitalization() column name
+ * capitalization} of the query.
+ *
+ * @since 5.0
+ */
+ public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.SQLTemplate.columnNameCapitalization";
+
protected String sql;
protected Map<String, Integer> prefetchesMap = new HashMap<>();
@@ -69,6 +78,24 @@ public class SQLTemplateDescriptor extends QueryDescriptor {
this.adapterSql = adapterSql;
}
+ /**
+ * Returns the capitalization strategy applied to the column names of the query result, or null if none is set.
+ *
+ * @since 5.0
+ */
+ public CapsStrategy getColumnNamesCapitalization() {
+ String value = getProperty(COLUMN_NAME_CAPITALIZATION_PROPERTY);
+ return value != null ? CapsStrategy.valueOf(value.toUpperCase()) : null;
+ }
+
+ /**
+ * @since 5.0
+ */
+ public void setColumnNamesCapitalization(CapsStrategy columnNamesCapitalization) {
+ setProperty(COLUMN_NAME_CAPITALIZATION_PROPERTY,
+ columnNamesCapitalization != null ? columnNamesCapitalization.name() : null);
+ }
+
/**
* Returns map of prefetch paths with semantics for this query.
* @since 4.1
@@ -113,7 +140,14 @@ public class SQLTemplateDescriptor extends QueryDescriptor {
}
}
- template.initWithProperties(this.getProperties());
+ template.setFetchLimit(getFetchLimit());
+ template.setFetchOffset(getFetchOffset());
+ template.setPageSize(getPageSize());
+ template.setStatementFetchSize(getStatementFetchSize());
+ template.setFetchingDataRows(isFetchingDataRows());
+ template.setCacheStrategy(getCacheStrategy());
+ template.setCacheGroup(getCacheGroup());
+ template.setColumnNamesCapitalization(getColumnNamesCapitalization());
// init SQL
template.setDefaultTemplate(this.getSql());
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 5bc2ffb02..a4d623e61 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
@@ -171,10 +171,20 @@ public class SelectQueryDescriptor extends QueryDescriptor {
prefetchesMap.forEach(query::prefetch);
}
- query.initWithProperties(this.getProperties());
- if(this.isDistinct()) {
+ query.limit(getFetchLimit())
+ .offset(getFetchOffset())
+ .pageSize(getPageSize())
+ .statementFetchSize(getStatementFetchSize())
+ .cacheStrategy(getCacheStrategy(), getCacheGroup());
+
+ if (isFetchingDataRows()) {
+ query.fetchDataRows();
+ }
+
+ if (isDistinct()) {
query.distinct();
}
+
return query;
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/BaseQueryMetadata.java b/cayenne/src/main/java/org/apache/cayenne/query/BaseQueryMetadata.java
index 34006521b..4d5121623 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/BaseQueryMetadata.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/BaseQueryMetadata.java
@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.map.DataMap;
@@ -141,55 +140,6 @@ class BaseQueryMetadata implements QueryMetadata {
return false;
}
- void initWithProperties(Map<String, ?> properties) {
- // must init defaults even if properties are empty
- if (properties == null) {
- properties = Collections.emptyMap();
- }
-
- Object fetchOffset = properties.get(QueryMetadata.FETCH_OFFSET_PROPERTY);
- Object fetchLimit = properties.get(QueryMetadata.FETCH_LIMIT_PROPERTY);
- Object pageSize = properties.get(QueryMetadata.PAGE_SIZE_PROPERTY);
- Object statementFetchSize = properties.get(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY);
- Object fetchingDataRows = properties.get(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY);
-
- Object cacheStrategy = properties.get(QueryMetadata.CACHE_STRATEGY_PROPERTY);
-
- Object cacheGroups = properties.get(QueryMetadata.CACHE_GROUPS_PROPERTY);
-
- // init ivars from properties
- this.fetchOffset = (fetchOffset != null) ? Integer.parseInt(fetchOffset.toString())
- : QueryMetadata.FETCH_OFFSET_DEFAULT;
-
- this.fetchLimit = (fetchLimit != null) ? Integer.parseInt(fetchLimit.toString())
- : QueryMetadata.FETCH_LIMIT_DEFAULT;
-
- this.pageSize = (pageSize != null) ? Integer.parseInt(pageSize.toString()) : QueryMetadata.PAGE_SIZE_DEFAULT;
-
- this.statementFetchSize = (statementFetchSize != null) ? Integer.parseInt(statementFetchSize.toString())
- : QueryMetadata.STATEMENT_FETCH_SIZE_DEFAULT;
-
- this.fetchingDataRows = (fetchingDataRows != null) ? "true".equalsIgnoreCase(fetchingDataRows.toString())
- : QueryMetadata.FETCHING_DATA_ROWS_DEFAULT;
-
- this.cacheStrategy = (cacheStrategy != null) ? QueryCacheStrategy.safeValueOf(cacheStrategy.toString())
- : QueryCacheStrategy.getDefaultStrategy();
-
- this.cacheGroup = null;
- if(cacheGroups instanceof String) {
- if(((String) cacheGroups).contains(",")) {
- StringTokenizer toks = new StringTokenizer(cacheGroups.toString(), ",");
- if(toks.countTokens() > 0) {
- this.cacheGroup = toks.nextToken();
- }
- } else {
- this.cacheGroup = (String) cacheGroups;
- }
- } else if (cacheGroups instanceof String[]) {
- this.cacheGroup = ((String[]) cacheGroups)[0];
- }
- }
-
/**
* @since 1.2
*/
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 feb72566d..d5fc4a117 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
@@ -53,15 +53,6 @@ public class EJBQLQuery<T> extends CacheableQuery implements Select<T> {
public EJBQLQuery() {
}
- public void initWithProperties(Map<String, ?> properties) {
-
- // must init defaults even if properties are empty
- if (properties == null) {
- properties = Collections.emptyMap();
- }
- metadata.initWithProperties(properties);
- }
-
public QueryMetadata getMetaData(EntityResolver resolver) {
metadata.resolve(resolver, this);
return metadata;
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 7bb590baa..8e4c808e3 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -710,13 +710,6 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> implements S
return distinct;
}
- /**
- * @since 4.2
- */
- public void initWithProperties(Map<String, String> properties) {
- getBaseMetaData().initWithProperties(properties);
- }
-
/**
* Utility method to perform (re)cast this type, doesn't perform any checks, so use with caution.
*
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 4ae59db0c..810deed85 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/ProcedureQuery.java
@@ -59,8 +59,6 @@ import java.util.Map;
*/
public class ProcedureQuery<T> extends CacheableQuery implements Select<T> {
- public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.ProcedureQuery.columnNameCapitalization";
-
protected String resultEntityName;
protected Class<?> resultClass;
protected CapsStrategy columnNamesCapitalization;
@@ -245,27 +243,6 @@ public class ProcedureQuery<T> extends CacheableQuery implements Select<T> {
return context.selectFirst(this);
}
- /**
- * Initializes query parameters using a set of properties.
- *
- * @since 1.1
- */
- public void initWithProperties(Map<String, ?> properties) {
-
- // must init defaults even if properties are empty
- if (properties == null) {
- properties = Collections.emptyMap();
- }
- Object columnNamesCapitalization = properties
- .get(COLUMN_NAME_CAPITALIZATION_PROPERTY);
- this.columnNamesCapitalization = (columnNamesCapitalization != null)
- ? CapsStrategy
- .valueOf(columnNamesCapitalization.toString().toUpperCase())
- : null;
-
- metaData.initWithProperties(properties);
- }
-
@Override
protected BaseQueryMetadata getBaseMetaData() {
return metaData;
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadata.java b/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadata.java
index 262c24b85..2f861f37d 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadata.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadata.java
@@ -36,26 +36,12 @@ import org.apache.cayenne.reflect.ClassDescriptor;
*/
public interface QueryMetadata {
- /**
- * Defines the name of the property for the query {@link #getFetchLimit() fetch limit}
- * .
- */
- String FETCH_LIMIT_PROPERTY = "cayenne.GenericSelectQuery.fetchLimit";
-
/**
* Defines default query fetch limit, which is zero, meaning that all matching rows
* should be fetched.
*/
int FETCH_LIMIT_DEFAULT = 0;
- /**
- * Defines the name of the property for the query {@link #getFetchOffset() fetch
- * offset}.
- *
- * @since 3.0
- */
- String FETCH_OFFSET_PROPERTY = "cayenne.GenericSelectQuery.fetchOffset";
-
/**
* Defines default query fetch start index, which is 0, meaning that matching rows
* selected starting from the first.
@@ -66,41 +52,15 @@ public interface QueryMetadata {
int QUERY_TIMEOUT_DEFAULT = -1;
- /**
- * Defines the name of the property for the query {@link #getPageSize() page size}.
- */
- String PAGE_SIZE_PROPERTY = "cayenne.GenericSelectQuery.pageSize";
-
/**
* Defines default query page size, which is zero for no pagination.
*/
int PAGE_SIZE_DEFAULT = 0;
- String FETCHING_DATA_ROWS_PROPERTY = "cayenne.GenericSelectQuery.fetchingDataRows";
-
boolean FETCHING_DATA_ROWS_DEFAULT = false;
/**
- * @since 3.0
- */
- String CACHE_STRATEGY_PROPERTY = "cayenne.GenericSelectQuery.cacheStrategy";
-
- /**
- * @since 3.0
- */
- String CACHE_GROUPS_PROPERTY = "cayenne.GenericSelectQuery.cacheGroups";
-
- /**
- * Defines the name of the property for the query {@link #getStatementFetchSize() fetch
- * size}.
- *
- * @since 3.0
- */
- String STATEMENT_FETCH_SIZE_PROPERTY = "cayenne.GenericSelectQuery.statementFetchSize";
-
- /**
- * Defines default query fetch start index, which is 0, meaning that matching rows
- * selected starting from the first.
+ * Defines default statement fetch size, which is 0, meaning that the JDBC driver default is used.
*
* @since 3.0
*/
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 80a50c2f4..2ae095919 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SQLTemplate.java
@@ -72,8 +72,6 @@ import java.util.stream.Stream;
*/
public class SQLTemplate<T> extends CacheableQuery implements Select<T> {
- public static final String COLUMN_NAME_CAPITALIZATION_PROPERTY = "cayenne.SQLTemplate.columnNameCapitalization";
-
private static final Function<Map<String, ?>, Map<String, ?>> nullMapTransformer = input ->
(input != null) ? input : Collections.emptyMap();
@@ -245,24 +243,6 @@ public class SQLTemplate<T> extends CacheableQuery implements Select<T> {
return context.selectFirst(this);
}
- /**
- * Initializes query parameters using a set of properties.
- *
- * @since 1.1
- */
- public void initWithProperties(Map<String, ?> properties) {
- // must init defaults even if properties are empty
- metaData.initWithProperties(properties);
-
- if (properties == null) {
- properties = Collections.emptyMap();
- }
-
- Object columnNamesCapitalization = properties.get(COLUMN_NAME_CAPITALIZATION_PROPERTY);
- this.columnNamesCapitalization = (columnNamesCapitalization != null) ? CapsStrategy
- .valueOf(columnNamesCapitalization.toString().toUpperCase()) : null;
- }
-
/**
* Returns an iterator over parameter sets. Each element returned from the
* iterator is a java.util.Map.
diff --git a/cayenne/src/test/java/org/apache/cayenne/map/EJBQLQueryDescriptorTest.java b/cayenne/src/test/java/org/apache/cayenne/map/EJBQLQueryDescriptorTest.java
index a878d02fe..c4f465673 100644
--- a/cayenne/src/test/java/org/apache/cayenne/map/EJBQLQueryDescriptorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/map/EJBQLQueryDescriptorTest.java
@@ -22,9 +22,11 @@ package org.apache.cayenne.map;
import java.util.Map;
import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.query.QueryCacheStrategy;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class EJBQLQueryDescriptorTest {
@@ -37,4 +39,27 @@ public class EJBQLQueryDescriptorTest {
assertEquals(Map.of("name", "artist1"), query.getNamedParameters());
}
+
+ @Test
+ public void getQueryProperties() {
+ EJBQLQueryDescriptor builder = QueryDescriptor.ejbqlQueryDescriptor();
+ builder.setEjbql("select a from Artist a");
+ builder.setProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, "5");
+ builder.setProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, "2");
+ builder.setProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, "10");
+ builder.setProperty(QueryDescriptor.STATEMENT_FETCH_SIZE_PROPERTY, "6");
+ builder.setProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY, "true");
+ builder.setProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, "SHARED_CACHE");
+ builder.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "g1");
+
+ EJBQLQuery<?> query = builder.buildQuery();
+ assertEquals("select a from Artist a", query.getEjbqlStatement());
+ assertEquals(5, query.getFetchLimit());
+ assertEquals(2, query.getFetchOffset());
+ assertEquals(10, query.getPageSize());
+ assertEquals(6, query.getStatementFetchSize());
+ assertTrue(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.SHARED_CACHE, query.getCacheStrategy());
+ assertEquals("g1", query.getCacheGroup());
+ }
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/map/ProcedureQueryDescriptorTest.java b/cayenne/src/test/java/org/apache/cayenne/map/ProcedureQueryDescriptorTest.java
index f0dc3f611..4d4adb65f 100644
--- a/cayenne/src/test/java/org/apache/cayenne/map/ProcedureQueryDescriptorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/map/ProcedureQueryDescriptorTest.java
@@ -21,10 +21,15 @@ package org.apache.cayenne.map;
import java.util.Map;
+import org.apache.cayenne.query.CapsStrategy;
import org.apache.cayenne.query.ProcedureQuery;
+import org.apache.cayenne.query.QueryCacheStrategy;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class ProcedureQueryDescriptorTest {
@@ -38,4 +43,53 @@ public class ProcedureQueryDescriptorTest {
assertEquals(params, query.getParameters());
}
+
+ @Test
+ public void getQueryRoot() {
+ Procedure procedure = new Procedure("p1");
+
+ ProcedureQueryDescriptor builder = QueryDescriptor.procedureQueryDescriptor();
+ builder.setRoot(procedure);
+ builder.setResultEntityName("A");
+
+ ProcedureQuery<?> query = builder.buildQuery();
+ assertSame(procedure, query.getRoot());
+ assertEquals("A", query.getResultEntityName());
+ }
+
+ @Test
+ public void getQueryProperties() {
+ ProcedureQueryDescriptor builder = QueryDescriptor.procedureQueryDescriptor();
+ builder.setProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, "5");
+ builder.setProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, "2");
+ builder.setProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, "10");
+ builder.setProperty(QueryDescriptor.STATEMENT_FETCH_SIZE_PROPERTY, "6");
+ builder.setProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY, "true");
+ builder.setProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, "LOCAL_CACHE");
+ builder.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "g1");
+ builder.setProperty(ProcedureQueryDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY, "UPPER");
+
+ ProcedureQuery<?> query = builder.buildQuery();
+ assertEquals(5, query.getFetchLimit());
+ assertEquals(2, query.getFetchOffset());
+ assertEquals(10, query.getPageSize());
+ assertEquals(6, query.getStatementFetchSize());
+ assertTrue(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.LOCAL_CACHE, query.getCacheStrategy());
+ assertEquals("g1", query.getCacheGroup());
+ assertEquals(CapsStrategy.UPPER, query.getColumnNamesCapitalization());
+ }
+
+ @Test
+ public void columnNamesCapitalization() {
+ ProcedureQueryDescriptor builder = QueryDescriptor.procedureQueryDescriptor();
+ assertNull(builder.getColumnNamesCapitalization());
+
+ builder.setColumnNamesCapitalization(CapsStrategy.LOWER);
+ assertEquals("LOWER", builder.getProperty(ProcedureQueryDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY));
+ assertEquals(CapsStrategy.LOWER, builder.buildQuery().getColumnNamesCapitalization());
+
+ builder.setColumnNamesCapitalization(null);
+ assertNull(builder.getProperty(ProcedureQueryDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY));
+ }
}
diff --git a/cayenne/src/test/java/org/apache/cayenne/map/QueryDescriptorTest.java b/cayenne/src/test/java/org/apache/cayenne/map/QueryDescriptorTest.java
new file mode 100644
index 000000000..6d693a737
--- /dev/null
+++ b/cayenne/src/test/java/org/apache/cayenne/map/QueryDescriptorTest.java
@@ -0,0 +1,107 @@
+/*****************************************************************
+ * 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.map;
+
+import org.apache.cayenne.query.QueryCacheStrategy;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class QueryDescriptorTest {
+
+ @Test
+ public void defaults() {
+ QueryDescriptor descriptor = QueryDescriptor.descriptor("Unknown");
+ assertEquals(0, descriptor.getFetchLimit());
+ assertEquals(0, descriptor.getFetchOffset());
+ assertEquals(0, descriptor.getPageSize());
+ assertEquals(0, descriptor.getStatementFetchSize());
+ assertFalse(descriptor.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.NO_CACHE, descriptor.getCacheStrategy());
+ assertNull(descriptor.getCacheGroup());
+ }
+
+ @Test
+ public void typedSettersStoreProperties() {
+ QueryDescriptor descriptor = QueryDescriptor.descriptor("Unknown");
+ descriptor.setFetchLimit(5);
+ descriptor.setFetchOffset(2);
+ descriptor.setPageSize(10);
+ descriptor.setStatementFetchSize(6);
+ descriptor.setFetchingDataRows(true);
+ descriptor.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);
+ descriptor.setCacheGroup("g1");
+
+ assertEquals("5", descriptor.getProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY));
+ assertEquals("2", descriptor.getProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY));
+ assertEquals("10", descriptor.getProperty(QueryDescriptor.PAGE_SIZE_PROPERTY));
+ assertEquals("6", descriptor.getProperty(QueryDescriptor.STATEMENT_FETCH_SIZE_PROPERTY));
+ assertEquals("true", descriptor.getProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY));
+ assertEquals("SHARED_CACHE", descriptor.getProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY));
+ assertEquals("g1", descriptor.getProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY));
+
+ assertEquals(5, descriptor.getFetchLimit());
+ assertEquals(2, descriptor.getFetchOffset());
+ assertEquals(10, descriptor.getPageSize());
+ assertEquals(6, descriptor.getStatementFetchSize());
+ assertTrue(descriptor.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.SHARED_CACHE, descriptor.getCacheStrategy());
+ assertEquals("g1", descriptor.getCacheGroup());
+ }
+
+ @Test
+ public void nullRemovesProperty() {
+ QueryDescriptor descriptor = QueryDescriptor.descriptor("Unknown");
+ descriptor.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ descriptor.setCacheGroup("g1");
+
+ descriptor.setCacheStrategy(null);
+ descriptor.setCacheGroup(null);
+
+ assertFalse(descriptor.getProperties().containsKey(QueryDescriptor.CACHE_STRATEGY_PROPERTY));
+ assertFalse(descriptor.getProperties().containsKey(QueryDescriptor.CACHE_GROUPS_PROPERTY));
+ assertEquals(QueryCacheStrategy.NO_CACHE, descriptor.getCacheStrategy());
+ assertNull(descriptor.getCacheGroup());
+ }
+
+ @Test
+ public void unknownCacheStrategyFallsBackToDefault() {
+ QueryDescriptor descriptor = QueryDescriptor.descriptor("Unknown");
+ descriptor.setProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, "NO_SUCH_STRATEGY");
+ assertEquals(QueryCacheStrategy.NO_CACHE, descriptor.getCacheStrategy());
+ }
+
+ @Test
+ public void legacyCacheGroupList() {
+ QueryDescriptor descriptor = QueryDescriptor.descriptor("Unknown");
+
+ descriptor.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "g1,g2");
+ assertEquals("g1", descriptor.getCacheGroup());
+
+ descriptor.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, ",g2");
+ assertEquals("g2", descriptor.getCacheGroup());
+
+ descriptor.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "");
+ assertNull(descriptor.getCacheGroup());
+ }
+}
diff --git a/cayenne/src/test/java/org/apache/cayenne/map/SQLTemplateDescriptorTest.java b/cayenne/src/test/java/org/apache/cayenne/map/SQLTemplateDescriptorTest.java
index 9710442b5..6a2b9044d 100644
--- a/cayenne/src/test/java/org/apache/cayenne/map/SQLTemplateDescriptorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/map/SQLTemplateDescriptorTest.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.query.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -54,16 +55,37 @@ public class SQLTemplateDescriptorTest {
@Test
public void getQueryProperties() throws Exception {
SQLTemplateDescriptor builder = QueryDescriptor.sqlTemplateDescriptor();
- builder.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, "5");
- builder.setProperty(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY, "6");
-
- Query query = builder.buildQuery();
- assertTrue(query instanceof SQLTemplate);
- assertEquals(5, ((SQLTemplate) query).getFetchLimit());
-
- assertEquals(6, ((SQLTemplate) query).getStatementFetchSize());
+ builder.setProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, "5");
+ builder.setProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, "2");
+ builder.setProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, "10");
+ builder.setProperty(QueryDescriptor.STATEMENT_FETCH_SIZE_PROPERTY, "6");
+ builder.setProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY, "true");
+ builder.setProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, "LOCAL_CACHE");
+ builder.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "g1");
+ builder.setProperty(SQLTemplateDescriptor.COLUMN_NAME_CAPITALIZATION_PROPERTY, "lower");
+
+ SQLTemplate<?> query = builder.buildQuery();
+ assertEquals(5, query.getFetchLimit());
+ assertEquals(2, query.getFetchOffset());
+ assertEquals(10, query.getPageSize());
+ assertEquals(6, query.getStatementFetchSize());
+ assertTrue(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.LOCAL_CACHE, query.getCacheStrategy());
+ assertEquals("g1", query.getCacheGroup());
+ assertEquals(CapsStrategy.LOWER, query.getColumnNamesCapitalization());
+ }
- // TODO: test other properties...
+ @Test
+ public void getQueryPropertiesDefaults() throws Exception {
+ SQLTemplate<?> query = QueryDescriptor.sqlTemplateDescriptor().buildQuery();
+ assertEquals(0, query.getFetchLimit());
+ assertEquals(0, query.getFetchOffset());
+ assertEquals(0, query.getPageSize());
+ assertEquals(0, query.getStatementFetchSize());
+ assertFalse(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.NO_CACHE, query.getCacheStrategy());
+ assertNull(query.getCacheGroup());
+ assertEquals(CapsStrategy.DEFAULT, query.getColumnNamesCapitalization());
}
@Test
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 69815aac9..1201f34c9 100644
--- a/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
@@ -23,7 +23,7 @@ import java.util.Map;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.query.QueryCacheStrategy;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -85,14 +85,55 @@ public class SelectQueryDescriptorTest {
public void getQueryProperties() {
SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
builder.setRoot("FakeRoot");
- builder.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, "5");
- builder.setProperty(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY, "6");
+ builder.setProperty(QueryDescriptor.FETCH_LIMIT_PROPERTY, "5");
+ builder.setProperty(QueryDescriptor.FETCH_OFFSET_PROPERTY, "2");
+ builder.setProperty(QueryDescriptor.PAGE_SIZE_PROPERTY, "10");
+ builder.setProperty(QueryDescriptor.STATEMENT_FETCH_SIZE_PROPERTY, "6");
+ builder.setProperty(QueryDescriptor.FETCHING_DATA_ROWS_PROPERTY, "true");
+ builder.setProperty(QueryDescriptor.CACHE_STRATEGY_PROPERTY, "SHARED_CACHE");
+ builder.setProperty(QueryDescriptor.CACHE_GROUPS_PROPERTY, "g1");
+ builder.setProperty(SelectQueryDescriptor.DISTINCT_PROPERTY, "true");
ObjectSelect<?> query = builder.buildQuery();
- assertTrue(query instanceof ObjectSelect);
assertEquals(5, query.getLimit());
+ assertEquals(2, query.getOffset());
+ assertEquals(10, query.getPageSize());
assertEquals(6, query.getStatementFetchSize());
+ assertTrue(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.SHARED_CACHE, query.getCacheStrategy());
+ assertEquals("g1", query.getCacheGroup());
+ assertTrue(query.isDistinct());
+ }
+
+ @Test
+ public void getQueryPropertiesDefaults() {
+ SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
+ builder.setRoot("FakeRoot");
+
+ ObjectSelect<?> query = builder.buildQuery();
+ assertEquals(0, query.getLimit());
+ assertEquals(0, query.getOffset());
+ assertEquals(0, query.getPageSize());
+ assertEquals(0, query.getStatementFetchSize());
+ assertFalse(query.isFetchingDataRows());
+ assertEquals(QueryCacheStrategy.NO_CACHE, query.getCacheStrategy());
+ assertNull(query.getCacheGroup());
+ assertFalse(query.isDistinct());
+ }
- // TODO: test other properties...
+ @Test
+ public void typedSetters() {
+ SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
+ builder.setRoot("FakeRoot");
+ builder.setFetchLimit(5);
+ builder.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE);
+ builder.setCacheGroup("g1");
+ builder.setFetchingDataRows(true);
+
+ ObjectSelect<?> query = builder.buildQuery();
+ assertEquals(5, query.getLimit());
+ assertEquals(QueryCacheStrategy.LOCAL_CACHE, query.getCacheStrategy());
+ assertEquals("g1", query.getCacheGroup());
+ assertTrue(query.isFetchingDataRows());
}
}