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 2007/12/27 12:12:03 UTC
svn commit: r607039 - in
/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src:
main/java/org/apache/cayenne/access/jdbc/
test/java/org/apache/cayenne/access/
Author: aadamchik
Date: Thu Dec 27 03:12:03 2007
New Revision: 607039
URL: http://svn.apache.org/viewvc?rev=607039&view=rev
Log:
CAY-948 Implement flattened attributes in Cayenne
(preliminary refactoring EJBQL translator)
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
Modified:
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/EJBQLPathTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslatorFactory.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JdbcEJBQLTranslatorFactory.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesTest.java
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=607039&r1=607038&r2=607039&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 Thu Dec 27 03:12:03 2007
@@ -18,17 +18,10 @@
****************************************************************/
package org.apache.cayenne.access.jdbc;
-import java.util.Iterator;
-
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
-import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLExpression;
import org.apache.cayenne.ejbql.parser.EJBQLFromItem;
import org.apache.cayenne.ejbql.parser.EJBQLJoin;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.reflect.ClassDescriptor;
/**
* @since 3.0
@@ -38,20 +31,18 @@
protected EJBQLTranslationContext context;
private String lastId;
-
- static String makeJoinTailMarker(String id) {
- return "FROM_TAIL" + id;
- }
+ private EJBQLJoinAppender joinAppender;
public EJBQLFromTranslator(EJBQLTranslationContext context) {
super(true);
this.context = context;
+ this.joinAppender = context.getTranslatorFactory().getJoinAppender(context);
}
public boolean visitFrom(EJBQLExpression expression, int finishedChildIndex) {
if (finishedChildIndex + 1 == expression.getChildrenCount()) {
if (lastId != null) {
- context.markCurrentPosition(makeJoinTailMarker(lastId));
+ context.markCurrentPosition(EJBQLJoinAppender.makeJoinTailMarker(lastId));
}
}
@@ -64,11 +55,11 @@
if (lastId != null) {
context.append(',');
- context.markCurrentPosition(makeJoinTailMarker(lastId));
+ context.markCurrentPosition(EJBQLJoinAppender.makeJoinTailMarker(lastId));
}
this.lastId = id;
- appendTable(id);
+ joinAppender.appendTable(id);
return false;
}
@@ -78,7 +69,8 @@
}
public boolean visitInnerJoin(EJBQLJoin join) {
- appendJoin(join, "INNER JOIN");
+ joinAppender.appendInnerJoin(null, join.getLeftHandSideId(), join
+ .getRightHandSideId());
return false;
}
@@ -88,77 +80,8 @@
}
public boolean visitOuterJoin(EJBQLJoin join) {
- appendJoin(join, "LEFT OUTER JOIN");
+ joinAppender.appendOuterJoin(null, join.getLeftHandSideId(), join
+ .getRightHandSideId());
return false;
- }
-
- private void appendJoin(EJBQLJoin join, String semantics) {
-
- String rhsId = join.getRightHandSideId();
-
- ObjRelationship joinRelationship = context.getIncomingRelationship(rhsId);
- if (joinRelationship == null) {
- throw new EJBQLException("No join configured for id " + rhsId);
- }
-
- // TODO: andrus, 4/8/2007 - support for flattened relationships
- DbRelationship incomingDB = joinRelationship.getDbRelationships().get(0);
-
- String lhsId = join.getLeftHandSideId();
- String sourceAlias = context.getTableAlias(lhsId, incomingDB
- .getSourceEntity()
- .getName());
-
- context.append(" ").append(semantics);
- String targetAlias = appendTable(rhsId);
- context.append(" ON (");
-
- Iterator<DbJoin> it = incomingDB.getJoins().iterator();
- if (it.hasNext()) {
- DbJoin dbJoin = it.next();
- context
- .append(sourceAlias)
- .append('.')
- .append(dbJoin.getSourceName())
- .append(" = ")
- .append(targetAlias)
- .append('.')
- .append(dbJoin.getTargetName());
- }
-
- while (it.hasNext()) {
- context.append(", ");
- DbJoin dbJoin = it.next();
- context
- .append(sourceAlias)
- .append('.')
- .append(dbJoin.getSourceName())
- .append(" = ")
- .append(targetAlias)
- .append('.')
- .append(dbJoin.getTargetName());
- }
-
- context.append(")");
- }
-
- protected String appendTable(String id) {
- ClassDescriptor descriptor = context.getEntityDescriptor(id);
-
- String tableName = descriptor.getEntity().getDbEntity().getFullyQualifiedName();
-
- if (context.isUsingAliases()) {
- String alias = context.getTableAlias(id, tableName);
-
- // not using "AS" to separate table name and alias name - OpenBase doesn't
- // support
- // "AS", and the rest of the databases do not care
- context.append(' ').append(tableName).append(' ').append(alias);
- return alias;
- }
- else {
- context.append(' ').append(tableName);
- return tableName;
- }
}
}
Added: 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=607039&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java Thu Dec 27 03:12:03 2007
@@ -0,0 +1,133 @@
+/*****************************************************************
+ * 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.ejbql.EJBQLException;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.reflect.ClassDescriptor;
+
+/**
+ * Handles appending joins to the content buffer at a marked position.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class EJBQLJoinAppender {
+
+ protected EJBQLTranslationContext context;
+
+ public EJBQLJoinAppender(EJBQLTranslationContext context) {
+ this.context = context;
+ }
+
+ public void appendInnerJoin(String marker, String lhsId, String rhsId) {
+ appendJoin(marker, lhsId, rhsId, "INNER JOIN");
+ }
+
+ public void appendOuterJoin(String marker, String lhsId, String rhsId) {
+ appendJoin(marker, lhsId, rhsId, "LEFT OUTER JOIN");
+ }
+
+ protected void appendJoin(String marker, String lhsId, String rhsId, String semantics) {
+
+ ObjRelationship joinRelationship = context.getIncomingRelationship(rhsId);
+ if (joinRelationship == null) {
+ throw new EJBQLException("No join configured for id " + rhsId);
+ }
+
+ // TODO: andrus, 4/8/2007 - support for flattened relationships
+ DbRelationship incomingDB = joinRelationship.getDbRelationships().get(0);
+
+ String sourceAlias = context.getTableAlias(lhsId, incomingDB
+ .getSourceEntity()
+ .getName());
+
+ if (marker != null) {
+ context.switchToMarker(marker, false);
+ }
+
+ try {
+
+ context.append(" ").append(semantics);
+ String targetAlias = appendTable(rhsId);
+ context.append(" ON (");
+
+ Iterator<DbJoin> it = incomingDB.getJoins().iterator();
+ if (it.hasNext()) {
+ DbJoin dbJoin = it.next();
+ context
+ .append(sourceAlias)
+ .append('.')
+ .append(dbJoin.getSourceName())
+ .append(" = ")
+ .append(targetAlias)
+ .append('.')
+ .append(dbJoin.getTargetName());
+ }
+
+ while (it.hasNext()) {
+ context.append(", ");
+ DbJoin dbJoin = it.next();
+ context
+ .append(sourceAlias)
+ .append('.')
+ .append(dbJoin.getSourceName())
+ .append(" = ")
+ .append(targetAlias)
+ .append('.')
+ .append(dbJoin.getTargetName());
+ }
+
+ context.append(")");
+ }
+ finally {
+ if (marker != null) {
+ context.switchToMainBuffer();
+ }
+ }
+ }
+
+ public String appendTable(String id) {
+ ClassDescriptor descriptor = context.getEntityDescriptor(id);
+
+ String tableName = descriptor.getEntity().getDbEntity().getFullyQualifiedName();
+
+ if (context.isUsingAliases()) {
+ String alias = context.getTableAlias(id, tableName);
+
+ // not using "AS" to separate table name and alias name - OpenBase doesn't
+ // support
+ // "AS", and the rest of the databases do not care
+ context.append(' ').append(tableName).append(' ').append(alias);
+ return alias;
+ }
+ else {
+ context.append(' ').append(tableName);
+ return tableName;
+ }
+ }
+
+ static String makeJoinTailMarker(String id) {
+ return "FROM_TAIL" + id;
+ }
+}
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=607039&r1=607038&r2=607039&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 Thu Dec 27 03:12:03 2007
@@ -26,13 +26,6 @@
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLExpression;
-import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
-import org.apache.cayenne.ejbql.parser.EJBQLIdentificationVariable;
-import org.apache.cayenne.ejbql.parser.EJBQLIdentifier;
-import org.apache.cayenne.ejbql.parser.EJBQLInnerJoin;
-import org.apache.cayenne.ejbql.parser.EJBQLJoin;
-import org.apache.cayenne.ejbql.parser.EJBQLOuterJoin;
-import org.apache.cayenne.ejbql.parser.EJBQLPath;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
@@ -58,7 +51,6 @@
protected String idPath;
protected String joinMarker;
private String fullPath;
- private EJBQLExpressionVisitor joinAppender;
private boolean usingAliases;
public EJBQLPathTranslator(EJBQLTranslationContext context) {
@@ -93,7 +85,7 @@
this.currentEntity = descriptor.getEntity();
this.idPath = expression.getText();
- this.joinMarker = EJBQLFromTranslator.makeJoinTailMarker(idPath);
+ this.joinMarker = EJBQLJoinAppender.makeJoinTailMarker(idPath);
this.fullPath = idPath;
return true;
}
@@ -110,14 +102,6 @@
return true;
}
- private EJBQLExpressionVisitor getJoinAppender() {
- if (joinAppender == null) {
- joinAppender = context.getTranslatorFactory().getFromTranslator(context);
- }
-
- return joinAppender;
- }
-
private void resolveJoin(boolean inner) {
String newPath = idPath + '.' + lastPathComponent;
@@ -131,36 +115,19 @@
.getDbEntityName());
}
else {
- // register join
- EJBQLIdentifier id = new EJBQLIdentifier(-1);
- id.setText(idPath);
-
- EJBQLIdentificationVariable idVar = new EJBQLIdentificationVariable(-1);
- idVar.setText(lastPathComponent);
- EJBQLPath path = new EJBQLPath(-1);
- path.jjtAddChild(id, 0);
- path.jjtAddChild(idVar, 1);
-
- EJBQLIdentifier joinId = new EJBQLIdentifier(-1);
- joinId.setText(fullPath);
-
- context.switchToMarker(joinMarker, false);
+ EJBQLJoinAppender joinAppender = context
+ .getTranslatorFactory()
+ .getJoinAppender(context);
+ // register join
if (inner) {
- EJBQLJoin join = new EJBQLInnerJoin(-1);
- join.jjtAddChild(path, 0);
- join.jjtAddChild(joinId, 1);
- getJoinAppender().visitInnerJoin(join);
-
+ joinAppender.appendInnerJoin(joinMarker, idPath, fullPath);
this.lastAlias = context.getTableAlias(fullPath, currentEntity
.getDbEntityName());
}
else {
- EJBQLJoin join = new EJBQLOuterJoin(-1);
- join.jjtAddChild(path, 0);
- join.jjtAddChild(joinId, 1);
- getJoinAppender().visitOuterJoin(join);
+ joinAppender.appendOuterJoin(joinMarker, idPath, fullPath);
Relationship lastRelationship = currentEntity
.getRelationship(lastPathComponent);
@@ -170,10 +137,7 @@
.getDbEntityName());
}
- context.switchToMainBuffer();
-
this.idPath = newPath;
-
}
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslatorFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslatorFactory.java?rev=607039&r1=607038&r2=607039&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslatorFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslatorFactory.java Thu Dec 27 03:12:03 2007
@@ -28,6 +28,8 @@
* @author Andrus Adamchik
*/
public interface EJBQLTranslatorFactory {
+
+ EJBQLJoinAppender getJoinAppender(EJBQLTranslationContext context);
EJBQLExpressionVisitor getSelectTranslator(EJBQLTranslationContext context);
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JdbcEJBQLTranslatorFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JdbcEJBQLTranslatorFactory.java?rev=607039&r1=607038&r2=607039&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JdbcEJBQLTranslatorFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JdbcEJBQLTranslatorFactory.java Thu Dec 27 03:12:03 2007
@@ -28,6 +28,20 @@
*/
public class JdbcEJBQLTranslatorFactory implements EJBQLTranslatorFactory {
+ protected static final String JOIN_APPENDER_KEY = "$JoinAppender";
+
+ public EJBQLJoinAppender getJoinAppender(EJBQLTranslationContext context) {
+ EJBQLJoinAppender appender = (EJBQLJoinAppender) context
+ .getAttribute(JOIN_APPENDER_KEY);
+
+ if (appender == null) {
+ appender = new EJBQLJoinAppender(context);
+ context.setAttribute(JOIN_APPENDER_KEY, appender);
+ }
+
+ return appender;
+ }
+
public EJBQLExpressionVisitor getDeleteTranslator(EJBQLTranslationContext context) {
context.setUsingAliases(false);
return new EJBQLDeleteTranslator(context);
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesTest.java?rev=607039&r1=607038&r2=607039&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesTest.java Thu Dec 27 03:12:03 2007
@@ -179,6 +179,41 @@
painting.getGalleryName());
}
}
+
+ public void testSelectEJQBQL() throws Exception {
+// populateTables();
+// EJBQLQuery query = new EJBQLQuery("SELECT a FROM CompoundPainting a WHERE a.artistName = 'artist2'");
+// List<?> objects = context.performQuery(query);
+//
+// assertNotNull(objects);
+// assertEquals(1, objects.size());
+// assertTrue("CompoundPainting expected, got " + objects.get(0).getClass(), objects
+// .get(0) instanceof CompoundPainting);
+//
+// for (Iterator<?> i = objects.iterator(); i.hasNext();) {
+// CompoundPainting painting = (CompoundPainting) i.next();
+// Number id = (Number) painting
+// .getObjectId()
+// .getIdSnapshot()
+// .get("PAINTING_ID");
+// assertEquals("CompoundPainting.getObjectId(): " + id, id.intValue(), 2);
+// assertEquals("CompoundPainting.getPaintingTitle(): "
+// + painting.getPaintingTitle(), "painting" + id, painting
+// .getPaintingTitle());
+// assertEquals(
+// "CompoundPainting.getTextReview(): " + painting.getTextReview(),
+// "painting review" + id,
+// painting.getTextReview());
+// assertEquals(
+// "CompoundPainting.getArtistName(): " + painting.getArtistName(),
+// "artist2",
+// painting.getArtistName());
+// assertEquals(
+// "CompoundPainting.getArtistName(): " + painting.getGalleryName(),
+// painting.getToGallery().getGalleryName(),
+// painting.getGalleryName());
+// }
+ }
public void testInsert() {
CompoundPainting o1 = context.newObject(CompoundPainting.class);