Author: aadamchik
Date: Thu Aug 16 05:41:23 2007
New Revision: 566685
URL: http://svn.apache.org/viewvc?view=rev&rev=566685
Log:
CAY-846 EJBQL Support for Functional Expressions
(mysql trim)
Added:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLConditionTranslator.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/EJBQLTranslationContext.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLTranslatorFactory.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/AccessStackAdapter.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/MySQLStackAdapter.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=566685&r1=566684&r2=566685
==============================================================================
---
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
Thu Aug 16 05:41:23 2007
@@ -48,12 +48,12 @@
* @since 3.0
* @author Andrus Adamchik
*/
-class EJBQLConditionTranslator extends EJBQLBaseVisitor {
+public class EJBQLConditionTranslator extends EJBQLBaseVisitor {
protected EJBQLTranslationContext context;
protected List multiColumnOperands;
- EJBQLConditionTranslator(EJBQLTranslationContext context) {
+ public EJBQLConditionTranslator(EJBQLTranslationContext context) {
this.context = context;
}
@@ -66,7 +66,8 @@
}
public boolean visitAggregate(EJBQLExpression expression) {
-
expression.visit(context.getTranslatorFactory().getAggregateColumnTranslator(context));
+
expression.visit(context.getTranslatorFactory().getAggregateColumnTranslator(
+ context));
return false;
}
@@ -782,7 +783,13 @@
public boolean visitTrimCharacter(EJBQLExpression expression) {
// this is expected to be overwritten in adapter-specific translators
- throw new UnsupportedOperationException("Not implemented in a generic
translator");
+ if (!"' '".equals(expression.getText())) {
+ throw new UnsupportedOperationException(
+ "TRIM character other than space is not supported by a
generic adapter: "
+ + expression.getText());
+ }
+
+ return false;
}
public boolean visitTrimLeading(EJBQLExpression expression) {
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java?view=diff&rev=566685&r1=566684&r2=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
Thu Aug 16 05:41:23 2007
@@ -210,7 +210,7 @@
/**
* Appends a piece of SQL to the internal buffer.
*/
- EJBQLTranslationContext append(String chunk) {
+ public EJBQLTranslationContext append(String chunk) {
currentBuffer.append(chunk);
return this;
}
@@ -218,7 +218,7 @@
/**
* Appends a piece of SQL to the internal buffer.
*/
- EJBQLTranslationContext append(char chunk) {
+ public EJBQLTranslationContext append(char chunk) {
currentBuffer.append(chunk);
return this;
}
Added:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLConditionTranslator.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLConditionTranslator.java?view=auto&rev=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLConditionTranslator.java
(added)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLConditionTranslator.java
Thu Aug 16 05:41:23 2007
@@ -0,0 +1,70 @@
+/*****************************************************************
+ * 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.dba.mysql;
+
+import org.apache.cayenne.access.jdbc.EJBQLConditionTranslator;
+import org.apache.cayenne.access.jdbc.EJBQLTranslationContext;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+
+/**
+ * Customizes EJBQL conditions translation for MySQL.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class MySQLEJBQLConditionTranslator extends EJBQLConditionTranslator {
+
+ MySQLEJBQLConditionTranslator(EJBQLTranslationContext context) {
+ super(context);
+ }
+
+ public boolean visitTrim(EJBQLExpression expression, int
finishedChildIndex) {
+ if (finishedChildIndex < 0) {
+ context.append(" TRIM(");
+ }
+ else if (finishedChildIndex + 2 == expression.getChildrenCount()) {
+ context.append(" FROM");
+ }
+ else if (finishedChildIndex + 1 == expression.getChildrenCount()) {
+ context.append(")");
+ }
+
+ return true;
+ }
+
+ public boolean visitTrimCharacter(EJBQLExpression expression) {
+ context.append(' ').append(expression.getText());
+ return false;
+ }
+
+ public boolean visitTrimLeading(EJBQLExpression expression) {
+ context.append("LEADING");
+ return false;
+ }
+
+ public boolean visitTrimTrailing(EJBQLExpression expression) {
+ context.append("TRAILING");
+ return false;
+ }
+
+ public boolean visitTrimBoth(EJBQLExpression expression) {
+ context.append("BOTH");
+ return false;
+ }
+}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLTranslatorFactory.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLTranslatorFactory.java?view=diff&rev=566685&r1=566684&r2=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLTranslatorFactory.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLEJBQLTranslatorFactory.java
Thu Aug 16 05:41:23 2007
@@ -18,7 +18,9 @@
****************************************************************/
package org.apache.cayenne.dba.mysql;
+import org.apache.cayenne.access.jdbc.EJBQLTranslationContext;
import org.apache.cayenne.access.jdbc.JdbcEJBQLTranslatorFactory;
+import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
/**
* @since 3.0
@@ -26,5 +28,7 @@
*/
class MySQLEJBQLTranslatorFactory extends JdbcEJBQLTranslatorFactory {
- // TODO: andrus 8/13/2007 - implement TRIM CHAR translation
+ public EJBQLExpressionVisitor
getConditionTranslator(EJBQLTranslationContext context) {
+ return new MySQLEJBQLConditionTranslator(context);
+ }
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java?view=diff&rev=566685&r1=566684&r2=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
Thu Aug 16 05:41:23 2007
@@ -365,40 +365,45 @@
}
- // public void testTRIMChar() {
- // ObjectContext context = createDataContext();
- //
- // Artist a1 = (Artist) context.newObject(Artist.class);
- // a1.setArtistName("XXXA");
- //
- // Artist a2 = (Artist) context.newObject(Artist.class);
- // a2.setArtistName("AXXX");
- // context.commitChanges();
- //
- // EJBQLQuery query = new EJBQLQuery(
- // "SELECT a FROM Artist a WHERE TRIM('X' FROM a.artistName) = 'A'");
- // List objects = context.performQuery(query);
- // assertEquals(2, objects.size());
- // assertTrue(objects.contains(a1));
- // assertTrue(objects.contains(a2));
- //
- // query = new EJBQLQuery(
- // "SELECT a FROM Artist a WHERE TRIM(LEADING 'X' FROM a.artistName) =
'A'");
- // objects = context.performQuery(query);
- // assertEquals(1, objects.size());
- // assertTrue(objects.contains(a1));
- //
- // query = new EJBQLQuery(
- // "SELECT a FROM Artist a WHERE TRIM(TRAILING 'X' FROM a.artistName) =
'A'");
- // objects = context.performQuery(query);
- // assertEquals(1, objects.size());
- // assertTrue(objects.contains(a2));
- //
- // query = new EJBQLQuery(
- // "SELECT a FROM Artist a WHERE TRIM(BOTH 'X' FROM a.artistName) = 'A'");
- // objects = context.performQuery(query);
- // assertEquals(2, objects.size());
- // assertTrue(objects.contains(a1));
- // assertTrue(objects.contains(a2));
- // }
+ public void testTRIMChar() {
+
+ if (!getAccessStackAdapter().supportsTrimChar()) {
+ return;
+ }
+
+ ObjectContext context = createDataContext();
+
+ Artist a1 = (Artist) context.newObject(Artist.class);
+ a1.setArtistName("XXXA");
+
+ Artist a2 = (Artist) context.newObject(Artist.class);
+ a2.setArtistName("AXXX");
+ context.commitChanges();
+
+ EJBQLQuery query = new EJBQLQuery(
+ "SELECT a FROM Artist a WHERE TRIM('X' FROM a.artistName) =
'A'");
+ List objects = context.performQuery(query);
+ assertEquals(2, objects.size());
+ assertTrue(objects.contains(a1));
+ assertTrue(objects.contains(a2));
+
+ query = new EJBQLQuery(
+ "SELECT a FROM Artist a WHERE TRIM(LEADING 'X' FROM
a.artistName) = 'A'");
+ objects = context.performQuery(query);
+ assertEquals(1, objects.size());
+ assertTrue(objects.contains(a1));
+
+ query = new EJBQLQuery(
+ "SELECT a FROM Artist a WHERE TRIM(TRAILING 'X' FROM
a.artistName) = 'A'");
+ objects = context.performQuery(query);
+ assertEquals(1, objects.size());
+ assertTrue(objects.contains(a2));
+
+ query = new EJBQLQuery(
+ "SELECT a FROM Artist a WHERE TRIM(BOTH 'X' FROM a.artistName)
= 'A'");
+ objects = context.performQuery(query);
+ assertEquals(2, objects.size());
+ assertTrue(objects.contains(a1));
+ assertTrue(objects.contains(a2));
+ }
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/AccessStackAdapter.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/AccessStackAdapter.java?view=diff&rev=566685&r1=566684&r2=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/AccessStackAdapter.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/AccessStackAdapter.java
Thu Aug 16 05:41:23 2007
@@ -152,6 +152,13 @@
}
/**
+ * Returns whether the DB supports a TRIM function for an arbitrary
character.
+ */
+ public boolean supportsTrimChar() {
+ return false;
+ }
+
+ /**
* Returns false if stored procedures are not supported or if it is a
victim of
* CAY-148 (column name capitalization).
*/
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/MySQLStackAdapter.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/MySQLStackAdapter.java?view=diff&rev=566685&r1=566684&r2=566685
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/MySQLStackAdapter.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/unit/MySQLStackAdapter.java
Thu Aug 16 05:41:23 2007
@@ -54,6 +54,10 @@
public boolean supportsStoredProcedures() {
return true;
}
+
+ public boolean supportsTrimChar() {
+ return true;
+ }
public void createdTables(Connection con, DataMap map) throws Exception {
if (map.getProcedureMap().containsKey("cayenne_tst_select_proc")) {