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());
     }