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 2008/12/01 11:01:46 UTC
svn commit: r722020 - in
/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src:
main/java/org/apache/cayenne/access/
main/java/org/apache/cayenne/access/jdbc/ test/java/org/apache/cayenne/
Author: aadamchik
Date: Mon Dec 1 02:01:44 2008
New Revision: 722020
URL: http://svn.apache.org/viewvc?rev=722020&view=rev
Log:
CAY-1140 Store ObjEntity name in the DataRow
pushing result resolution action down to JDBC ResultIterator
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAction.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EntityRowReader.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/DataObjectUtilsTest.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java Mon Dec 1 02:01:44 2008
@@ -41,7 +41,6 @@
import org.apache.cayenne.map.LifecycleEvent;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.query.EntityResultMetadata;
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.PrefetchSelectQuery;
import org.apache.cayenne.query.PrefetchTreeNode;
@@ -430,7 +429,7 @@
if (context != null && !metadata.isFetchingDataRows()) {
- List<DataRow> mainRows = response.firstList();
+ List<Object> mainRows = response.firstList();
if (mainRows != null && !mainRows.isEmpty()) {
ObjectConversionStrategy converter;
@@ -568,9 +567,9 @@
return isQualifiedEntity(entity);
}
- abstract class ObjectConversionStrategy {
+ abstract class ObjectConversionStrategy<T> {
- abstract void convert(List<DataRow> mainRows);
+ abstract void convert(List<T> mainRows);
protected List<Persistent> toObjects(
ClassDescriptor descriptor,
@@ -593,27 +592,6 @@
return objects;
}
- protected List<DataRow> toNormalizedDataRows(
- EntityResultMetadata entityMapping,
- List<DataRow> dataRows) {
- List<DataRow> normalized = new ArrayList<DataRow>(dataRows.size());
-
- Map<String, String> fields = entityMapping.getFields();
- int rowCapacity = (int) Math.ceil(fields.size() / 0.75);
-
- for (DataRow src : dataRows) {
- DataRow target = new DataRow(rowCapacity);
-
- for (Map.Entry<String, String> field : fields.entrySet()) {
- target.put(field.getKey(), src.get(field.getValue()));
- }
-
- normalized.add(target);
- }
-
- return normalized;
- }
-
protected void updateResponse(List sourceObjects, List targetObjects) {
if (response instanceof GenericResponse) {
((GenericResponse) response).replaceResult(sourceObjects, targetObjects);
@@ -627,28 +605,15 @@
}
}
- class SingleObjectConversionStrategy extends ObjectConversionStrategy {
+ class SingleObjectConversionStrategy extends ObjectConversionStrategy<DataRow> {
@Override
void convert(List<DataRow> mainRows) {
- List<DataRow> normalized;
-
- // convert data rows to standardized format...
- SQLResultSetMetadata rsMapping = metadata.getResultSetMapping();
- if (rsMapping != null) {
- // expect 1 and only 1 entityMapping...
- EntityResultMetadata entityMapping = rsMapping.getEntitySegment(0);
- normalized = toNormalizedDataRows(entityMapping, mainRows);
- }
- else {
- normalized = mainRows;
- }
-
ClassDescriptor descriptor = metadata.getClassDescriptor();
PrefetchTreeNode prefetchTree = metadata.getPrefetchTree();
- List<Persistent> objects = toObjects(descriptor, prefetchTree, normalized);
+ List<Persistent> objects = toObjects(descriptor, prefetchTree, mainRows);
updateResponse(mainRows, objects);
// apply POST_LOAD callback
@@ -662,71 +627,68 @@
}
}
- class SingleScalarConversionStrategy extends ObjectConversionStrategy {
+ class SingleScalarConversionStrategy extends ObjectConversionStrategy<Object> {
@Override
- void convert(List<DataRow> mainRows) {
+ void convert(List<Object> mainRows) {
+ // noop... scalars require no further processing
+ }
+ }
- SQLResultSetMetadata rsMapping = metadata.getResultSetMapping();
+ class MixedConversionStrategy extends ObjectConversionStrategy<Object[]> {
- int rowsLen = mainRows.size();
-
- List objects = new ArrayList(rowsLen);
- String column = rsMapping.getScalarSegment(0);
+ protected List<Persistent> toObjects(
+ ClassDescriptor descriptor,
+ PrefetchTreeNode prefetchTree,
+ List<Object[]> rows,
+ int position) {
+ List<Persistent> objects;
- // add scalars to the result
- for (DataRow row : mainRows) {
- objects.add(row.get(column));
+ // take a shortcut when no prefetches exist...
+ if (prefetchTree == null) {
+ objects = new ObjectResolver(context, descriptor)
+ .synchronizedObjectsFromDataRows(rows, position);
}
-
- updateResponse(mainRows, objects);
+ else {
+ ObjectTreeResolver resolver = new ObjectTreeResolver(context, metadata);
+ objects = resolver.synchronizedObjectsFromDataRows(
+ prefetchTree,
+ rows,
+ prefetchResultsByPath);
+ }
+ return objects;
}
- }
-
- class MixedConversionStrategy extends ObjectConversionStrategy {
@Override
- void convert(List<DataRow> mainRows) {
+ void convert(List<Object[]> mainRows) {
int rowsLen = mainRows.size();
- List<Object[]> objects = new ArrayList<Object[]>(rowsLen);
SQLResultSetMetadata rsMapping = metadata.getResultSetMapping();
- // pass 1 - init Object[]'s and resolve scalars for each row
+ // no conversions needed for scalar positions; reuse Object[]'s to fill them
+ // with resolved objects
- int resultWidth = rsMapping.getSegmentsCount();
int[] entityPositions = rsMapping.getEntitySegments();
- int[] columnPositions = rsMapping.getScalarSegments();
-
- for (DataRow row : mainRows) {
- Object[] resultRow = new Object[resultWidth];
- for (int i = 0; i < columnPositions.length; i++) {
- int pos = columnPositions[i];
- resultRow[pos] = row.get(rsMapping.getScalarSegment(pos));
- }
- objects.add(resultRow);
- }
-
- // pass 2 - resolve individual object columns, and then update the rows...
EntityResolver resolver = domain.getEntityResolver();
List[] resultLists = new List[entityPositions.length];
for (int i = 0; i < entityPositions.length; i++) {
int pos = entityPositions[i];
- EntityResultMetadata entityMapping = rsMapping.getEntitySegment(pos);
- List<DataRow> normalized = toNormalizedDataRows(entityMapping, mainRows);
-
- List<Persistent> nextResult = toObjects(entityMapping
- .getClassDescriptor(), null, normalized);
- for (int j = 0; j < rowsLen; j++) {
- objects.get(j)[pos] = nextResult.get(j);
- }
+ List<Persistent> nextResult = toObjects(rsMapping
+ .getEntitySegment(pos)
+ .getClassDescriptor(), null, mainRows, pos);
resultLists[i] = nextResult;
}
- updateResponse(mainRows, objects);
+ for (int j = 0; j < rowsLen; j++) {
+
+ Object[] row = mainRows.get(j);
+ for (int i = 0; i < entityPositions.length; i++) {
+ row[i] = resultLists[i].get(j);
+ }
+ }
// invoke callbacks now that all objects are resolved...
LifecycleCallbackRegistry callbackRegistry = context
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java Mon Dec 1 02:01:44 2008
@@ -89,12 +89,18 @@
/**
* Properly synchronized version of 'objectsFromDataRows'.
*/
- List<Persistent> synchronizedObjectsFromDataRows(List rows) {
+ List<Persistent> synchronizedObjectsFromDataRows(List<? extends DataRow> rows) {
synchronized (context.getObjectStore()) {
return objectsFromDataRows(rows);
}
}
+ List<Persistent> synchronizedObjectsFromDataRows(List<Object[]> rows, int position) {
+ synchronized (context.getObjectStore()) {
+ return objectsFromDataRows(rows, position);
+ }
+ }
+
/**
* Converts rows to objects.
* <p>
@@ -102,16 +108,14 @@
* and DataRowStore.
* </p>
*/
- List<Persistent> objectsFromDataRows(List rows) {
+ List<Persistent> objectsFromDataRows(List<? extends DataRow> rows) {
if (rows == null || rows.size() == 0) {
return new ArrayList<Persistent>(1);
}
List<Persistent> results = new ArrayList<Persistent>(rows.size());
- Iterator it = rows.iterator();
- while (it.hasNext()) {
- DataRow row = (DataRow) it.next();
+ for (DataRow row : rows) {
Persistent object = objectFromDataRow(row);
if (object == null) {
@@ -127,6 +131,29 @@
return results;
}
+ List<Persistent> objectsFromDataRows(List<Object[]> rows, int position) {
+ if (rows == null || rows.size() == 0) {
+ return new ArrayList<Persistent>(1);
+ }
+
+ List<Persistent> results = new ArrayList<Persistent>(rows.size());
+
+ for (Object[] row : rows) {
+ Persistent object = objectFromDataRow((DataRow) row[position]);
+
+ if (object == null) {
+ throw new CayenneRuntimeException("Can't build Object from row: " + row[position]);
+ }
+
+ results.add(object);
+ }
+
+ // now deal with snapshots
+ cache.snapshotsUpdatedForObjects(results, rows);
+
+ return results;
+ }
+
/**
* Processes a list of rows for a result set that has objects related to a set of
* parent objects via some relationship defined in PrefetchProcessorNode parameter.
@@ -308,6 +335,7 @@
}
interface DescriptorResolutionStrategy {
+
ClassDescriptor descriptorForRow(DataRow row);
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAction.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAction.java Mon Dec 1 02:01:44 2008
@@ -96,6 +96,7 @@
QueryMetadata md = query.getMetaData(getEntityResolver());
sqlQuery.setFetchLimit(md.getFetchLimit());
sqlQuery.setFetchOffset(md.getFetchOffset());
+ sqlQuery.setResult(compiledExpression.getResult());
actionFactory.sqlAction(sqlQuery).performAction(connection, observer);
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EntityRowReader.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EntityRowReader.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EntityRowReader.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EntityRowReader.java Mon Dec 1 02:01:44 2008
@@ -50,15 +50,14 @@
valueIndices[j++] = i;
}
}
-
}
@Override
public DataRow readRow(ResultSet resultSet) throws CayenneException {
-
+
try {
- DataRow idRow = new DataRow(mapCapacity);
- idRow.setEntityName(entityName);
+ DataRow row = new DataRow(mapCapacity);
+ row.setEntityName(entityName);
int len = valueIndices.length;
for (int i = 0; i < len; i++) {
@@ -71,14 +70,14 @@
resultSet,
index + 1,
types[index]);
- idRow.put(labels[index], val);
+ row.put(labels[index], val);
}
if (postProcessor != null) {
- postProcessor.postprocessRow(resultSet, idRow);
+ postProcessor.postprocessRow(resultSet, row);
}
- return idRow;
+ return row;
}
catch (CayenneException cex) {
// rethrow unmodified
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java Mon Dec 1 02:01:44 2008
@@ -117,12 +117,12 @@
reader.addRowReader(i, new EntityRowReader(
descriptor,
queryMetadata,
- rsMapping.getEntitySegment(entitySegments[i])));
+ rsMapping.getEntitySegment(i)));
}
for (int i : scalarSegments) {
reader.addRowReader(i, new ScalarRowReader(descriptor, rsMapping
- .getScalarSegment(scalarSegments[i])));
+ .getScalarSegment(i)));
}
return reader;
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/DataObjectUtilsTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/DataObjectUtilsTest.java?rev=722020&r1=722019&r2=722020&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/DataObjectUtilsTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/DataObjectUtilsTest.java Mon Dec 1 02:01:44 2008
@@ -78,7 +78,7 @@
EJBQLQuery query = new EJBQLQuery(ejbql);
Object object = DataObjectUtils.objectForQuery(context, query);
assertNotNull(object);
- assertTrue(object instanceof Number);
+ assertTrue("Object class: " + object.getClass().getName(), object instanceof Number);
assertEquals(2, ((Number) object).intValue());
}