cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r609146 - /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/
Date Sat, 05 Jan 2008 15:06:27 GMT
Author: aadamchik
Date: Sat Jan  5 07:05:15 2008
New Revision: 609146

URL: http://svn.apache.org/viewvc?rev=609146&view=rev
Log:
CAY-948 Implement flattened attributes in Cayenne
(support for joined tables in select clause translation)

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTableId.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
Sat Jan  5 07:05:15 2008
@@ -166,9 +166,8 @@
         context.append(" WHERE");
 
         // TODO: andrus, 8/11/2007 flattened?
-        DbRelationship correlatedJoinRelationship = context
-                .getIncomingRelationships(id)
-                .get(0);
+        DbRelationship correlatedJoinRelationship = context.getIncomingRelationships(
+                new EJBQLTableId(id)).get(0);
         Iterator<DbJoin> it = correlatedJoinRelationship.getJoins().iterator();
         while (it.hasNext()) {
             DbJoin join = it.next();
@@ -244,9 +243,8 @@
         context.append(" WHERE");
 
         // TODO: andrus, 8/11/2007 flattened?
-        DbRelationship correlatedJoinRelationship = context
-                .getIncomingRelationships(id)
-                .get(0);
+        DbRelationship correlatedJoinRelationship = context.getIncomingRelationships(
+                new EJBQLTableId(id)).get(0);
 
         for (DbJoin join : correlatedJoinRelationship.getJoins()) {
             context.append(' ').append(subqueryRootAlias).append('.').append(

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLFromTranslator.java
Sat Jan  5 07:05:15 2008
@@ -59,7 +59,7 @@
         }
 
         this.lastId = id;
-        joinAppender.appendTable(id);
+        joinAppender.appendTable(new EJBQLTableId(id));
         return false;
     }
 
@@ -69,8 +69,10 @@
     }
 
     public boolean visitInnerJoin(EJBQLJoin join) {
-        joinAppender.appendInnerJoin(null, join.getLeftHandSideId(), join
-                .getRightHandSideId());
+        joinAppender.appendInnerJoin(
+                null,
+                new EJBQLTableId(join.getLeftHandSideId()),
+                new EJBQLTableId(join.getRightHandSideId()));
         return false;
     }
 
