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/08/01 21:42:46 UTC
svn commit: r561931 - in
/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc:
EJBQLConditionTranslator.java EJBQLUpdateFieldTranslator.java
EJBQLUpdateTranslator.java
Author: aadamchik
Date: Wed Aug 1 12:42:44 2007
New Revision: 561931
URL: http://svn.apache.org/viewvc?view=rev&rev=561931
Log:
CAY-837 EJBQL Update Statement Support
(translator refactoring to reuse Condition translator or UpdateField which is semantically very close)
Added:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateFieldTranslator.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateTranslator.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?view=diff&rev=561931&r1=561930&r2=561931
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java Wed Aug 1 12:42:44 2007
@@ -37,7 +37,7 @@
*/
class EJBQLConditionTranslator extends EJBQLBaseVisitor {
- private EJBQLTranslationContext context;
+ protected EJBQLTranslationContext context;
private List multiColumnOperands;
Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateFieldTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateFieldTranslator.java?view=auto&rev=561931
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateFieldTranslator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateFieldTranslator.java Wed Aug 1 12:42:44 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.access.jdbc;
+
+import org.apache.cayenne.ejbql.EJBQLException;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class EJBQLUpdateFieldTranslator extends EJBQLConditionTranslator {
+
+ public EJBQLUpdateFieldTranslator(EJBQLTranslationContext context) {
+ super(context);
+ }
+
+ public boolean visitUpdateField(EJBQLExpression expression, int finishedChildIndex) {
+
+ EJBQLPathTranslator pathTranslator = new EJBQLPathTranslator(context) {
+
+ protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
+ throw new EJBQLException(
+ "Multi-column paths are not yet supported in UPDATEs");
+ }
+
+ public boolean visitUpdateField(
+ EJBQLExpression expression,
+ int finishedChildIndex) {
+ return visitPath(expression, finishedChildIndex);
+ }
+ };
+
+ expression.visit(pathTranslator);
+ return false;
+ }
+
+ public boolean visitUpdateValue(EJBQLExpression expression) {
+ context.append(" =");
+ return true;
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateTranslator.java?view=diff&rev=561931&r1=561930&r2=561931
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLUpdateTranslator.java Wed Aug 1 12:42:44 2007
@@ -18,15 +18,8 @@
****************************************************************/
package org.apache.cayenne.access.jdbc;
-import java.math.BigDecimal;
-import java.util.Map;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
-import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLExpression;
-import org.apache.cayenne.ejbql.parser.EJBQLPositionalInputParameter;
/**
* A translator of EJBQL UPDATE statements into SQL.
@@ -72,155 +65,7 @@
context.append(" SET");
}
- return true;
- }
-
- public boolean visitUpdateField(EJBQLExpression expression, int finishedChildIndex) {
-
- EJBQLPathTranslator pathTranslator = new EJBQLPathTranslator(context) {
-
- protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
- throw new EJBQLException(
- "Multi-column paths are not yet supported in UPDATEs");
- }
-
- public boolean visitUpdateField(
- EJBQLExpression expression,
- int finishedChildIndex) {
- return visitPath(expression, finishedChildIndex);
- }
- };
-
- expression.visit(pathTranslator);
+ expression.visit(new EJBQLUpdateFieldTranslator(context));
return false;
- }
-
- public boolean visitUpdateValue(EJBQLExpression expression) {
- context.append(" =");
- return true;
- }
-
- // TODO: andrus, 7/31/2007 - all literal processing (visitStringLiteral,
- // visitIntegerLiteral, visitDecimalLiteral, visitBooleanLiteral,
- // visitPositionalInputParameter, visitnamedInputParameter) is duplicated in
- // EJBQLConditionalTranslator - may need to refactor
- // one current difference is support of multi-column matching by
- // EJBQLConditionalTranslator/
- public boolean visitStringLiteral(EJBQLExpression expression) {
- if (expression.getText() == null) {
- context.append("null");
- }
- else {
- // note that String Literal text is already wrapped in single quotes, with
- // quotes that are part of the string escaped.
- context.append(" #bind(").append(expression.getText()).append(" 'VARCHAR')");
- }
-
- return true;
- }
-
- public boolean visitBooleanLiteral(EJBQLExpression expression) {
- if (expression.getText() == null) {
- context.append("null");
- }
- else {
- Object value = new Boolean(expression.getText());
- String var = context.bindParameter(value);
- context.append(" #bind($").append(var).append(" 'BOOLEAN')");
- }
-
- return true;
- }
-
- public boolean visitIntegerLiteral(EJBQLExpression expression) {
- if (expression.getText() == null) {
- context.append("null");
- }
- else {
- Object value;
-
- try {
- value = new Integer(expression.getText());
- }
- catch (NumberFormatException nfex) {
- throw new EJBQLException("Invalid integer: " + expression.getText());
- }
-
- String var = context.bindParameter(value);
- context.append(" #bind($").append(var).append(" 'INTEGER')");
- }
- return true;
- }
-
- public boolean visitDecimalLiteral(EJBQLExpression expression) {
- if (expression.getText() == null) {
- context.append("null");
- }
- else {
- Object value;
-
- try {
- value = new BigDecimal(expression.getText());
- }
- catch (NumberFormatException nfex) {
- throw new EJBQLException("Invalid decimal: " + expression.getText());
- }
-
- String var = context.bindParameter(value);
- context.append(" #bind($").append(var).append(" 'DECIMAL')");
- }
- return true;
- }
-
- public boolean visitPositionalInputParameter(EJBQLPositionalInputParameter expression) {
-
- String parameter = context.bindPositionalParameter(expression.getPosition());
- processParameter(parameter);
- return true;
- }
-
- public boolean visitNamedInputParameter(EJBQLExpression expression) {
- String parameter = context.bindNamedParameter(expression.getText());
- processParameter(parameter);
- return true;
- }
-
- private void processParameter(String boundName) {
- Object object = context.getBoundParameter(boundName);
-
- Map map = null;
- if (object instanceof Persistent) {
- map = ((Persistent) object).getObjectId().getIdSnapshot();
- }
- else if (object instanceof ObjectId) {
- map = ((ObjectId) object).getIdSnapshot();
- }
- else if (object instanceof Map) {
- map = (Map) object;
- }
-
- if (map != null) {
- if (map.size() == 1) {
- context.rebindParameter(boundName, map.values().iterator().next());
- }
- else {
- throw new EJBQLException(
- "Multi-column paths are not yet supported in UPDATEs");
- }
- }
-
- if (object != null) {
- context.append(" #bind($").append(boundName).append(")");
- }
- else {
- // this is a hack to prevent execptions on DB's like Derby for expressions
- // "X = NULL". The 'VARCHAR' parameter is totally bogus, but seems to work on
- // all tested DB's... Also note what JPA spec, chapter 4.11 says: "Comparison
- // or arithmetic operations with a NULL value always yield an unknown value."
-
- // TODO: andrus 6/28/2007 Ideally we should track the type of the current
- // expression to provide a meaningful type.
- context.append(" #bind($").append(boundName).append(" 'VARCHAR')");
- }
}
}