aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstatta <statta@research.att.com>2019-05-31 12:28:00 -0400
committerstatta <statta@research.att.com>2019-05-31 12:28:00 -0400
commit1f36e4303bf76b752eed9ebb8c79a80c31139037 (patch)
tree4ca30eb5f32459460cbc098396a32d5ec1925452
parent65b45cafb4dff93bef52e91f2ab3f2a772e4472e (diff)
Enhance Clob,Blob support
Issue-ID: MUSIC-388 Change-Id: Ib02df8239e5d7572470fa696697685bdc582cdbb Signed-off-by: statta <statta@research.att.com>
-rw-r--r--mdbc-server/src/main/java/org/apache/calcite/avatica/AvaticaSite.java1239
-rw-r--r--mdbc-server/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java25
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java3
3 files changed, 652 insertions, 615 deletions
diff --git a/mdbc-server/src/main/java/org/apache/calcite/avatica/AvaticaSite.java b/mdbc-server/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
index 5fd4e69..2e7cdc0 100644
--- a/mdbc-server/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
+++ b/mdbc-server/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
@@ -1,612 +1,627 @@
-/*
- * 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.calcite.avatica;
-
-import org.apache.calcite.avatica.remote.TypedValue;
-import org.apache.calcite.avatica.util.Cursor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
-import java.sql.RowId;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-
-/**
- * A location that a value can be written to or read from.
- */
-public class AvaticaSite {
- final AvaticaParameter parameter;
-
- /** Calendar is not thread-safe. But calendar is only used from within one
- * thread, and we have to trust that clients are not modifying calendars
- * that they pass to us in a method such as
- * {@link java.sql.PreparedStatement#setTime(int, Time, Calendar)}, so we do
- * not need to synchronize access. */
- final Calendar calendar;
- private final int index;
- final TypedValue[] slots;
-
- /** Value that means the parameter has been set to null.
- * If value is null, parameter has not been set. */
- public static final Object DUMMY_VALUE = Dummy.INSTANCE;
-
- public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,
- TypedValue[] slots) {
- assert calendar != null;
- assert parameter != null;
- assert slots != null;
- this.parameter = parameter;
- this.calendar = calendar;
- this.index = index;
- this.slots = slots;
- }
-
- private TypedValue wrap(ColumnMetaData.Rep rep, Object o,
- Calendar calendar) {
- return TypedValue.ofJdbc(rep, o, calendar);
- }
-
- private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {
- return TypedValue.ofJdbc(rep, o, calendar);
- }
-
- public boolean isSet(int index) {
- return slots[index] != null;
- }
-
- public void setByte(byte o) {
- slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);
- }
-
- public void setChar(char o) {
- slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);
- }
-
- public void setShort(short o) {
- slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);
- }
-
- public void setInt(int o) {
- slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);
- }
-
- public void setLong(long o) {
- slots[index] = wrap(ColumnMetaData.Rep.LONG, o);
- }
-
- public void setBoolean(boolean o) {
- slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);
- }
-
- public void setRowId(RowId x) {
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);
- }
-
- public void setNString(String o) {
- slots[index] = wrap(ColumnMetaData.Rep.STRING, o);
- }
-
- public void setNCharacterStream(Reader value, long length) {
- }
-
- public void setNClob(NClob value) {
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);
- }
-
- public void setClob(Reader reader, long length) {
- }
-
- public void setBlob(InputStream inputStream, long length) {
- }
-
- public void setNClob(Reader reader, long length) {
- }
-
- public void setSQLXML(SQLXML xmlObject) {
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);
- }
-
- public void setAsciiStream(InputStream x, long length) {
- }
-
- public void setBinaryStream(InputStream x, long length) {
- }
-
- public void setCharacterStream(Reader reader, long length) {
- }
-
- public void setAsciiStream(InputStream x) {
- }
-
- public void setBinaryStream(InputStream x) {
- }
-
- public void setCharacterStream(Reader reader) {
- }
-
- public void setNCharacterStream(Reader value) {
- }
-
- public void setClob(Reader reader) {
- }
-
- public void setClob(InputStream inputStream) {
- }
-
- public void setBlob(InputStream inputStream) {
- }
-
- public void setNClob(Reader reader) {
- }
-
- public void setUnicodeStream(InputStream x, int length) {
- }
-
- public void setFloat(float x) {
- slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);
- }
-
- public void setDouble(double x) {
- slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);
- }
-
- public void setBigDecimal(BigDecimal x) {
- slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);
- }
-
- public void setString(String x) {
- slots[index] = wrap(ColumnMetaData.Rep.STRING, x);
- }
-
- public void setBytes(byte[] x) {
- slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);
- }
-
- public void setTimestamp(Timestamp x, Calendar calendar) {
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);
- }
-
- public void setTime(Time x, Calendar calendar) {
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);
- }
-
- public void setDate(Date x, Calendar calendar) {
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);
- }
-
- public void setObject(Object x, int targetSqlType) {
- if (x == null || Types.NULL == targetSqlType) {
- setNull(targetSqlType);
- return;
- }
- switch (targetSqlType) {
- case Types.CLOB:
- if (x instanceof Clob) {
- setClob((Clob) x);
- break;
- } else if (x instanceof InputStream) {
- setClob((InputStream) x);
- }
- throw unsupportedCast(x.getClass(), Blob.class);
- case Types.DATALINK:
- case Types.NCLOB:
- case Types.OTHER:
- case Types.REF:
- case Types.SQLXML:
- case Types.STRUCT:
- throw notImplemented();
- case Types.ARRAY:
- setArray(toArray(x));
- break;
- case Types.BIGINT:
- setLong(toLong(x));
- break;
- case Types.BINARY:
- case Types.LONGVARBINARY:
- case Types.VARBINARY:
- setBytes(toBytes(x));
- break;
- case Types.BIT:
- case Types.BOOLEAN:
- setBoolean(toBoolean(x));
- break;
- case Types.BLOB:
- if (x instanceof Blob) {
- setBlob((Blob) x);
- break;
- } else if (x instanceof InputStream) {
- setBlob((InputStream) x);
- }
- throw unsupportedCast(x.getClass(), Blob.class);
- case Types.DATE:
- setDate(toDate(x), calendar);
- break;
- case Types.DECIMAL:
- case Types.NUMERIC:
- setBigDecimal(toBigDecimal(x));
- break;
- case Types.DISTINCT:
- throw notImplemented();
- case Types.DOUBLE:
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
- setDouble(toDouble(x));
- break;
- case Types.INTEGER:
- setInt(toInt(x));
- break;
- case Types.JAVA_OBJECT:
- setObject(x);
- break;
- case Types.LONGNVARCHAR:
- case Types.LONGVARCHAR:
- case Types.NVARCHAR:
- case Types.VARCHAR:
- case Types.CHAR:
- case Types.NCHAR:
- setString(toString(x));
- break;
- case Types.REAL:
- setFloat(toFloat(x));
- break;
- case Types.ROWID:
- if (x instanceof RowId) {
- setRowId((RowId) x);
- break;
- }
- throw unsupportedCast(x.getClass(), RowId.class);
- case Types.SMALLINT:
- setShort(toShort(x));
- break;
- case Types.TIME:
- setTime(toTime(x), calendar);
- break;
- case Types.TIMESTAMP:
- setTimestamp(toTimestamp(x), calendar);
- break;
- case Types.TINYINT:
- setByte(toByte(x));
- break;
- default:
- throw notImplemented();
- }
- }
-
- /** Similar logic to {@link #setObject}. */
- public static Object get(Cursor.Accessor accessor, int targetSqlType,
- Calendar localCalendar) throws SQLException {
- switch (targetSqlType) {
- case Types.CLOB:
- return accessor.getClob();
- case Types.DATALINK:
- case Types.NCLOB:
- case Types.REF:
- case Types.SQLXML:
- case Types.STRUCT:
- throw notImplemented();
- case Types.ARRAY:
- return accessor.getArray();
- case Types.BIGINT:
- final long aLong = accessor.getLong();
- if (aLong == 0 && accessor.wasNull()) {
- return null;
- }
- return aLong;
- case Types.BINARY:
- case Types.LONGVARBINARY:
- case Types.VARBINARY:
- return accessor.getBytes();
- case Types.BIT:
- case Types.BOOLEAN:
- final boolean aBoolean = accessor.getBoolean();
- if (!aBoolean && accessor.wasNull()) {
- return null;
- }
- return aBoolean;
- case Types.BLOB:
- return accessor.getBlob();
- case Types.DATE:
- return accessor.getDate(localCalendar);
- case Types.DECIMAL:
- case Types.NUMERIC:
- return accessor.getBigDecimal();
- case Types.DISTINCT:
- throw notImplemented();
- case Types.DOUBLE:
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
- final double aDouble = accessor.getDouble();
- if (aDouble == 0 && accessor.wasNull()) {
- return null;
- }
- return aDouble;
- case Types.INTEGER:
- final int anInt = accessor.getInt();
- if (anInt == 0 && accessor.wasNull()) {
- return null;
- }
- return anInt;
- case Types.JAVA_OBJECT:
- case Types.OTHER:
- return accessor.getObject();
- case Types.LONGNVARCHAR:
- case Types.LONGVARCHAR:
- case Types.NVARCHAR:
- case Types.VARCHAR:
- case Types.CHAR:
- case Types.NCHAR:
- return accessor.getString();
- case Types.REAL:
- final float aFloat = accessor.getFloat();
- if (aFloat == 0 && accessor.wasNull()) {
- return null;
- }
- return aFloat;
- case Types.ROWID:
- throw notImplemented();
- case Types.SMALLINT:
- final short aShort = accessor.getShort();
- if (aShort == 0 && accessor.wasNull()) {
- return null;
- }
- return aShort;
- case Types.TIME:
- return accessor.getTime(localCalendar);
- case Types.TIMESTAMP:
- return accessor.getTimestamp(localCalendar);
- case Types.TINYINT:
- final byte aByte = accessor.getByte();
- if (aByte == 0 && accessor.wasNull()) {
- return null;
- }
- return aByte;
- default:
- throw notImplemented();
- }
- }
-
- public void setObject(Object x) {
- slots[index] = TypedValue.ofJdbc(x, calendar);
- }
-
- public void setNull(int sqlType) {
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);
- }
-
- public void setRef(Ref x) {
- }
-
- public void setBlob(Blob x) {
- InputStream iStream;
- try {
- iStream = x.getBinaryStream();
- int length =0;
- while(iStream.read() != -1)
- length ++;
- setBytes(x.getBytes(1, length));
-
- } catch (SQLException | IOException e) {
- throw new RuntimeException(e);
- }
-
- }
-
- public void setClob(Clob x) {
- }
-
- public void setArray(Array x) {
- slots[index] = wrap(ColumnMetaData.Rep.ARRAY, x);
- }
-
- public void setNull(int sqlType, String typeName) {
- }
-
- public void setURL(URL x) {
- }
-
- public void setObject(Object x, int targetSqlType,
- int scaleOrLength) {
- }
-
- private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
- return new UnsupportedOperationException("Cannot convert from "
- + from.getCanonicalName() + " to " + to.getCanonicalName());
- }
-
- private static RuntimeException notImplemented() {
- return new RuntimeException("not implemented");
- }
-
- private static Array toArray(Object x) {
- if (x instanceof Array) {
- return (Array) x;
- }
- throw unsupportedCast(x.getClass(), Array.class);
- }
-
- public static BigDecimal toBigDecimal(Object x) {
- if (x instanceof BigDecimal) {
- return (BigDecimal) x;
- } else if (x instanceof BigInteger) {
- return new BigDecimal((BigInteger) x);
- } else if (x instanceof Number) {
- if (x instanceof Double || x instanceof Float) {
- return new BigDecimal(((Number) x).doubleValue());
- } else {
- return new BigDecimal(((Number) x).longValue());
- }
- } else if (x instanceof Boolean) {
- return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
- } else if (x instanceof String) {
- return new BigDecimal((String) x);
- }
- throw unsupportedCast(x.getClass(), BigDecimal.class);
- }
-
- private static boolean toBoolean(Object x) {
- if (x instanceof Boolean) {
- return (Boolean) x;
- } else if (x instanceof Number) {
- return ((Number) x).intValue() != 0;
- } else if (x instanceof String) {
- String s = (String) x;
- if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
- return true;
- } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
- return false;
- }
- }
- throw unsupportedCast(x.getClass(), Boolean.TYPE);
- }
-
- private static byte toByte(Object x) {
- if (x instanceof Number) {
- return ((Number) x).byteValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? (byte) 1 : (byte) 0;
- } else if (x instanceof String) {
- return Byte.parseByte((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Byte.TYPE);
- }
- }
-
- private static byte[] toBytes(Object x) {
- if (x instanceof byte[]) {
- return (byte[]) x;
- }
- if (x instanceof String) {
- return ((String) x).getBytes(StandardCharsets.UTF_8);
- }
- throw unsupportedCast(x.getClass(), byte[].class);
- }
-
- private static Date toDate(Object x) {
- if (x instanceof String) {
- return Date.valueOf((String) x);
- }
- return new Date(toLong(x));
- }
-
- private static Time toTime(Object x) {
- if (x instanceof String) {
- return Time.valueOf((String) x);
- }
- return new Time(toLong(x));
- }
-
- private static Timestamp toTimestamp(Object x) {
- if (x instanceof String) {
- return Timestamp.valueOf((String) x);
- }
- return new Timestamp(toLong(x));
- }
-
- private static double toDouble(Object x) {
- if (x instanceof Number) {
- return ((Number) x).doubleValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1D : 0D;
- } else if (x instanceof String) {
- return Double.parseDouble((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Double.TYPE);
- }
- }
-
- private static float toFloat(Object x) {
- if (x instanceof Number) {
- return ((Number) x).floatValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1F : 0F;
- } else if (x instanceof String) {
- return Float.parseFloat((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Float.TYPE);
- }
- }
-
- private static int toInt(Object x) {
- if (x instanceof Number) {
- return ((Number) x).intValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1 : 0;
- } else if (x instanceof String) {
- return Integer.parseInt((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Integer.TYPE);
- }
- }
-
- private static long toLong(Object x) {
- if (x instanceof Number) {
- return ((Number) x).longValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? 1L : 0L;
- } else if (x instanceof String) {
- return Long.parseLong((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Long.TYPE);
- }
- }
-
- private static short toShort(Object x) {
- if (x instanceof Number) {
- return ((Number) x).shortValue();
- } else if (x instanceof Boolean) {
- return (Boolean) x ? (short) 1 : (short) 0;
- } else if (x instanceof String) {
- return Short.parseShort((String) x);
- } else {
- throw unsupportedCast(x.getClass(), Short.TYPE);
- }
- }
-
- private static String toString(Object x) {
- if (x instanceof String) {
- return (String) x;
- } else if (x instanceof Character
- || x instanceof Boolean) {
- return x.toString();
- }
- throw unsupportedCast(x.getClass(), String.class);
- }
-
- /** Singleton value to denote parameters that have been set to null (as
- * opposed to not set).
- *
- * <p>Not a valid value for a parameter.
- *
- * <p>As an enum, it is serializable by Jackson. */
- private enum Dummy {
- INSTANCE
- }
-}
-
-// End AvaticaSite.java
+/*
+ * 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.calcite.avatica;
+
+import org.apache.calcite.avatica.remote.TypedValue;
+import org.apache.calcite.avatica.util.Cursor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+
+/**
+ * A location that a value can be written to or read from.
+ */
+public class AvaticaSite {
+ final AvaticaParameter parameter;
+
+ /** Calendar is not thread-safe. But calendar is only used from within one
+ * thread, and we have to trust that clients are not modifying calendars
+ * that they pass to us in a method such as
+ * {@link java.sql.PreparedStatement#setTime(int, Time, Calendar)}, so we do
+ * not need to synchronize access. */
+ final Calendar calendar;
+ private final int index;
+ final TypedValue[] slots;
+
+ /** Value that means the parameter has been set to null.
+ * If value is null, parameter has not been set. */
+ public static final Object DUMMY_VALUE = Dummy.INSTANCE;
+
+ public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,
+ TypedValue[] slots) {
+ assert calendar != null;
+ assert parameter != null;
+ assert slots != null;
+ this.parameter = parameter;
+ this.calendar = calendar;
+ this.index = index;
+ this.slots = slots;
+ }
+
+ private TypedValue wrap(ColumnMetaData.Rep rep, Object o,
+ Calendar calendar) {
+ return TypedValue.ofJdbc(rep, o, calendar);
+ }
+
+ private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {
+ return TypedValue.ofJdbc(rep, o, calendar);
+ }
+
+ public boolean isSet(int index) {
+ return slots[index] != null;
+ }
+
+ public void setByte(byte o) {
+ slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);
+ }
+
+ public void setChar(char o) {
+ slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);
+ }
+
+ public void setShort(short o) {
+ slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);
+ }
+
+ public void setInt(int o) {
+ slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);
+ }
+
+ public void setLong(long o) {
+ slots[index] = wrap(ColumnMetaData.Rep.LONG, o);
+ }
+
+ public void setBoolean(boolean o) {
+ slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);
+ }
+
+ public void setRowId(RowId x) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);
+ }
+
+ public void setNString(String o) {
+ slots[index] = wrap(ColumnMetaData.Rep.STRING, o);
+ }
+
+ public void setNCharacterStream(Reader value, long length) {
+ }
+
+ public void setNClob(NClob value) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);
+ }
+
+ public void setClob(Reader reader, long length) {
+ }
+
+ public void setBlob(InputStream inputStream, long length) {
+ }
+
+ public void setNClob(Reader reader, long length) {
+ }
+
+ public void setSQLXML(SQLXML xmlObject) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);
+ }
+
+ public void setAsciiStream(InputStream x, long length) {
+ }
+
+ public void setBinaryStream(InputStream x, long length) {
+ }
+
+ public void setCharacterStream(Reader reader, long length) {
+ }
+
+ public void setAsciiStream(InputStream x) {
+ }
+
+ public void setBinaryStream(InputStream x) {
+ }
+
+ public void setCharacterStream(Reader reader) {
+ }
+
+ public void setNCharacterStream(Reader value) {
+ }
+
+ public void setClob(Reader reader) {
+ }
+
+ public void setClob(InputStream inputStream) {
+ }
+
+ public void setBlob(InputStream inputStream) {
+ }
+
+ public void setNClob(Reader reader) {
+ }
+
+ public void setUnicodeStream(InputStream x, int length) {
+ }
+
+ public void setFloat(float x) {
+ slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);
+ }
+
+ public void setDouble(double x) {
+ slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);
+ }
+
+ public void setBigDecimal(BigDecimal x) {
+ slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);
+ }
+
+ public void setString(String x) {
+ slots[index] = wrap(ColumnMetaData.Rep.STRING, x);
+ }
+
+ public void setBytes(byte[] x) {
+ slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);
+ }
+
+ public void setTimestamp(Timestamp x, Calendar calendar) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);
+ }
+
+ public void setTime(Time x, Calendar calendar) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);
+ }
+
+ public void setDate(Date x, Calendar calendar) {
+ slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);
+ }
+
+ public void setObject(Object x, int targetSqlType) {
+ if (x == null || Types.NULL == targetSqlType) {
+ setNull(targetSqlType);
+ return;
+ }
+ switch (targetSqlType) {
+ case Types.CLOB:
+ if (x instanceof Clob) {
+ setClob((Clob) x);
+ break;
+ } else if (x instanceof InputStream) {
+ setClob((InputStream) x);
+ }
+ throw unsupportedCast(x.getClass(), Blob.class);
+ case Types.DATALINK:
+ case Types.NCLOB:
+ case Types.OTHER:
+ case Types.REF:
+ case Types.SQLXML:
+ case Types.STRUCT:
+ throw notImplemented();
+ case Types.ARRAY:
+ setArray(toArray(x));
+ break;
+ case Types.BIGINT:
+ setLong(toLong(x));
+ break;
+ case Types.BINARY:
+ case Types.LONGVARBINARY:
+ case Types.VARBINARY:
+ setBytes(toBytes(x));
+ break;
+ case Types.BIT:
+ case Types.BOOLEAN:
+ setBoolean(toBoolean(x));
+ break;
+ case Types.BLOB:
+ if (x instanceof Blob) {
+ setBlob((Blob) x);
+ break;
+ } else if (x instanceof InputStream) {
+ setBlob((InputStream) x);
+ }
+ throw unsupportedCast(x.getClass(), Blob.class);
+ case Types.DATE:
+ setDate(toDate(x), calendar);
+ break;
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ setBigDecimal(toBigDecimal(x));
+ break;
+ case Types.DISTINCT:
+ throw notImplemented();
+ case Types.DOUBLE:
+ case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+ setDouble(toDouble(x));
+ break;
+ case Types.INTEGER:
+ setInt(toInt(x));
+ break;
+ case Types.JAVA_OBJECT:
+ setObject(x);
+ break;
+ case Types.LONGNVARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.NVARCHAR:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.NCHAR:
+ setString(toString(x));
+ break;
+ case Types.REAL:
+ setFloat(toFloat(x));
+ break;
+ case Types.ROWID:
+ if (x instanceof RowId) {
+ setRowId((RowId) x);
+ break;
+ }
+ throw unsupportedCast(x.getClass(), RowId.class);
+ case Types.SMALLINT:
+ setShort(toShort(x));
+ break;
+ case Types.TIME:
+ setTime(toTime(x), calendar);
+ break;
+ case Types.TIMESTAMP:
+ setTimestamp(toTimestamp(x), calendar);
+ break;
+ case Types.TINYINT:
+ setByte(toByte(x));
+ break;
+ default:
+ throw notImplemented();
+ }
+ }
+
+ /** Similar logic to {@link #setObject}. */
+ public static Object get(Cursor.Accessor accessor, int targetSqlType,
+ Calendar localCalendar) throws SQLException {
+ switch (targetSqlType) {
+ case Types.CLOB:
+ return accessor.getClob();
+ case Types.DATALINK:
+ case Types.NCLOB:
+ case Types.REF:
+ case Types.SQLXML:
+ case Types.STRUCT:
+ throw notImplemented();
+ case Types.ARRAY:
+ return accessor.getArray();
+ case Types.BIGINT:
+ final long aLong = accessor.getLong();
+ if (aLong == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aLong;
+ case Types.BINARY:
+ case Types.LONGVARBINARY:
+ case Types.VARBINARY:
+ return accessor.getBytes();
+ case Types.BIT:
+ case Types.BOOLEAN:
+ final boolean aBoolean = accessor.getBoolean();
+ if (!aBoolean && accessor.wasNull()) {
+ return null;
+ }
+ return aBoolean;
+ case Types.BLOB:
+ return accessor.getBlob();
+ case Types.DATE:
+ return accessor.getDate(localCalendar);
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ return accessor.getBigDecimal();
+ case Types.DISTINCT:
+ throw notImplemented();
+ case Types.DOUBLE:
+ case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes
+ final double aDouble = accessor.getDouble();
+ if (aDouble == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aDouble;
+ case Types.INTEGER:
+ final int anInt = accessor.getInt();
+ if (anInt == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return anInt;
+ case Types.JAVA_OBJECT:
+ case Types.OTHER:
+ return accessor.getObject();
+ case Types.LONGNVARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.NVARCHAR:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.NCHAR:
+ return accessor.getString();
+ case Types.REAL:
+ final float aFloat = accessor.getFloat();
+ if (aFloat == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aFloat;
+ case Types.ROWID:
+ throw notImplemented();
+ case Types.SMALLINT:
+ final short aShort = accessor.getShort();
+ if (aShort == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aShort;
+ case Types.TIME:
+ return accessor.getTime(localCalendar);
+ case Types.TIMESTAMP:
+ return accessor.getTimestamp(localCalendar);
+ case Types.TINYINT:
+ final byte aByte = accessor.getByte();
+ if (aByte == 0 && accessor.wasNull()) {
+ return null;
+ }
+ return aByte;
+ default:
+ throw notImplemented();
+ }
+ }
+
+ public void setObject(Object x) {
+ slots[index] = TypedValue.ofJdbc(x, calendar);
+ }
+
+ public void setNull(int sqlType) {
+ slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);
+ }
+
+ public void setRef(Ref x) {
+ }
+
+ // This method is not implemented in the base Avatica jar version which is being used currently;
+ // Added implementation to enable Blob database writes
+ public void setBlob(Blob x) {
+ InputStream iStream;
+ try {
+ iStream = x.getBinaryStream();
+ int length =0;
+ while(iStream.read() != -1)
+ length ++;
+ setBytes(x.getBytes(1, length));
+
+ } catch (SQLException | IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ // This method is not implemented in the base Avatica jar version which is being used currently;
+ // Added implementation to enable Clob database writes
+ public void setClob(Clob x) {
+ Reader iStream;
+ try {
+ iStream = x.getCharacterStream();
+ int length =0;
+ while(iStream.read() != -1)
+ length ++;
+ setBytes(x.getSubString(1, length).getBytes());
+
+ } catch (SQLException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void setArray(Array x) {
+ slots[index] = wrap(ColumnMetaData.Rep.ARRAY, x);
+ }
+
+ public void setNull(int sqlType, String typeName) {
+ }
+
+ public void setURL(URL x) {
+ }
+
+ public void setObject(Object x, int targetSqlType,
+ int scaleOrLength) {
+ }
+
+ private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {
+ return new UnsupportedOperationException("Cannot convert from "
+ + from.getCanonicalName() + " to " + to.getCanonicalName());
+ }
+
+ private static RuntimeException notImplemented() {
+ return new RuntimeException("not implemented");
+ }
+
+ private static Array toArray(Object x) {
+ if (x instanceof Array) {
+ return (Array) x;
+ }
+ throw unsupportedCast(x.getClass(), Array.class);
+ }
+
+ public static BigDecimal toBigDecimal(Object x) {
+ if (x instanceof BigDecimal) {
+ return (BigDecimal) x;
+ } else if (x instanceof BigInteger) {
+ return new BigDecimal((BigInteger) x);
+ } else if (x instanceof Number) {
+ if (x instanceof Double || x instanceof Float) {
+ return new BigDecimal(((Number) x).doubleValue());
+ } else {
+ return new BigDecimal(((Number) x).longValue());
+ }
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;
+ } else if (x instanceof String) {
+ return new BigDecimal((String) x);
+ }
+ throw unsupportedCast(x.getClass(), BigDecimal.class);
+ }
+
+ private static boolean toBoolean(Object x) {
+ if (x instanceof Boolean) {
+ return (Boolean) x;
+ } else if (x instanceof Number) {
+ return ((Number) x).intValue() != 0;
+ } else if (x instanceof String) {
+ String s = (String) x;
+ if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {
+ return true;
+ } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {
+ return false;
+ }
+ }
+ throw unsupportedCast(x.getClass(), Boolean.TYPE);
+ }
+
+ private static byte toByte(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).byteValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? (byte) 1 : (byte) 0;
+ } else if (x instanceof String) {
+ return Byte.parseByte((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Byte.TYPE);
+ }
+ }
+
+ private static byte[] toBytes(Object x) {
+ if (x instanceof byte[]) {
+ return (byte[]) x;
+ }
+ if (x instanceof String) {
+ return ((String) x).getBytes(StandardCharsets.UTF_8);
+ }
+ throw unsupportedCast(x.getClass(), byte[].class);
+ }
+
+ private static Date toDate(Object x) {
+ if (x instanceof String) {
+ return Date.valueOf((String) x);
+ }
+ return new Date(toLong(x));
+ }
+
+ private static Time toTime(Object x) {
+ if (x instanceof String) {
+ return Time.valueOf((String) x);
+ }
+ return new Time(toLong(x));
+ }
+
+ private static Timestamp toTimestamp(Object x) {
+ if (x instanceof String) {
+ return Timestamp.valueOf((String) x);
+ }
+ return new Timestamp(toLong(x));
+ }
+
+ private static double toDouble(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).doubleValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1D : 0D;
+ } else if (x instanceof String) {
+ return Double.parseDouble((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Double.TYPE);
+ }
+ }
+
+ private static float toFloat(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).floatValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1F : 0F;
+ } else if (x instanceof String) {
+ return Float.parseFloat((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Float.TYPE);
+ }
+ }
+
+ private static int toInt(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).intValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1 : 0;
+ } else if (x instanceof String) {
+ return Integer.parseInt((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Integer.TYPE);
+ }
+ }
+
+ private static long toLong(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).longValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? 1L : 0L;
+ } else if (x instanceof String) {
+ return Long.parseLong((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Long.TYPE);
+ }
+ }
+
+ private static short toShort(Object x) {
+ if (x instanceof Number) {
+ return ((Number) x).shortValue();
+ } else if (x instanceof Boolean) {
+ return (Boolean) x ? (short) 1 : (short) 0;
+ } else if (x instanceof String) {
+ return Short.parseShort((String) x);
+ } else {
+ throw unsupportedCast(x.getClass(), Short.TYPE);
+ }
+ }
+
+ private static String toString(Object x) {
+ if (x instanceof String) {
+ return (String) x;
+ } else if (x instanceof Character
+ || x instanceof Boolean) {
+ return x.toString();
+ }
+ throw unsupportedCast(x.getClass(), String.class);
+ }
+
+ /** Singleton value to denote parameters that have been set to null (as
+ * opposed to not set).
+ *
+ * <p>Not a valid value for a parameter.
+ *
+ * <p>As an enum, it is serializable by Jackson. */
+ private enum Dummy {
+ INSTANCE
+ }
+}
+
+// End AvaticaSite.java
diff --git a/mdbc-server/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java b/mdbc-server/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
index cacbb8b..bf139f5 100644
--- a/mdbc-server/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
+++ b/mdbc-server/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
@@ -41,6 +41,7 @@ import java.util.Calendar;
import java.util.List;
import java.util.Map;
import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
import org.apache.calcite.avatica.AvaticaSite;
import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData;
@@ -848,7 +849,9 @@ public abstract class AbstractCursor implements Cursor {
throw new IllegalStateException("Unhandled value type: " + o.getClass());
}
-
+ // This method is not implemented in the base Avatica jar version which is being used currently;
+ // Added implementation to enable Blob database reads; this has unintended consequences if entire object
+ // cannot be loaded into memory
@Override public Blob getBlob() throws SQLException {
Object o = getObject();
@@ -857,13 +860,31 @@ public abstract class AbstractCursor implements Cursor {
}
if (o instanceof byte[]) {
byte[] byteArr = (byte[] )o;
- //System.out.println(new String(byteArr, StandardCharsets.UTF_8));
return new SerialBlob(byteArr);
}
throw new IllegalStateException("Unhandled value type: " + o.getClass());
}
+
+ // This method is not implemented in the base Avatica jar version which is being used currently;
+ // Added implementation to enable Clob database writes; this has unintended consequences if entire object
+ // cannot be loaded into memory
+ @Override public Clob getClob() throws SQLException {
+
+ Object o = getObject();
+ if (null == o) {
+ return null;
+ }
+ if (o instanceof byte[]) {
+ byte[] byteArr = (byte[] )o;
+ return new SerialClob(new String(byteArr).toCharArray());
+ }
+
+ throw new IllegalStateException("Unhandled value type: " + o.getClass());
+
+ }
+
}
/**
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
index 7e9b5f4..8f27953 100755
--- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
+++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java
@@ -333,7 +333,8 @@ mysql> describe tables;
case "text":
case "varchar": return Types.VARCHAR;
case "mediumblob":
- case "blob": return Types.VARCHAR;
+ case "longblob":
+ case "blob": return Types.BLOB;
default:
logger.error(EELFLoggerDelegate.errorLogger,"unrecognized and/or unsupported data type "+nm);
return Types.VARCHAR;