Author: shawkins
Date: 2010-06-18 13:58:01 -0400 (Fri, 18 Jun 2010)
New Revision: 2249
Modified:
trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/engine/src/main/java/org/teiid/query/function/CharsetUtils.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
Log:
TEIID-1021 refining support for clob<->blob conversions. adding validation of binary
conversions
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java 2010-06-18
16:09:32 UTC (rev 2248)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java 2010-06-18
17:58:01 UTC (rev 2249)
@@ -61,16 +61,17 @@
@Override
public int read() throws IOException {
- if (!hasMore) {
- return -1;
- }
while (pos >= out.getCount()) {
+ if (!hasMore) {
+ return -1;
+ }
out.reset();
pos = 0;
int charsRead = reader.read(charBuffer);
if (charsRead == -1) {
+ writer.close();
hasMore = false;
- return -1;
+ continue;
}
writer.write(charBuffer, 0, charsRead);
writer.flush();
Modified:
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
---
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2010-06-18
16:09:32 UTC (rev 2248)
+++
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2010-06-18
17:58:01 UTC (rev 2249)
@@ -1028,7 +1028,8 @@
<para>TO_CHARS(x, encoding)</para>
</entry>
<entry>
- <para>Return a clob from the blob with the given encoding. BASE64,
HEX, and the builtin Java Charset<footnote id="charset"><para>See
the <ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/Charse...
JavaDoc</ulink></para></footnote> names are valid values for the
encoding.</para>
+ <para>Return a clob from the blob with the given encoding.
+ BASE64, HEX, and the builtin Java Charset names are valid values for the
encoding.<footnote id="charset"><para>See the <ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/Charse...
JavaDoc</ulink> for more on supported Charset names. For charsets, unmappable chars
will be replaced with the charset default character. binary formats, such as BASE64, will
error in their conversion to bytes is a unrecognizable character is
encountered.</para></footnote></para>
</entry>
<entry>
<para>x is a blob, encoding is a string, and returns a
clob</para>
@@ -1038,7 +1039,8 @@
<para>TO_BYTES(x, encoding)</para>
</entry>
<entry>
- <para>Return a blob from the clob with the given encoding. BASE64,
HEX, and the builtin Java Charset<footnoteref linkend="charset"/> names
are valid values for the encoding.</para>
+ <para>Return a blob from the clob with the given encoding.
+ BASE64, HEX, and the builtin Java Charset names are valid values for the
encoding.<footnoteref linkend="charset"/></para>
</entry>
<entry>
<para>x in a clob, encoding is a string, and returns a
blob</para>
Modified: trunk/engine/src/main/java/org/teiid/query/function/CharsetUtils.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/CharsetUtils.java 2010-06-18
16:09:32 UTC (rev 2248)
+++ trunk/engine/src/main/java/org/teiid/query/function/CharsetUtils.java 2010-06-18
17:58:01 UTC (rev 2249)
@@ -45,9 +45,10 @@
char[] chars = new char[2];
@Override
- protected void encode(ByteBuffer out) {
+ protected CoderResult encode(ByteBuffer out) {
this.cb.get(chars);
out.put((byte)(Integer.parseInt(new String(chars), 16) & 0xff));
+ return CoderResult.UNDERFLOW;
}
};
@@ -84,8 +85,13 @@
return new FixedEncoder(this, 4, .75f, 1) {
@Override
- protected void encode(ByteBuffer out) {
- out.put(Base64.decode(cb));
+ protected CoderResult encode(ByteBuffer out) {
+ try {
+ out.put(Base64.decode(cb));
+ return CoderResult.UNDERFLOW;
+ } catch (IllegalArgumentException e) {
+ return CoderResult.unmappableForLength(4);
+ }
}
};
@@ -130,14 +136,17 @@
return CoderResult.OVERFLOW;
}
cb.flip();
- encode(out);
+ CoderResult result = encode(out);
+ if (result != CoderResult.UNDERFLOW) {
+ return result;
+ }
cb.clear();
}
}
return CoderResult.UNDERFLOW;
}
- abstract protected void encode(ByteBuffer out);
+ abstract protected CoderResult encode(ByteBuffer out);
@Override
protected CoderResult implFlush(ByteBuffer out) {
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2010-06-18
16:09:32 UTC (rev 2248)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionMethods.java 2010-06-18
17:58:01 UTC (rev 2249)
@@ -22,6 +22,8 @@
package org.teiid.query.function;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -1265,10 +1267,22 @@
return new ClobType(clob);
}
- public static Blob toBytes(ClobType value, String encoding) {
+ public static Blob toBytes(ClobType value, String encoding) throws IOException {
Charset cs = getCharset(encoding);
ClobInputStreamFactory cisf = new ClobInputStreamFactory(value.getReference());
cisf.setCharset(cs);
+ if (CharsetUtils.BASE64_NAME.equalsIgnoreCase(encoding) ||
CharsetUtils.HEX_NAME.equalsIgnoreCase(encoding)) {
+ //validate that the binary conversion is possible
+ //TODO: cache the result in a filestore
+ InputStream is = cisf.getInputStream();
+ try {
+ while (is.read() != -1) {
+
+ }
+ } finally {
+ is.close();
+ }
+ }
return new BlobType(new BlobImpl(cisf));
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
---
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2010-06-18
16:09:32 UTC (rev 2248)
+++
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2010-06-18
17:58:01 UTC (rev 2249)
@@ -1369,32 +1369,36 @@
assertEquals("<!--comment-->", xml);
}
- @Test public void testEncode() throws Exception {
+ @Test public void testToChars() throws Exception {
Clob result = (Clob)helpInvokeMethod("to_chars", new Class[]
{DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new
SerialBlob("hello world".getBytes("ASCII"))), "ASCII" },
null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", string);
}
- @Test public void testDecode() throws Exception {
+ @Test public void testToBytes() throws Exception {
Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[]
{DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new
SerialClob("hello world".toCharArray())), "UTF32" }, null);
//$NON-NLS-1$
assertEquals(44, result.length()); //4 bytes / char
}
- @Test public void testEncode1() throws Exception {
+ @Test public void testToChars1() throws Exception {
Clob result = (Clob)helpInvokeMethod("to_chars", new Class[]
{DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new
SerialBlob("hello world".getBytes("ASCII"))), "BASE64" },
null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("hello world", new String(Base64.decode(string),
"ASCII"));
}
- @Test public void testEncode2() throws Exception {
+ @Test public void testToChars2() throws Exception {
Clob result = (Clob)helpInvokeMethod("to_chars", new Class[]
{DefaultDataClasses.BLOB, DefaultDataClasses.STRING}, new Object[] { new BlobType(new
SerialBlob("hello world".getBytes("ASCII"))), "HEX" },
null); //$NON-NLS-1$
String string = result.getSubString(1, (int)result.length());
assertEquals("68656C6C6F20776F726C64", string);
}
- @Test public void testDecode2() throws Exception {
+ @Test public void testToBytes2() throws Exception {
Blob result = (Blob)helpInvokeMethod("to_bytes", new Class[]
{DefaultDataClasses.CLOB, DefaultDataClasses.STRING}, new Object[] { new ClobType(new
SerialClob("68656C6C6F20776F726C64".toCharArray())), "HEX" }, null);
//$NON-NLS-1$
assertEquals("hello world", new
String(ObjectConverterUtil.convertToCharArray(result.getBinaryStream(), -1,
"ASCII")));
}
+ @Test(expected=FunctionExecutionException.class) public void testToBytes3() throws
Exception {
+ helpInvokeMethod("to_bytes", new Class[] {DefaultDataClasses.CLOB,
DefaultDataClasses.STRING}, new Object[] { new ClobType(new
SerialClob("a".toCharArray())), "BASE64" }, null); //$NON-NLS-1$
+ }
+
}