From 388c56f05ffb515eb4f61bb5461ef969b0a9cadd Mon Sep 17 00:00:00 2001 From: Catalina Wei Date: Thu, 15 Jan 2009 03:11:00 +0000 Subject: [PATCH] OPENJPA-846 XML column support for MySQL git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@734601 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/openjpa/jdbc/meta/MappingInfo.java | 2 + .../jdbc/meta/strats/XMLValueHandler.java | 1 + .../apache/openjpa/jdbc/schema/Column.java | 14 ++++++- .../openjpa/jdbc/sql/MySQLDictionary.java | 42 +++++++++++++++++++ .../query/TestXMLCustomerOrder.mysql | 22 ++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.mysql diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java index ef4439329..364fbba9a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java @@ -765,6 +765,8 @@ public abstract class MappingInfo if (tmplate.hasComment()) col.setComment(tmplate.getComment()); + if (tmplate.isXML()) + col.setXML(tmplate.isXML()); return col; } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/XMLValueHandler.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/XMLValueHandler.java index 7008ec062..ff1bfc178 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/XMLValueHandler.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/XMLValueHandler.java @@ -53,6 +53,7 @@ public class XMLValueHandler col.setSize(-1); col.setTypeName(vm.getMappingRepository().getDBDictionary() .xmlTypeName); + col.setXML(true); return new Column[]{ col }; } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java index c965518ed..79c9494e0 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Column.java @@ -74,6 +74,7 @@ public class Column private boolean _pk = false; private VersionStrategy _versionStrategy = null; private String _comment = null; + private boolean _XML = false; /** * Default constructor. @@ -721,13 +722,22 @@ public class Column setTargetField(from.getTargetField()); if (_flags == 0) _flags = from._flags; + if (!isXML()) + setXML(from.isXML()); } /** - * Whether this column is an XML type. + * Whether this column is of XML type. */ public boolean isXML() { - return _typeName != null && _typeName.startsWith("XML"); + return _XML; + } + + /** + * Whether this column is of XML type. + */ + public void setXML(boolean xml) { + _XML = xml; } public VersionStrategy getVersionStrategy() { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java index d3e98abb4..3d25d95a4 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java @@ -27,6 +27,7 @@ import java.util.Arrays; import org.apache.commons.lang.StringUtils; import org.apache.openjpa.jdbc.kernel.JDBCStore; +import org.apache.openjpa.jdbc.kernel.exps.FilterValue; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.ForeignKey; import org.apache.openjpa.jdbc.schema.Index; @@ -94,6 +95,7 @@ public class MySQLDictionary longVarcharTypeName = "TEXT"; longVarbinaryTypeName = "LONG VARBINARY"; timestampTypeName = "DATETIME"; + xmlTypeName = "TEXT"; fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{ "BOOL", "LONG VARBINARY", "MEDIUMBLOB", "LONGBLOB", "TINYBLOB", "LONG VARCHAR", "MEDIUMTEXT", "LONGTEXT", "TEXT", @@ -130,6 +132,8 @@ public class MySQLDictionary supportsSubselect = false; allowsAliasInBulkClause = false; } + if (maj > 5 || (maj == 5 && min >= 1)) + supportsXMLColumn = true; versions = getMajorMinorVersions(driverVersion); maj = versions[0]; @@ -262,4 +266,42 @@ public class MySQLDictionary return Types.LONGVARCHAR; return super.getPreferredType(type); } + + /** + * Append XML comparison. + * + * @param buf the SQL buffer to write the comparison + * @param op the comparison operation to perform + * @param lhs the left hand side of the comparison + * @param rhs the right hand side of the comparison + * @param lhsxml indicates whether the left operand maps to XML + * @param rhsxml indicates whether the right operand maps to XML + */ + public void appendXmlComparison(SQLBuffer buf, String op, FilterValue lhs, + FilterValue rhs, boolean lhsxml, boolean rhsxml) { + super.appendXmlComparison(buf, op, lhs, rhs, lhsxml, rhsxml); + if (lhsxml) + appendXmlValue(buf, lhs); + else + lhs.appendTo(buf); + buf.append(" ").append(op).append(" "); + if (rhsxml) + appendXmlValue(buf, rhs); + else + rhs.appendTo(buf); + } + + /** + * Append XML column value so that it can be used in comparisons. + * + * @param buf the SQL buffer to write the value + * @param val the value to be written + */ + private void appendXmlValue(SQLBuffer buf, FilterValue val) { + buf.append("ExtractValue("). + append(val.getColumnAlias(val.getFieldMapping().getColumns()[0])). + append(",'/*/"); + val.appendTo(buf); + buf.append("')"); + } } diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.mysql b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.mysql new file mode 100644 index 000000000..5119f9778 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/xmlmapping/query/TestXMLCustomerOrder.mysql @@ -0,0 +1,22 @@ +-- 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. + +SELECT t0.shipAddress, t0.oid FROM TORDER t0 ORDER BY t0.oid ASC +SELECT t0.oid, t1.oid FROM TORDER t0 CROSS JOIN TORDER t1 WHERE (ExtractValue(t0.shipAddress,'/*/City') = ExtractValue(t1.shipAddress,'/*/City')) ORDER BY t0.oid ASC +SELECT t0.oid, t0.version, t0.amount, t0.CUSTOMER_COUNTRYCODE, t0.CUSTOMER_ID, t0.delivered, t0.shipAddress FROM TORDER t0 CROSS JOIN TCUSTOMER t1 WHERE (ExtractValue(t0.shipAddress,'/*/City') = t1.city) +SELECT t0.oid, t0.version, t0.amount, t0.CUSTOMER_COUNTRYCODE, t0.CUSTOMER_ID, t0.delivered, t0.shipAddress FROM TORDER t0 WHERE (ExtractValue(t0.shipAddress,'/*/City') = ?) +SELECT t0.oid, t0.version, t0.amount, t0.CUSTOMER_COUNTRYCODE, t0.CUSTOMER_ID, t0.delivered, t0.shipAddress FROM TORDER t0 WHERE (? = ExtractValue(t0.shipAddress,'/*/City'))