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 <[email protected]> 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 */
