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/06/29 00:07:37 UTC
(cayenne) 02/02: cleanup
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 7fcbadb75afc09c555ffdb510917fc175be8d0c3
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Sun Jun 28 17:48:32 2026 -0400
cleanup
---
.../reader/CryptoRowReaderFactoryDecorator.java | 9 +-
.../cayenne/access/jdbc/reader/BaseRowReader.java | 59 -----------
.../access/jdbc/reader/CompoundRowReader.java | 10 +-
.../jdbc/reader/DefaultRowReaderFactory.java | 113 ++++++++++++++++-----
.../access/jdbc/reader/EntityRowReader.java | 100 ++++++++++--------
.../cayenne/access/jdbc/reader/FullRowReader.java | 62 ++++++++---
.../cayenne/access/jdbc/reader/IdRowReader.java | 113 ---------------------
.../{FullRowReader.java => IndexedRowReader.java} | 42 ++++----
.../reader/InheritanceAwareEntityRowReader.java | 47 ---------
.../jdbc/reader/InheritanceAwareRowReader.java | 46 ---------
.../cayenne/access/jdbc/reader/RowReader.java | 3 +-
11 files changed, 219 insertions(+), 385 deletions(-)
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
index acfd558fe..61ddd42b3 100644
--- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
+++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
@@ -18,9 +18,6 @@
****************************************************************/
package org.apache.cayenne.crypto.reader;
-import java.sql.ResultSet;
-import java.util.Map;
-
import org.apache.cayenne.access.jdbc.RSColumn;
import org.apache.cayenne.access.jdbc.reader.DefaultRowReaderFactory;
import org.apache.cayenne.access.jdbc.reader.RowReader;
@@ -41,6 +38,9 @@ import org.apache.cayenne.query.EntityResultSegment;
import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.query.ScalarResultSegment;
+import java.sql.ResultSet;
+import java.util.Map;
+
public class CryptoRowReaderFactoryDecorator extends DefaultRowReaderFactory {
private TransformerFactory transformerFactory;
@@ -208,8 +208,7 @@ public class CryptoRowReaderFactoryDecorator extends DefaultRowReaderFactory {
private class DecoratedFullRowReader extends DecoratedEntityFullRowReader {
- DecoratedFullRowReader(RSColumn[] columns,
- RowReader<?> delegateReader) {
+ DecoratedFullRowReader(RSColumn[] columns, RowReader<?> delegateReader) {
super(columns, delegateReader, null);
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java
deleted file mode 100644
index a6cefeab1..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne.access.jdbc.reader;
-
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.access.types.ExtendedType;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.QueryMetadata;
-
-import java.sql.ResultSet;
-
-/**
- * @since 3.0
- */
-abstract class BaseRowReader<T> implements RowReader<T> {
-
- ExtendedType[] converters;
- String[] labels;
- int[] types;
- String entityName;
-
- BaseRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
- ObjEntity rootObjEntity = queryMetadata.getObjEntity();
- if (rootObjEntity != null) {
- this.entityName = rootObjEntity.getName();
- }
-
- int width = columns.length;
- this.converters = new ExtendedType[width];
- this.labels = new String[width];
- this.types = new int[width];
-
- for (int i = 0; i < width; i++) {
- converters[i] = columns[i].reader();
- labels[i] = columns[i].dataRowName();
- types[i] = columns[i].rsType();
- }
- }
-
- @Override
- public abstract T readRow(ResultSet resultSet);
-
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
index 37c195ef7..d0ca470ea 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
@@ -27,14 +27,10 @@ import java.sql.ResultSet;
*/
class CompoundRowReader implements RowReader<Object[]> {
- private RowReader<?>[] readers;
+ private final RowReader<?>[] readers;
- CompoundRowReader(int width) {
- this.readers = new RowReader[width];
- }
-
- void addRowReader(int pos, RowReader<?> reader) {
- this.readers[pos] = reader;
+ public CompoundRowReader(RowReader<?>[] readers) {
+ this.readers = readers;
}
@Override
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
index 84fdda10d..0952a3d6f 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
@@ -22,6 +22,9 @@ import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.jdbc.RSColumn;
import org.apache.cayenne.access.types.ExtendedType;
import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.query.EmbeddableResultSegment;
import org.apache.cayenne.query.EntityResultSegment;
import org.apache.cayenne.query.QueryMetadata;
@@ -37,26 +40,22 @@ public class DefaultRowReaderFactory implements RowReaderFactory {
@Override
public RowReader<?> rowReader(RSColumn[] columns, QueryMetadata queryMetadata, DbAdapter adapter) {
- List<Object> rsMapping = queryMetadata.getResultSetMapping();
- if (rsMapping == null) {
+ List<Object> segments = queryMetadata.getResultSetMapping();
+ if (segments == null || segments.isEmpty()) {
return createFullRowReader(columns, queryMetadata);
}
- int resultWidth = rsMapping.size();
- if (resultWidth == 0) {
- throw new CayenneRuntimeException("Empty result columns");
- }
-
if (queryMetadata.isSingleResultSetMapping()) {
- return segmentRowReader(rsMapping.getFirst(), columns, queryMetadata);
- } else {
- CompoundRowReader reader = new CompoundRowReader(resultWidth);
- for (int i = 0; i < resultWidth; i++) {
- reader.addRowReader(i, segmentRowReader(rsMapping.get(i), columns, queryMetadata));
- }
+ return segmentRowReader(segments.getFirst(), columns, queryMetadata);
+ }
- return reader;
+ int w = segments.size();
+ RowReader<?>[] readers = new RowReader[w];
+ for (int i = 0; i < w; i++) {
+ readers[i] = segmentRowReader(segments.get(i), columns, queryMetadata);
}
+
+ return new CompoundRowReader(readers);
}
private RowReader<?> segmentRowReader(Object segment, RSColumn[] columns, QueryMetadata queryMetadata) {
@@ -93,27 +92,89 @@ public class DefaultRowReaderFactory implements RowReaderFactory {
columns[scalarIndex].rsType());
}
- protected RowReader<?> createEntityRowReader(RSColumn[] columns, QueryMetadata queryMetadata,
- EntityResultSegment resultMetadata) {
+ protected RowReader<?> createEntityRowReader(
+ RSColumn[] columns,
+ QueryMetadata queryMetadata,
+ EntityResultSegment resultMetadata) {
if (queryMetadata.getPageSize() > 0) {
- return new IdRowReader<>(columns, queryMetadata, resultMetadata);
- } else if (resultMetadata.getClassDescriptor() != null && resultMetadata.getClassDescriptor().hasSubclasses()) {
- return new InheritanceAwareEntityRowReader(columns, resultMetadata);
- } else {
- return new EntityRowReader(columns, resultMetadata);
+ return createIdRowReader(columns, queryMetadata, resultMetadata);
}
+
+ int startIndex = resultMetadata.getColumnOffset();
+ int segmentWidth = resultMetadata.getFields().size();
+ ExtendedType<?>[] readers = new ExtendedType[segmentWidth];
+ int[] types = new int[segmentWidth];
+ String[] labels = new String[segmentWidth];
+
+ for (int i = 0; i < segmentWidth; i++) {
+ RSColumn column = columns[startIndex + i];
+ readers[i] = column.reader();
+ types[i] = column.rsType();
+
+ // the query translator may reorder fields compared to the entity result, so resolve the
+ // DataRow label by reverse lookup of the column name...
+ if (column.dataRowName().contains(".")) {
+ // a dotted dataRowName is a prefetched column - use it directly instead of by alias
+ labels[i] = column.dataRowName();
+ } else {
+ labels[i] = resultMetadata.getColumnPath(column.dataRowName());
+ }
+ }
+
+ return EntityRowReader.of(readers, types, labels, startIndex, resultMetadata.getClassDescriptor());
}
protected RowReader<?> createFullRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
if (queryMetadata.getPageSize() > 0) {
- return new IdRowReader<>(columns, queryMetadata, null);
- } else if (queryMetadata.getClassDescriptor() != null && queryMetadata.getClassDescriptor().hasSubclasses()) {
- return new InheritanceAwareRowReader(columns, queryMetadata);
- } else {
- return new FullRowReader(columns, queryMetadata);
+ return createIdRowReader(columns, queryMetadata, null);
+ }
+
+ return FullRowReader.of(columns, queryMetadata);
+ }
+
+ private RowReader<?> createIdRowReader(RSColumn[] columns, QueryMetadata queryMetadata,
+ EntityResultSegment resultMetadata) {
+ int[] pk = pkIndices(columns, queryMetadata, resultMetadata);
+
+ // single-column PK - read the value directly as a scalar
+ if (pk.length == 1) {
+ RSColumn column = columns[pk[0]];
+ // jdbc column indexes start from 1
+ return new ScalarRowReader<>(column.reader(), pk[0] + 1, column.rsType());
+ }
+
+ return new IndexedRowReader(columns, entityName(queryMetadata), pk);
+ }
+
+ private static String entityName(QueryMetadata queryMetadata) {
+ ObjEntity objEntity = queryMetadata.getObjEntity();
+ return objEntity != null ? objEntity.getName() : null;
+ }
+
+ private static int[] pkIndices(RSColumn[] columns, QueryMetadata queryMetadata, EntityResultSegment resultMetadata) {
+ DbEntity dbEntity = resultMetadata == null
+ ? queryMetadata.getDbEntity()
+ : resultMetadata.getClassDescriptor().getEntity().getDbEntity();
+ if (dbEntity == null) {
+ throw new CayenneRuntimeException("Null root DbEntity, can't index PK");
+ }
+
+ int len = dbEntity.getPrimaryKeys().size();
+ if (len == 0) {
+ throw new CayenneRuntimeException("Root DBEntity has no PK defined: %s", dbEntity);
+ }
+
+ int[] pk = new int[len];
+ int offset = resultMetadata != null ? resultMetadata.getColumnOffset() : 0;
+ for (int i = offset, j = 0; i < offset + len; i++) {
+ DbAttribute a = dbEntity.getAttribute(columns[i].rsName());
+ if (a != null && a.isPrimaryKey()) {
+ pk[j++] = i;
+ }
}
+ return pk;
}
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
index 524066fa1..eb4413829 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
@@ -18,59 +18,48 @@
****************************************************************/
package org.apache.cayenne.access.jdbc.reader;
-import java.sql.ResultSet;
-
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
import org.apache.cayenne.access.types.ExtendedType;
-import org.apache.cayenne.query.EntityResultSegment;
+import org.apache.cayenne.map.EntityInheritanceTree;
+import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.reflect.ClassDescriptor;
import org.apache.cayenne.util.Util;
+import java.sql.ResultSet;
+
/**
* @since 3.0
*/
class EntityRowReader implements RowReader<DataRow> {
- private ExtendedType[] converters;
- private String[] labels;
- private int[] types;
-
- String entityName;
- private int mapCapacity;
- private int startIndex;
-
- EntityRowReader(RSColumn[] columns, EntityResultSegment segmentMetadata) {
-
- ClassDescriptor classDescriptor = segmentMetadata.getClassDescriptor();
-
- if (classDescriptor != null) {
- this.entityName = classDescriptor.getEntity().getName();
- }
+ private final ExtendedType<?>[] readers;
+ private final String[] labels;
+ private final int[] types;
+ private final int mapCapacity;
+ private final int startIndex;
+ protected final String entityName;
+
+ static RowReader<DataRow> of(
+ ExtendedType<?>[] readers,
+ int[] types,
+ String[] labels,
+ int startIndex,
+ ClassDescriptor classDescriptor) {
+
+ String entityName = classDescriptor != null ? classDescriptor.getEntity().getName() : null;
+ return classDescriptor != null && classDescriptor.hasSubclasses()
+ ? new InheritanceAwareEntityRowReader(readers, types, labels, startIndex, entityName, classDescriptor.getEntityInheritanceTree())
+ : new EntityRowReader(readers, types, labels, startIndex, entityName);
+ }
- int segmentWidth = segmentMetadata.getFields().size();
- this.startIndex = segmentMetadata.getColumnOffset();
- this.converters = new ExtendedType[segmentWidth];
- this.types = new int[segmentWidth];
- this.labels = new String[segmentWidth];
-
- for (int i = 0; i < segmentWidth; i++) {
- this.converters[i] = columns[startIndex + i].reader();
- types[i] = columns[startIndex + i].rsType();
-
- // query translator may change the order of fields compare to the entity
- // result, so figure out DataRow labels by doing reverse lookup of
- // RowDescriptor labels...
- if (columns[startIndex + i].dataRowName().contains(".")) {
- // if the dataRowKey contains ".", it is prefetched column and
- // we can use it instead of search the name by alias
- labels[i] = columns[startIndex + i].dataRowName();
- } else {
- labels[i] = segmentMetadata.getColumnPath(columns[startIndex + i].dataRowName());
- }
- }
- this.mapCapacity = (int) Math.ceil(segmentWidth / 0.75);
+ protected EntityRowReader(ExtendedType<?>[] readers, int[] types, String[] labels, int startIndex, String entityName) {
+ this.readers = readers;
+ this.types = types;
+ this.labels = labels;
+ this.startIndex = startIndex;
+ this.entityName = entityName;
+ this.mapCapacity = (int) Math.ceil(readers.length / 0.75);
}
@Override
@@ -78,12 +67,12 @@ class EntityRowReader implements RowReader<DataRow> {
try {
DataRow row = new DataRow(mapCapacity);
- int len = converters.length;
+ int len = readers.length;
for (int i = 0; i < len; i++) {
// note: jdbc column indexes start from 1, not 0 as in arrays
- Object val = converters[i].materializeObject(resultSet, startIndex + i + 1, types[i]);
+ Object val = readers[i].materializeObject(resultSet, startIndex + i + 1, types[i]);
row.put(labels[i], val);
}
@@ -98,7 +87,30 @@ class EntityRowReader implements RowReader<DataRow> {
}
}
- void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception {
+ protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
dataRow.setEntityName(entityName);
}
+
+ private static class InheritanceAwareEntityRowReader extends EntityRowReader {
+
+ private final EntityInheritanceTree entityInheritanceTree;
+
+ InheritanceAwareEntityRowReader(
+ ExtendedType<?>[] readers,
+ int[] types,
+ String[] labels,
+ int startIndex,
+ String entityName,
+ EntityInheritanceTree entityInheritanceTree) {
+
+ super(readers, types, labels, startIndex, entityName);
+ this.entityInheritanceTree = entityInheritanceTree;
+ }
+
+ @Override
+ protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
+ ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
+ dataRow.setEntityName(entity != null ? entity.getName() : entityName);
+ }
+ }
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
index 31857d6cd..84bd20284 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
@@ -21,35 +21,53 @@ package org.apache.cayenne.access.jdbc.reader;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.access.jdbc.RSColumn;
+import org.apache.cayenne.map.EntityInheritanceTree;
+import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.reflect.ClassDescriptor;
import java.sql.ResultSet;
/**
* @since 3.0
*/
-class FullRowReader extends BaseRowReader<DataRow> {
+class FullRowReader implements RowReader<DataRow> {
- int mapCapacity;
+ private final RSColumn[] columns;
+ private final int mapCapacity;
+ protected final String entityName;
- FullRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
- super(columns, queryMetadata);
+ static RowReader<DataRow> of(RSColumn[] columns, QueryMetadata queryMetadata) {
+
+ ObjEntity objEntity = queryMetadata.getObjEntity();
+ String entityName = objEntity != null ? objEntity.getName() : null;
+
+ ClassDescriptor classDescriptor = queryMetadata.getClassDescriptor();
+ if (classDescriptor != null && classDescriptor.hasSubclasses()) {
+ return new InheritanceAwareRowReader(columns, entityName, classDescriptor.getEntityInheritanceTree());
+ }
+
+ return new FullRowReader(columns, entityName);
+ }
+
+ public FullRowReader(RSColumn[] columns, String entityName) {
+ this.columns = columns;
+ this.entityName = entityName;
this.mapCapacity = (int) Math.ceil(columns.length / 0.75);
}
@Override
public DataRow readRow(ResultSet resultSet) {
- try {
- DataRow dataRow = new DataRow(mapCapacity);
+ DataRow dataRow = new DataRow(mapCapacity);
+ int w = columns.length;
- int resultWidth = labels.length;
+ try {
- // process result row columns,
- for (int i = 0; i < resultWidth; i++) {
- // note: jdbc column indexes start from 1, not 0 unlike
- // everywhere else
- Object val = converters[i].materializeObject(resultSet, i + 1, types[i]);
- dataRow.put(labels[i], val);
+ for (int i = 0; i < w; i++) {
+ RSColumn column = columns[i];
+ // jdbc column indexes start from 1, not 0 unlike everywhere else
+ Object val = column.reader().materializeObject(resultSet, i + 1, column.rsType());
+ dataRow.put(column.dataRowName(), val);
}
postprocessRow(resultSet, dataRow);
@@ -62,7 +80,23 @@ class FullRowReader extends BaseRowReader<DataRow> {
}
}
- void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception {
+ protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
dataRow.setEntityName(entityName);
}
+
+ private static class InheritanceAwareRowReader extends FullRowReader {
+
+ private final EntityInheritanceTree entityInheritanceTree;
+
+ InheritanceAwareRowReader(RSColumn[] columns, String entityName, EntityInheritanceTree entityInheritanceTree) {
+ super(columns, entityName);
+ this.entityInheritanceTree = entityInheritanceTree;
+ }
+
+ @Override
+ protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
+ ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
+ dataRow.setEntityName(entity != null ? entity.getName() : entityName);
+ }
+ }
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java
deleted file mode 100644
index 789ccf2d8..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne.access.jdbc.reader;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.query.EntityResultSegment;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.util.Util;
-
-import java.sql.ResultSet;
-
-/**
- * @since 3.0
- */
-class IdRowReader<T> extends BaseRowReader<T> {
-
- protected int[] pkIndices;
-
- public IdRowReader(RSColumn[] columns, QueryMetadata queryMetadata, EntityResultSegment resultMetadata) {
- super(columns, queryMetadata);
-
- DbEntity dbEntity = resultMetadata == null
- ? queryMetadata.getDbEntity()
- : resultMetadata.getClassDescriptor().getEntity().getDbEntity();
- if (dbEntity == null) {
- throw new CayenneRuntimeException("Null root DbEntity, can't index PK");
- }
-
- int len = dbEntity.getPrimaryKeys().size();
-
- // sanity check
- if (len == 0) {
- throw new CayenneRuntimeException("Root DBEntity has no PK defined: %s", dbEntity);
- }
-
- int[] pk = new int[len];
- int offset = resultMetadata != null ?
- resultMetadata.getColumnOffset() :
- 0;
- for(int i = offset, j = 0; i < offset + len; i++) {
- DbAttribute a = dbEntity.getAttribute(columns[i].rsName());
- if(a != null && a.isPrimaryKey()) {
- pk[j++] = i;
- }
- }
-
- this.pkIndices = pk;
- }
-
- @Override
- public T readRow(ResultSet resultSet) {
- try {
- if (pkIndices.length == 1) {
- return readSingleId(resultSet);
- } else {
- return readIdMap(resultSet);
- }
- } catch (CayenneRuntimeException cex) {
- // rethrow unmodified
- throw cex;
- } catch (Exception otherex) {
- throw new CayenneRuntimeException("Exception materializing id column.", Util.unwindException(otherex));
- }
- }
-
- private T readSingleId(ResultSet resultSet) throws Exception {
-
- // dereference column index
- int index = pkIndices[0];
-
- // note: jdbc column indexes start from 1, not 0 as in arrays
- @SuppressWarnings("unchecked")
- T val = (T) converters[index].materializeObject(resultSet, index + 1, types[index]);
-
- return val;
- }
-
- @SuppressWarnings("unchecked")
- private T readIdMap(ResultSet resultSet) throws Exception {
-
- DataRow idRow = new DataRow(2);
- idRow.setEntityName(entityName);
-
- for (int index : pkIndices) {
- // dereference column index
- // note: jdbc column indexes start from 1, not 0 as in arrays
- Object val = converters[index].materializeObject(resultSet, index + 1, types[index]);
- idRow.put(labels[index], val);
- }
-
- return (T) idRow;
- }
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
similarity index 60%
copy from cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
copy to cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
index 31857d6cd..605b99790 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
@@ -21,48 +21,46 @@ package org.apache.cayenne.access.jdbc.reader;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.query.QueryMetadata;
import java.sql.ResultSet;
/**
- * @since 3.0
+ * A {@link RowReader} that materializes a subset of the result columns.
*/
-class FullRowReader extends BaseRowReader<DataRow> {
+class IndexedRowReader implements RowReader<DataRow> {
- int mapCapacity;
+ private final String entityName;
+ private final RSColumn[] columns;
+ private final int[] indices;
+ private final int mapCapacity;
- FullRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
- super(columns, queryMetadata);
- this.mapCapacity = (int) Math.ceil(columns.length / 0.75);
+ public IndexedRowReader(RSColumn[] columns, String entityName, int[] indices) {
+ this.columns = columns;
+ this.entityName = entityName;
+ this.mapCapacity = (int) Math.ceil(indices.length / 0.75);
+ this.indices = indices;
}
@Override
public DataRow readRow(ResultSet resultSet) {
- try {
- DataRow dataRow = new DataRow(mapCapacity);
+ DataRow dataRow = new DataRow(mapCapacity);
- int resultWidth = labels.length;
+ try {
- // process result row columns,
- for (int i = 0; i < resultWidth; i++) {
- // note: jdbc column indexes start from 1, not 0 unlike
- // everywhere else
- Object val = converters[i].materializeObject(resultSet, i + 1, types[i]);
- dataRow.put(labels[i], val);
+ for (int index : indices) {
+ RSColumn column = columns[index];
+ // jdbc column indexes start from 1, not 0 unlike everywhere else
+ Object val = column.reader().materializeObject(resultSet, index + 1, column.rsType());
+ dataRow.put(column.dataRowName(), val);
}
- postprocessRow(resultSet, dataRow);
+ dataRow.setEntityName(entityName);
return dataRow;
} catch (CayenneRuntimeException ex) {
throw ex;
} catch (Exception ex) {
- throw new CayenneRuntimeException("Exception materializing column.", ex);
+ throw new CayenneRuntimeException("Exception materializing id column.", ex);
}
}
-
- void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception {
- dataRow.setEntityName(entityName);
- }
}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java
deleted file mode 100644
index 449b7ebeb..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne.access.jdbc.reader;
-
-import java.sql.ResultSet;
-
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.EntityInheritanceTree;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.EntityResultSegment;
-
-/**
- * @since 3.0
- */
-class InheritanceAwareEntityRowReader extends EntityRowReader {
-
- private EntityInheritanceTree entityInheritanceTree;
-
- public InheritanceAwareEntityRowReader(RSColumn[] columns, EntityResultSegment segmentMetadata) {
-
- super(columns, segmentMetadata);
- this.entityInheritanceTree = segmentMetadata.getClassDescriptor().getEntityInheritanceTree();
- }
-
- @Override
- void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception {
- ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
- dataRow.setEntityName(entity != null ? entity.getName() : entityName);
- }
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java
deleted file mode 100644
index 7d765089f..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ****************************************************************/
-package org.apache.cayenne.access.jdbc.reader;
-
-import java.sql.ResultSet;
-
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.EntityInheritanceTree;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.QueryMetadata;
-
-/**
- * @since 3.0
- */
-class InheritanceAwareRowReader extends FullRowReader {
-
- private EntityInheritanceTree entityInheritanceTree;
-
- InheritanceAwareRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
- super(columns, queryMetadata);
- this.entityInheritanceTree = queryMetadata.getClassDescriptor().getEntityInheritanceTree();
- }
-
- @Override
- void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception {
- ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
- dataRow.setEntityName(entity != null ? entity.getName() : entityName);
- }
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
index 4a1599a94..1bb55ec91 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
@@ -21,8 +21,7 @@ package org.apache.cayenne.access.jdbc.reader;
import java.sql.ResultSet;
/**
- * A strategy class that encapsulates an algorithm for converting a single
- * ResultSet row into a DataRow.
+ * A strategy class that encapsulates an algorithm for converting a single ResultSet row into a DataRow.
*
* @since 3.0
*/