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/03/12 10:00:34 UTC
svn commit: r517136 [3/3] - in
/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src:
main/java/org/apache/cayenne/access/jdbc/ main/java/org/apache/cayenne/ejbql/
main/java/org/apache/cayenne/ejbql/parser/
main/java/org/apache/cayenne/query/ ma...
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLWhere.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLWhere.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLWhere.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLWhere.java Mon Mar 12 02:00:29 2007
@@ -18,12 +18,23 @@
****************************************************************/
package org.apache.cayenne.ejbql.parser;
+import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
+
/**
* @since 3.0
* @author Andrus Adamchik
*/
public class EJBQLWhere extends SimpleNode {
- public EJBQLWhere(int id) {
- super(id);
- }
+
+ public EJBQLWhere(int id) {
+ super(id);
+ }
+
+ EJBQLWhere(AbstractParser parser, int id) {
+ super(id);
+ }
+
+ protected boolean visitNode(EJBQLExpressionVisitor visitor) {
+ return visitor.visitWhere(this);
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/SimpleNode.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/SimpleNode.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/SimpleNode.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/SimpleNode.java Mon Mar 12 02:00:29 2007
@@ -42,7 +42,7 @@
public SimpleNode(int id) {
this.id = id;
}
-
+
public String getText() {
return text;
}
@@ -53,13 +53,13 @@
*/
public boolean visit(EJBQLExpressionVisitor visitor) {
- if (!nonRecursiveVisit(visitor)) {
+ if (!visitNode(visitor)) {
return false;
}
int len = getChildrenCount();
for (int i = 0; i < len; i++) {
- if (!children[i].visit(visitor)) {
+ if (!visitChild(visitor, i)) {
return false;
}
}
@@ -68,11 +68,19 @@
}
/**
- * A non-recursive version of accept method. Simply returns true. Subclasses normally
- * override this method instead of visit().
+ * Visits this not without recursion. Default implementation simply returns true.
+ * Subclasses override this method to call an appropriate visitor method.
*/
- protected boolean nonRecursiveVisit(EJBQLExpressionVisitor visitor) {
+ protected boolean visitNode(EJBQLExpressionVisitor visitor) {
return true;
+ }
+
+ /**
+ * Recursively visits a child at the specified index. Subclasses override this method
+ * if they desire to implement callbacks after visiting each child.
+ */
+ protected boolean visitChild(EJBQLExpressionVisitor visitor, int childIndex) {
+ return children[childIndex].visit(visitor);
}
public EJBQLExpression getChild(int index) {
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLConditionTranslator.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLConditionTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLConditionTranslator.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,73 @@
+/*****************************************************************
+ * 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.query;
+
+import org.apache.cayenne.ejbql.EJBQLDelegatingVisitor;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EJBQLConditionTranslator extends EJBQLDelegatingVisitor {
+
+ private EJBQLSelectTranslator parent;
+
+ EJBQLConditionTranslator(EJBQLSelectTranslator parent) {
+ this.parent = parent;
+ }
+
+ public boolean visitAnd(EJBQLExpression expression, int finishedChildIndex) {
+ if (finishedChildIndex >= 0) {
+ afterChild(expression, " AND", finishedChildIndex);
+ }
+
+ return true;
+ }
+
+ public boolean visitEquals(EJBQLExpression expression, int finishedChildIndex) {
+ if (finishedChildIndex >= 0) {
+ afterChild(expression, " =", finishedChildIndex);
+ }
+
+ return true;
+ }
+
+ public boolean visitOr(EJBQLExpression expression, int finishedChildIndex) {
+ if (finishedChildIndex >= 0) {
+ afterChild(expression, " OR", finishedChildIndex);
+ }
+
+ return true;
+ }
+
+ protected void afterChild(EJBQLExpression e, String text, int childIndex) {
+ if (childIndex + 1 < e.getChildrenCount()) {
+ parent.getParent().getBuffer().append(text);
+ }
+
+ // reset delegate if it was set for a child
+ setDelegate(null);
+ }
+
+ public boolean visitPath(EJBQLExpression expression) {
+ setDelegate(new EJBQLPathVisitor());
+ return true;
+ }
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLFromTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLFromTranslator.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLFromTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLFromTranslator.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,58 @@
+/*****************************************************************
+ * 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.query;
+
+import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.reflect.ClassDescriptor;
+
+public class EJBQLFromTranslator extends EJBQLBaseVisitor {
+
+ private EJBQLSelectTranslator parent;
+
+ public EJBQLFromTranslator(EJBQLSelectTranslator parent) {
+ super(false);
+ this.parent = parent;
+ }
+
+ public boolean visitFromItem(EJBQLExpression expression) {
+ return true;
+ }
+
+ public boolean visitAbstractSchemaName(EJBQLExpression expression) {
+ return true;
+ }
+
+ public boolean visitIdentificationVariable(EJBQLExpression expression) {
+ return true;
+ }
+
+ public boolean visitIdentifier(EJBQLExpression expression) {
+ String identifier = expression.getText();
+ ClassDescriptor descriptor = parent
+ .getParent()
+ .getCompiledExpression()
+ .getEntityDescriptor(identifier);
+
+ DbEntity table = descriptor.getEntity().getDbEntity();
+ parent.appendTable(identifier, table);
+ return true;
+ }
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLPathVisitor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLPathVisitor.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLPathVisitor.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLPathVisitor.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,30 @@
+/*****************************************************************
+ * 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.query;
+
+import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+
+class EJBQLPathVisitor extends EJBQLBaseVisitor {
+
+ EJBQLPathVisitor() {
+ super(true);
+ }
+
+
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLQuery.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLQuery.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLQuery.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLQuery.java Mon Mar 12 02:00:29 2007
@@ -18,8 +18,8 @@
****************************************************************/
package org.apache.cayenne.query;
+import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
import org.apache.cayenne.ejbql.EJBQLException;
-import org.apache.cayenne.ejbql.EJBQLExpression;
import org.apache.cayenne.ejbql.EJBQLParserFactory;
import org.apache.cayenne.map.EntityResolver;
@@ -29,37 +29,26 @@
* @since 3.0
* @author Andrus Adamchik
*/
-public class EJBQLQuery implements Query {
+public class EJBQLQuery extends IndirectQuery {
protected String ejbqlStatement;
- protected String name;
- private transient EJBQLExpression parsedRoot;
+ protected transient EJBQLCompiledExpression expression;
public EJBQLQuery(String ejbqlStatement) {
this.ejbqlStatement = ejbqlStatement;
}
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public SQLAction createSQLAction(SQLActionVisitor visitor) {
- // TODO Auto-generated method stub
- return null;
- }
+ /**
+ * Compiles EJBQL into a SQLTemplate query and returns this query.
+ */
+ protected Query createReplacementQuery(EntityResolver resolver) {
+ EJBQLCompiledExpression expression = getExpression(resolver);
- public QueryMetadata getMetaData(EntityResolver resolver) {
- // TODO Auto-generated method stub
- return null;
- }
+ EJBQLTranslator translator = new EJBQLTranslator(expression);
+ String sql = translator.translate();
- public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
- // TODO Auto-generated method stub
+ return new SQLTemplate(expression.getRootDescriptor().getObjectClass(), sql);
}
/**
@@ -70,13 +59,15 @@
}
/**
- * Returns lazily initialialized parsed root of this query.
+ * Returns lazily initialized EJBQLCompiledExpression for this query EJBQL.
*/
- Object getParsedRoot() throws EJBQLException {
- if (parsedRoot == null) {
- this.parsedRoot = EJBQLParserFactory.getParser().parse(ejbqlStatement);
+ EJBQLCompiledExpression getExpression(EntityResolver resolver) throws EJBQLException {
+ if (expression == null) {
+ this.expression = EJBQLParserFactory.getParser().compile(
+ ejbqlStatement,
+ resolver);
}
- return parsedRoot;
+ return expression;
}
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectColumnsTranslator.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectColumnsTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectColumnsTranslator.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,123 @@
+/*****************************************************************
+ * 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.query;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.reflect.ArcProperty;
+import org.apache.cayenne.reflect.AttributeProperty;
+import org.apache.cayenne.reflect.ClassDescriptor;
+import org.apache.cayenne.reflect.PropertyVisitor;
+import org.apache.cayenne.reflect.ToManyProperty;
+import org.apache.cayenne.reflect.ToOneProperty;
+
+/**
+ * Translator of the EJBQL select clause.
+ *
+ * @author Andrus Adamchik
+ * @since 3.0
+ */
+class EJBQLSelectColumnsTranslator extends EJBQLBaseVisitor {
+
+ private EJBQLSelectTranslator parent;
+
+ EJBQLSelectColumnsTranslator(EJBQLSelectTranslator parent) {
+ super(false);
+ this.parent = parent;
+ }
+
+ public boolean visitSelectExpression(EJBQLExpression expression) {
+ return true;
+ }
+
+ public boolean visitIdentifier(EJBQLExpression expression) {
+
+ final String idVar = expression.getText();
+
+ // append all table columns
+ ClassDescriptor descriptor = parent
+ .getParent()
+ .getCompiledExpression()
+ .getEntityDescriptor(idVar);
+
+ PropertyVisitor visitor = new PropertyVisitor() {
+
+ public boolean visitAttribute(AttributeProperty property) {
+ ObjAttribute oa = property.getAttribute();
+ Iterator dbPathIterator = oa.getDbPathIterator();
+ while (dbPathIterator.hasNext()) {
+ Object pathPart = dbPathIterator.next();
+ if (pathPart instanceof DbRelationship) {
+ // DbRelationship rel = (DbRelationship) pathPart;
+ // dbRelationshipAdded(rel);
+ }
+ else if (pathPart instanceof DbAttribute) {
+ DbAttribute dbAttr = (DbAttribute) pathPart;
+ if (dbAttr == null) {
+ throw new CayenneRuntimeException(
+ "ObjAttribute has no DbAttribute: " + oa.getName());
+ }
+
+ parent.appendColumn(idVar, dbAttr, oa.getType());
+ }
+ }
+ return true;
+ }
+
+ public boolean visitToMany(ToManyProperty property) {
+ visitRelationship(property);
+ return true;
+ }
+
+ public boolean visitToOne(ToOneProperty property) {
+ visitRelationship(property);
+ return true;
+ }
+
+ private void visitRelationship(ArcProperty property) {
+ ObjRelationship rel = property.getRelationship();
+ DbRelationship dbRel = (DbRelationship) rel.getDbRelationships().get(0);
+
+ List joins = dbRel.getJoins();
+ int len = joins.size();
+ for (int i = 0; i < len; i++) {
+ DbJoin join = (DbJoin) joins.get(i);
+ DbAttribute src = join.getSource();
+
+ parent.appendColumn(idVar, src);
+ }
+ }
+ };
+
+ // EJBQL queries are polimorphic by definition - there is no distinction between
+ // inheritance/no-inheritance fetch
+ descriptor.visitAllProperties(visitor);
+
+ return true;
+ }
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectOrderByTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectOrderByTranslator.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectOrderByTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectOrderByTranslator.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,35 @@
+/*****************************************************************
+ * 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.query;
+
+import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EJBQLSelectOrderByTranslator extends EJBQLBaseVisitor {
+
+ private EJBQLSelectTranslator parent;
+
+ EJBQLSelectOrderByTranslator(EJBQLSelectTranslator parent) {
+ super(false);
+ this.parent = parent;
+ }
+}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectTranslator.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLSelectTranslator.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,115 @@
+/*****************************************************************
+ * 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.query;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.ejbql.EJBQLDelegatingVisitor;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+/**
+ * A translator of EJBQL select statements into SQL.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EJBQLSelectTranslator extends EJBQLDelegatingVisitor {
+
+ private EJBQLTranslator parent;
+ private Set columns;
+
+ EJBQLSelectTranslator(EJBQLTranslator parent) {
+ this.parent = parent;
+ }
+
+ void appendTable(String identifier, DbEntity table) {
+ String fqn = table.getFullyQualifiedName();
+ String alias = parent.createAlias(identifier, fqn);
+ parent.getBuffer().append(' ').append(fqn).append(' ').append(alias);
+ }
+
+ void appendColumn(String identifier, DbAttribute column) {
+ appendColumn(identifier, column, TypesMapping.getJavaBySqlType(column.getType()));
+ }
+
+ void appendColumn(String identifier, DbAttribute column, String javaType) {
+ DbEntity table = (DbEntity) column.getEntity();
+ String alias = parent.createAlias(identifier, table.getFullyQualifiedName());
+ String columnName = alias + "." + column.getName();
+
+ if (columns == null) {
+ columns = new HashSet();
+ }
+
+ if (columns.add(columnName)) {
+ // using #result directive:
+ // 1. to ensure that DB default captalization rules won't lead to changing
+ // result columns capitalization, as #result() gives SQLTemplate a hint as to
+ // what name is expected by the caller.
+ // 2. to ensure proper type conversion
+ parent
+ .getBuffer()
+ .append(columns.size() > 1 ? ", " : " ")
+ .append("#result('")
+ .append(columnName)
+ .append("' '")
+ .append(javaType)
+ .append("' '")
+ .append(column.getName())
+ .append("')");
+ }
+ }
+
+ EJBQLTranslator getParent() {
+ return parent;
+ }
+
+ public boolean visitDistinct(EJBQLExpression expression) {
+ parent.getBuffer().append(" DISTINCT");
+ return true;
+ }
+
+ public boolean visitFrom(EJBQLExpression expression) {
+ parent.getBuffer().append(" FROM");
+ setDelegate(new EJBQLFromTranslator(this));
+ return true;
+ }
+
+ public boolean visitOrderBy(EJBQLExpression expression) {
+ parent.getBuffer().append(" ORDER BY");
+ setDelegate(new EJBQLSelectOrderByTranslator(this));
+ return true;
+ }
+
+ public boolean visitSelect(EJBQLExpression expression) {
+ parent.getBuffer().append("SELECT");
+ setDelegate(new EJBQLSelectColumnsTranslator(this));
+ return true;
+ }
+
+ public boolean visitWhere(EJBQLExpression expression) {
+ parent.getBuffer().append(" WHERE");
+ setDelegate(new EJBQLConditionTranslator(this));
+ return true;
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLTranslator.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/EJBQLTranslator.java Mon Mar 12 02:00:29 2007
@@ -18,34 +18,80 @@
****************************************************************/
package org.apache.cayenne.query;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
import org.apache.cayenne.ejbql.EJBQLExpression;
/**
- * A translator of {@link EJBQLExpression} into the database SQL.
+ * A translator of {@link EJBQLExpression} statements into the database SQL.
*
* @since 3.0
* @author Andrus Adamchik
*/
class EJBQLTranslator extends EJBQLBaseVisitor {
+ private Map aliases;
private StringBuffer buffer;
+ private EJBQLCompiledExpression compiledExpression;
- EJBQLTranslator() {
- this.buffer = new StringBuffer();
+ EJBQLTranslator(EJBQLCompiledExpression compiledExpression) {
+ super(false);
+ this.compiledExpression = compiledExpression;
}
- String getSql() {
+ String translate() {
+ this.buffer = new StringBuffer();
+ compiledExpression.getExpression().visit(this);
return buffer.length() > 0 ? buffer.toString() : null;
}
public boolean visitSelect(EJBQLExpression expression) {
- buffer.append("SELECT");
- return true;
+ EJBQLSelectTranslator visitor = new EJBQLSelectTranslator(this);
+ expression.visit(visitor);
+ return false;
+ }
+
+ public boolean visitDelete(EJBQLExpression expression) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean visitUpdate(EJBQLExpression expression) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ StringBuffer getBuffer() {
+ return buffer;
}
- public boolean visitFrom(EJBQLExpression expression) {
- buffer.append(" FROM");
- return true;
+ EJBQLCompiledExpression getCompiledExpression() {
+ return compiledExpression;
+ }
+
+ /**
+ * Retrieves a SQL alias for the combination of EJBQL id variable and a table name. If
+ * such alias hasn't been used, it is created on the fly.
+ */
+ String createAlias(String idVariable, String tableName) {
+ String key = idVariable + ":" + tableName;
+
+ String alias;
+
+ if (aliases != null) {
+ alias = (String) aliases.get(key);
+ }
+ else {
+ aliases = new HashMap();
+ alias = null;
+ }
+
+ if (alias == null) {
+ alias = "t" + aliases.size();
+ aliases.put(key, alias);
+ }
+
+ return alias;
}
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/ObjectIdQuery.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/ObjectIdQuery.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/ObjectIdQuery.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/ObjectIdQuery.java Mon Mar 12 02:00:29 2007
@@ -81,7 +81,7 @@
/**
* Returns query metadata object.
*/
- // return metadata without creating replacement, as this is not always possible to
+ // return metadata without creating replacement, as it is not always possible to
// create replacement (e.g. temp ObjectId).
public QueryMetadata getMetaData(final EntityResolver resolver) {
// caching metadata as it may be accessed multiple times (at a DC and DD level)
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/jjtree/org/apache/cayenne/ejbql/EJBQLParser.jjt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/jjtree/org/apache/cayenne/ejbql/EJBQLParser.jjt?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/jjtree/org/apache/cayenne/ejbql/EJBQLParser.jjt (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/jjtree/org/apache/cayenne/ejbql/EJBQLParser.jjt Mon Mar 12 02:00:29 2007
@@ -29,7 +29,7 @@
NODE_DEFAULT_VOID = true;
JAVA_UNICODE_ESCAPE = true;
STATIC = false;
- NODE_USES_PARSER = false;
+ NODE_USES_PARSER = true;
LOOKAHEAD = 1;
@@ -66,6 +66,7 @@
compiled.setExpression(parseQuery());
compiled.setDescriptorsById(descriptorsById);
compiled.setSource(source);
+ compiled.setRootId(rootId);
return compiled;
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLQueryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLQueryTest.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLQueryTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLQueryTest.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,45 @@
+/*****************************************************************
+ * 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;
+
+import java.util.List;
+
+import org.apache.art.Artist;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.unit.CayenneCase;
+
+public class DataContextEJBQLQueryTest extends CayenneCase {
+
+ protected void setUp() throws Exception {
+ deleteTestData();
+ }
+
+ public void testSimpleSelect() throws Exception {
+ createTestData("prepare");
+
+ String ejbql = "select a FROM Artist a";
+ EJBQLQuery query = new EJBQLQuery(ejbql);
+
+ List artists = createDataContext().performQuery(query);
+ assertEquals(4, artists.size());
+ assertTrue(artists.get(0) instanceof Artist);
+ assertTrue(((Artist) artists.get(0)).getPersistenceState() == PersistenceState.COMMITTED);
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java Mon Mar 12 02:00:29 2007
@@ -23,6 +23,24 @@
public class EJBQLCompiledExpressionTest extends CayenneCase {
+ public void testGetSource() {
+ String source = "select a from Artist a";
+ EntityResolver resolver = getDomain().getEntityResolver();
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+
+ EJBQLCompiledExpression select = parser.compile(source, resolver);
+ assertEquals(source, select.getSource());
+ }
+
+ public void testGetExpression() {
+ String source = "select a from Artist a";
+ EntityResolver resolver = getDomain().getEntityResolver();
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+
+ EJBQLCompiledExpression select = parser.compile(source, resolver);
+ assertNotNull(select.getExpression());
+ }
+
public void testGetEntityDescriptor() {
EntityResolver resolver = getDomain().getEntityResolver();
EJBQLParser parser = EJBQLParserFactory.getParser();
@@ -31,8 +49,20 @@
"select a from Artist a",
resolver);
- // assertNotNull(select.getEntityDescriptor("a"));
- // assertSame(resolver.getObjEntity("Artist"), select.getEntityDescriptor("a"));
+ assertNotNull(select.getEntityDescriptor("a"));
+ assertSame(resolver.getClassDescriptor("Artist"), select.getEntityDescriptor("a"));
+ }
+
+ public void testGetRootDescriptor() {
+ EntityResolver resolver = getDomain().getEntityResolver();
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+
+ EJBQLCompiledExpression select = parser.compile(
+ "select a from Artist a",
+ resolver);
+
+ assertSame("Root is not detected: " + select.getExpression(), resolver
+ .getClassDescriptor("Artist"), select.getRootDescriptor());
}
public void testGetEntityDescriptorCaseSensitivity() {
@@ -43,21 +73,21 @@
"select a from Artist a",
resolver);
- // assertNotNull(select1.getEntityDescriptor("a"));
- // assertNotNull(select1.getEntityDescriptor("A"));
+ assertNotNull(select1.getEntityDescriptor("a"));
+ assertNotNull(select1.getEntityDescriptor("A"));
EJBQLCompiledExpression select2 = parser.compile(
"select A from Artist A",
resolver);
- // assertNotNull(select2.getEntityDescriptor("a"));
- // assertNotNull(select2.getEntityDescriptor("A"));
+ assertNotNull(select2.getEntityDescriptor("a"));
+ assertNotNull(select2.getEntityDescriptor("A"));
EJBQLCompiledExpression select3 = parser.compile(
"select a from Artist A",
resolver);
- // assertNotNull(select3.getEntityDescriptor("a"));
- // assertNotNull(select3.getEntityDescriptor("A"));
+ assertNotNull(select3.getEntityDescriptor("a"));
+ assertNotNull(select3.getEntityDescriptor("A"));
}
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java Mon Mar 12 02:00:29 2007
@@ -0,0 +1,65 @@
+/*****************************************************************
+ * 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.query;
+
+import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.unit.CayenneCase;
+
+public class EJBQLQueryTest extends CayenneCase {
+
+ public void testGetExpression() {
+ String ejbql = "select a FROM Artist a";
+ EJBQLQuery query = new EJBQLQuery(ejbql);
+ EJBQLCompiledExpression parsed = query.getExpression(getDomain()
+ .getEntityResolver());
+ assertNotNull(parsed);
+ assertEquals(ejbql, parsed.getSource());
+ }
+
+ public void testGetName() {
+ String ejbql = "select a FROM Artist a";
+ EJBQLQuery query = new EJBQLQuery(ejbql);
+
+ assertNull(query.getName());
+ query.setName("XYZ");
+ assertEquals("XYZ", query.getName());
+ }
+
+ public void testGetMetadata() {
+
+ EntityResolver resolver = getDomain().getEntityResolver();
+ String ejbql = "select a FROM Artist a";
+ EJBQLQuery query = new EJBQLQuery(ejbql);
+ QueryMetadata md = query.getMetaData(resolver);
+
+ assertNotNull(md);
+
+ assertNotNull(md.getClassDescriptor());
+ assertSame(resolver.getClassDescriptor("Artist"), md.getClassDescriptor());
+
+ assertNotNull(md.getObjEntity());
+ assertSame(resolver.getObjEntity("Artist"), md.getObjEntity());
+
+ assertFalse(md.isFetchingDataRows());
+ assertTrue(md.isRefreshingObjects());
+ assertTrue(md.isResolvingInherited());
+ assertEquals(QueryMetadata.NO_CACHE, md.getCachePolicy());
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLTranslatorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLTranslatorTest.java?view=diff&rev=517136&r1=517135&r2=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLTranslatorTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/query/EJBQLTranslatorTest.java Mon Mar 12 02:00:29 2007
@@ -18,23 +18,94 @@
****************************************************************/
package org.apache.cayenne.query;
-import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.ejbql.EJBQLCompiledExpression;
import org.apache.cayenne.ejbql.EJBQLParser;
import org.apache.cayenne.ejbql.EJBQLParserFactory;
+import org.apache.cayenne.unit.CayenneCase;
-import junit.framework.TestCase;
+public class EJBQLTranslatorTest extends CayenneCase {
-public class EJBQLTranslatorTest extends TestCase {
+ public void testSelectFrom() {
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+ EJBQLCompiledExpression select = parser.compile(
+ "select a from Artist a",
+ getDomain().getEntityResolver());
+
+ EJBQLTranslator tr = new EJBQLTranslator(select);
+ String sql = tr.translate();
+
+ // System.out.println("Expression: " + select.getExpression());
+ // System.out.println("SQL: " + sql);
+
+ // column order is unpredictable, just need to ensure that they are all there
+ assertTrue(sql, sql.startsWith("SELECT "));
+ assertTrue(sql, sql.indexOf("t0.ARTIST_ID") > 0);
+ assertTrue(sql, sql.indexOf("t0.ARTIST_NAME") > 0);
+ assertTrue(sql, sql.indexOf("t0.DATE_OF_BIRTH") > 0);
+ assertTrue(sql, sql.endsWith(" FROM ARTIST t0"));
+ }
+
+ public void testSelectDistinct() {
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+ EJBQLCompiledExpression select = parser.compile(
+ "select distinct a from Artist a",
+ getDomain().getEntityResolver());
+
+ EJBQLTranslator tr = new EJBQLTranslator(select);
+ String sql = tr.translate();
+
+ // System.out.println("Expression: " + select.getExpression());
+ // System.out.println("SQL: " + sql);
+
+ assertTrue(sql, sql.startsWith("SELECT DISTINCT "));
+ assertTrue(sql, sql.endsWith(" FROM ARTIST t0"));
+ }
+
+ public void testSelectFromWhereEqual() {
+ EJBQLParser parser = EJBQLParserFactory.getParser();
+ EJBQLCompiledExpression select = parser.compile(
+ "select a from Artist a where a.artistName = 'Dali'",
+ getDomain().getEntityResolver());
+
+ EJBQLTranslator tr = new EJBQLTranslator(select);
+ String sql = tr.translate();
+
+ // System.out.println("Expression: " + select.getExpression());
+ // System.out.println("SQL: " + sql);
- public void testSelect1() {
+ assertTrue(sql, sql.startsWith("SELECT "));
+ // assertTrue(sql, sql.endsWith(" FROM ARTIST t0 WHERE t0.ARTIST_NAME = ?"));
+ }
+
+ public void testSelectFromWhereOrEqual() {
EJBQLParser parser = EJBQLParserFactory.getParser();
- EJBQLExpression select = parser.parse("select a from Artist a");
+ EJBQLCompiledExpression select = parser
+ .compile(
+ "select a from Artist a where a.artistName = 'Dali' or a.artistName = 'Malevich'",
+ getDomain().getEntityResolver());
+
+ EJBQLTranslator tr = new EJBQLTranslator(select);
+ String sql = tr.translate();
+
+ // System.out.println("Expression: " + select.getExpression());
+ // System.out.println("SQL: " + sql);
+
+ EJBQLCompiledExpression select1 = parser.compile(
+ "select a from Artist a where a.artistName = 'Dali' "
+ + "or a.artistName = 'Malevich' "
+ + "or a.artistName = 'Picasso'",
+ getDomain().getEntityResolver());
+
+ EJBQLTranslator tr1 = new EJBQLTranslator(select);
+ String sql1 = tr1.translate();
+
+ System.out.println("Expression: " + select1.getExpression());
+ System.out.println("SQL: " + sql1);
+
+ assertTrue(sql, sql.startsWith("SELECT "));
+ assertTrue(sql, sql.indexOf(" FROM ARTIST t0 WHERE ") > 0);
- EJBQLTranslator tr = new EJBQLTranslator();
- select.visit(tr);
-// assertEquals(
-// "Failed to translate: " + select,
-// "SELECT t0.ARTIST_ID, t0.ARTIST_NAME, t0.DATE_OF_BIRTH FROM ARTIST t0",
-// tr.getSql());
+ assertTrue(sql1, sql1.startsWith("SELECT "));
+ assertTrue(sql1, sql1.indexOf(" FROM ARTIST t0 WHERE ") > 0);
}
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLQueryTest.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLQueryTest.xml?view=auto&rev=517136
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLQueryTest.xml (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLQueryTest.xml Mon Mar 12 02:00:29 2007
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans default-lazy-init="true">
+ <!-- ======================================= -->
+ <!-- Named Queries -->
+ <!-- ======================================= -->
+
+ <!-- ARTIST -->
+ <bean id="A1" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+ <constructor-arg type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+ <constructor-arg><value>
+ insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33001, 'AA1')
+ </value></constructor-arg>
+ </bean>
+
+ <bean id="A2" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+ <constructor-arg type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+ <constructor-arg><value>
+ insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33002, 'AA2')
+ </value></constructor-arg>
+ </bean>
+
+ <bean id="A3" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+ <constructor-arg type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+ <constructor-arg><value>
+ insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33003, 'BB1')
+ </value></constructor-arg>
+ </bean>
+
+ <bean id="A4" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+ <constructor-arg type="java.lang.Class"><value>org.apache.art.Artist</value></constructor-arg>
+ <constructor-arg><value>
+ insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33004, 'BB2')
+ </value></constructor-arg>
+ </bean>
+
+
+
+ <!-- ======================================= -->
+ <!-- Data Sets -->
+ <!-- ======================================= -->
+
+ <bean id="prepare" class="java.util.ArrayList">
+ <constructor-arg>
+ <list>
+ <ref bean="A1"/>
+ <ref bean="A2"/>
+ <ref bean="A3"/>
+ <ref bean="A4"/>
+ </list>
+ </constructor-arg>
+ </bean>
+</beans>
\ No newline at end of file