@@ -80,8 +82,10 @@
     }
 
     public boolean visitOuterJoin(EJBQLJoin join) {
-        joinAppender.appendOuterJoin(null, join.getLeftHandSideId(), join
-                .getRightHandSideId());
+        joinAppender.appendOuterJoin(
+                null,
+                new EJBQLTableId(join.getLeftHandSideId()),
+                new EJBQLTableId(join.getRightHandSideId()));
         return false;
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
Sat Jan  5 07:05:15 2008
@@ -68,7 +68,7 @@
 
                 EJBQLJoinAppender joinAppender = null;
                 String marker = null;
-                String lhsId = idVar;
+                EJBQLTableId lhsId = new EJBQLTableId(idVar);
 
                 while (dbPathIterator.hasNext()) {
                     Object pathPart = dbPathIterator.next();
@@ -89,7 +89,7 @@
 
                         DbRelationship dr = (DbRelationship) pathPart;
 
-                        String rhsId = lhsId + ".db:" + dr.getName();
+                        EJBQLTableId rhsId = new EJBQLTableId(lhsId, dr.getName());
                         joinAppender.appendOuterJoin(marker, lhsId, rhsId);
                         lhsId = rhsId;
                     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
Sat Jan  5 07:05:15 2008
@@ -26,7 +26,6 @@
 import org.apache.cayenne.ejbql.EJBQLException;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
  * Handles appending joins to the content buffer at a marked position.
@@ -75,15 +74,19 @@
         return null;
     }
 
-    public void appendInnerJoin(String marker, String lhsId, String rhsId) {
+    public void appendInnerJoin(String marker, EJBQLTableId lhsId, EJBQLTableId rhsId) {
         appendJoin(marker, lhsId, rhsId, "INNER JOIN");
     }
 
-    public void appendOuterJoin(String marker, String lhsId, String rhsId) {
+    public void appendOuterJoin(String marker, EJBQLTableId lhsId, EJBQLTableId rhsId) {
         appendJoin(marker, lhsId, rhsId, "LEFT OUTER JOIN");
     }
 
-    protected void appendJoin(String marker, String lhsId, String rhsId, String semantics)
{
+    protected void appendJoin(
+            String marker,
+            EJBQLTableId lhsId,
+            EJBQLTableId rhsId,
+            String semantics) {
 
         List<DbRelationship> joinRelationships = context.getIncomingRelationships(rhsId);
         if (joinRelationships.isEmpty()) {
@@ -93,7 +96,7 @@
         // TODO: andrus, 4/8/2007 - support for flattened relationships
         DbRelationship incomingDB = joinRelationships.get(0);
 
-        String sourceAlias = context.getTableAlias(lhsId, incomingDB
+        String sourceAlias = context.getTableAlias(lhsId.getEntityId(), incomingDB
                 .getSourceEntity()
                 .getName());
 
@@ -142,13 +145,14 @@
         }
     }
 
-    public String appendTable(String id) {
-        ClassDescriptor descriptor = context.getEntityDescriptor(id);
+    public String appendTable(EJBQLTableId id) {
 
-        String tableName = descriptor.getEntity().getDbEntity().getFullyQualifiedName();
+        String tableName = id.getDbEntity(context).getFullyQualifiedName();
 
         if (context.isUsingAliases()) {
-            String alias = context.getTableAlias(id, tableName);
+            // TODO: andrus 1/5/2007 - if the same table is joined more than once, this
+            // will create an incorrect alias.
+            String alias = context.getTableAlias(id.getEntityId(), tableName);
 
             // not using "AS" to separate table name and alias name - OpenBase doesn't
             // support

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
Sat Jan  5 07:05:15 2008
@@ -103,7 +103,7 @@
     }
 
     private void resolveJoin(boolean inner) {
-        
+
         EJBQLJoinAppender joinAppender = context.getTranslatorFactory().getJoinAppender(
                 context);
 
@@ -124,12 +124,18 @@
 
             // register join
             if (inner) {
-                joinAppender.appendInnerJoin(joinMarker, idPath, fullPath);
+                joinAppender.appendInnerJoin(
+                        joinMarker,
+                        new EJBQLTableId(idPath),
+                        new EJBQLTableId(fullPath));
                 this.lastAlias = context.getTableAlias(fullPath, currentEntity
                         .getDbEntityName());
             }
             else {
-                joinAppender.appendOuterJoin(joinMarker, idPath, fullPath);
+                joinAppender.appendOuterJoin(
+                        joinMarker,
+                        new EJBQLTableId(idPath),
+                        new EJBQLTableId(fullPath));
 
                 Relationship lastRelationship = currentEntity
                         .getRelationship(lastPathComponent);

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTableId.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTableId.java?rev=609146&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTableId.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTableId.java
Sat Jan  5 07:05:15 2008
@@ -0,0 +1,141 @@
+/*****************************************************************
+ *   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
+ *
+ *    http://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;
+
+import java.util.Iterator;
+
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.reflect.ClassDescriptor;
+import org.apache.cayenne.util.Util;
+
+/**
+ * A helper class representing an "id" of a database table during EJBQL translation. EJBQL
+ * "ids" point to ObjEntities, but during translation we need id's that represent both
+ * "root" tables that map back to an ObjEntity, as well as joined tables for flattened
+ * attributes and relationships. EJBQLTableId is intended to represent both types of
+ * tables.
+ * 
+ * @author Andrus Adamchik
+ * @since 3.0
+ */
+class EJBQLTableId {
+
+    private static String appendPath(EJBQLTableId baseId, String dbPathSuffix) {
+        if (baseId.getDbPath() == null) {
+            return dbPathSuffix;
+        }
+
+        if (dbPathSuffix == null) {
+            return baseId.getDbPath();
+        }
+
+        return baseId.getDbPath() + "." + dbPathSuffix;
+    }
+
+    private String entityId;
+    private String dbPath;
+
+    EJBQLTableId(String entityId) {
+        this(entityId, null);
+    }
+
+    EJBQLTableId(EJBQLTableId baseId, String dbPathSuffix) {
+        this(baseId.getEntityId(), appendPath(baseId, dbPathSuffix));
+    }
+
+    EJBQLTableId(String entityId, String dbPath) {
+
+        if (entityId == null) {
+            throw new NullPointerException("Null entityId");
+        }
+
+        this.entityId = entityId;
+        this.dbPath = dbPath;
+    }
+
+    /**
+     * Returns a DbEntity corresponding to the ID, that could be a root entity for the id,
+     * or a joined entity.
+     */
+    DbEntity getDbEntity(EJBQLTranslationContext context) {
+        ClassDescriptor descriptor = context.getEntityDescriptor(entityId);
+        DbEntity rootEntity = descriptor.getEntity().getDbEntity();
+
+        if (dbPath == null) {
+            return rootEntity;
+        }
+
+        DbRelationship r = null;
+        Iterator<?> it = rootEntity.resolvePathComponents(dbPath);
+        while (it.hasNext()) {
+            r = (DbRelationship) it.next();
+        }
+
+        return (DbEntity) r.getTargetEntity();
+    }
+
+    String getEntityId() {
+        return entityId;
+    }
+
+    String getDbPath() {
+        return dbPath;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = entityId.hashCode();
+
+        if (dbPath != null) {
+            hash += dbPath.hashCode() * 7;
+        }
+
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+
+        if (this == object) {
+            return true;
+        }
+
+        if (!(object instanceof EJBQLTableId)) {
+            return false;
+        }
+
+        EJBQLTableId id = (EJBQLTableId) object;
+
+        if (!Util.nullSafeEquals(entityId, id.entityId)) {
+            return false;
+        }
+
+        if (!Util.nullSafeEquals(dbPath, id.dbPath)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return dbPath != null ? entityId + "/" + dbPath : entityId;
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java?rev=609146&r1=609145&r2=609146&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
Sat Jan  5 07:05:15 2008
@@ -18,12 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.access.jdbc;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
 import org.apache.cayenne.ejbql.EJBQLException;
+import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.query.SQLResultSetMapping;
 import org.apache.cayenne.query.SQLTemplate;
@@ -97,8 +100,36 @@
         return compiledExpression.getEntityDescriptor(resolveId(id));
     }
 
-    List<DbRelationship> getIncomingRelationships(String id) {
-        return compiledExpression.getIncomingRelationships(resolveId(id));
+    List<DbRelationship> getIncomingRelationships(EJBQLTableId id) {
+
+        List<DbRelationship> incoming = compiledExpression
+                .getIncomingRelationships(resolveId(id.getEntityId()));
+
+        // append tail of flattened relationships...
+        if (id.getDbPath() != null) {
+
+            DbEntity entity;
+
+            if (incoming == null || incoming.isEmpty()) {
+                entity = compiledExpression
+                        .getEntityDescriptor(id.getEntityId())
+                        .getEntity()
+                        .getDbEntity();
+            }
+            else {
+                DbRelationship last = incoming.get(incoming.size() - 1);
+                entity = (DbEntity) last.getTargetEntity();
+            }
+
+            incoming = new ArrayList<DbRelationship>(incoming);
+
+            Iterator<?> it = entity.resolvePathComponents(id.getDbPath());
+            while (it.hasNext()) {
+                incoming.add((DbRelationship) it.next());
+            }
+        }
+
+        return incoming;
     }
 
     /**



Mime
View raw message