-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements. See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to you under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.calcite.avatica;\r
-\r
-import org.apache.calcite.avatica.remote.TypedValue;\r
-import org.apache.calcite.avatica.util.Cursor;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.Reader;\r
-import java.math.BigDecimal;\r
-import java.math.BigInteger;\r
-import java.net.URL;\r
-import java.nio.charset.StandardCharsets;\r
-import java.sql.Array;\r
-import java.sql.Blob;\r
-import java.sql.Clob;\r
-import java.sql.Date;\r
-import java.sql.NClob;\r
-import java.sql.Ref;\r
-import java.sql.RowId;\r
-import java.sql.SQLException;\r
-import java.sql.SQLXML;\r
-import java.sql.Time;\r
-import java.sql.Timestamp;\r
-import java.sql.Types;\r
-import java.util.Calendar;\r
-\r
-/**\r
- * A location that a value can be written to or read from.\r
- */\r
-public class AvaticaSite {\r
- final AvaticaParameter parameter;\r
-\r
- /** Calendar is not thread-safe. But calendar is only used from within one\r
- * thread, and we have to trust that clients are not modifying calendars\r
- * that they pass to us in a method such as\r
- * {@link java.sql.PreparedStatement#setTime(int, Time, Calendar)}, so we do\r
- * not need to synchronize access. */\r
- final Calendar calendar;\r
- private final int index;\r
- final TypedValue[] slots;\r
-\r
- /** Value that means the parameter has been set to null.\r
- * If value is null, parameter has not been set. */\r
- public static final Object DUMMY_VALUE = Dummy.INSTANCE;\r
-\r
- public AvaticaSite(AvaticaParameter parameter, Calendar calendar, int index,\r
- TypedValue[] slots) {\r
- assert calendar != null;\r
- assert parameter != null;\r
- assert slots != null;\r
- this.parameter = parameter;\r
- this.calendar = calendar;\r
- this.index = index;\r
- this.slots = slots;\r
- }\r
-\r
- private TypedValue wrap(ColumnMetaData.Rep rep, Object o,\r
- Calendar calendar) {\r
- return TypedValue.ofJdbc(rep, o, calendar);\r
- }\r
-\r
- private TypedValue wrap(ColumnMetaData.Rep rep, Object o) {\r
- return TypedValue.ofJdbc(rep, o, calendar);\r
- }\r
-\r
- public boolean isSet(int index) {\r
- return slots[index] != null;\r
- }\r
-\r
- public void setByte(byte o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.BYTE, o);\r
- }\r
-\r
- public void setChar(char o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.CHARACTER, o);\r
- }\r
-\r
- public void setShort(short o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.SHORT, o);\r
- }\r
-\r
- public void setInt(int o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.INTEGER, o);\r
- }\r
-\r
- public void setLong(long o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.LONG, o);\r
- }\r
-\r
- public void setBoolean(boolean o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.BOOLEAN, o);\r
- }\r
-\r
- public void setRowId(RowId x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, x);\r
- }\r
-\r
- public void setNString(String o) {\r
- slots[index] = wrap(ColumnMetaData.Rep.STRING, o);\r
- }\r
-\r
- public void setNCharacterStream(Reader value, long length) {\r
- }\r
-\r
- public void setNClob(NClob value) {\r
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, value);\r
- }\r
-\r
- public void setClob(Reader reader, long length) {\r
- }\r
-\r
- public void setBlob(InputStream inputStream, long length) {\r
- }\r
-\r
- public void setNClob(Reader reader, long length) {\r
- }\r
-\r
- public void setSQLXML(SQLXML xmlObject) {\r
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, xmlObject);\r
- }\r
-\r
- public void setAsciiStream(InputStream x, long length) {\r
- }\r
-\r
- public void setBinaryStream(InputStream x, long length) {\r
- }\r
-\r
- public void setCharacterStream(Reader reader, long length) {\r
- }\r
-\r
- public void setAsciiStream(InputStream x) {\r
- }\r
-\r
- public void setBinaryStream(InputStream x) {\r
- }\r
-\r
- public void setCharacterStream(Reader reader) {\r
- }\r
-\r
- public void setNCharacterStream(Reader value) {\r
- }\r
-\r
- public void setClob(Reader reader) {\r
- }\r
- \r
- public void setClob(InputStream inputStream) {\r
- }\r
-\r
- public void setBlob(InputStream inputStream) {\r
- }\r
-\r
- public void setNClob(Reader reader) {\r
- }\r
-\r
- public void setUnicodeStream(InputStream x, int length) {\r
- }\r
-\r
- public void setFloat(float x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.FLOAT, x);\r
- }\r
-\r
- public void setDouble(double x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.DOUBLE, x);\r
- }\r
-\r
- public void setBigDecimal(BigDecimal x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.NUMBER, x);\r
- }\r
-\r
- public void setString(String x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.STRING, x);\r
- }\r
-\r
- public void setBytes(byte[] x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.BYTE_STRING, x);\r
- }\r
-\r
- public void setTimestamp(Timestamp x, Calendar calendar) {\r
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP, x, calendar);\r
- }\r
-\r
- public void setTime(Time x, Calendar calendar) {\r
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_TIME, x, calendar);\r
- }\r
-\r
- public void setDate(Date x, Calendar calendar) {\r
- slots[index] = wrap(ColumnMetaData.Rep.JAVA_SQL_DATE, x, calendar);\r
- }\r
-\r
- public void setObject(Object x, int targetSqlType) {\r
- if (x == null || Types.NULL == targetSqlType) {\r
- setNull(targetSqlType);\r
- return;\r
- }\r
- switch (targetSqlType) {\r
- case Types.CLOB:\r
- if (x instanceof Clob) {\r
- setClob((Clob) x);\r
- break;\r
- } else if (x instanceof InputStream) {\r
- setClob((InputStream) x);\r
- }\r
- throw unsupportedCast(x.getClass(), Blob.class);\r
- case Types.DATALINK:\r
- case Types.NCLOB:\r
- case Types.OTHER:\r
- case Types.REF:\r
- case Types.SQLXML:\r
- case Types.STRUCT:\r
- throw notImplemented();\r
- case Types.ARRAY:\r
- setArray(toArray(x));\r
- break;\r
- case Types.BIGINT:\r
- setLong(toLong(x));\r
- break;\r
- case Types.BINARY:\r
- case Types.LONGVARBINARY:\r
- case Types.VARBINARY:\r
- setBytes(toBytes(x));\r
- break;\r
- case Types.BIT:\r
- case Types.BOOLEAN:\r
- setBoolean(toBoolean(x));\r
- break;\r
- case Types.BLOB:\r
- if (x instanceof Blob) {\r
- setBlob((Blob) x);\r
- break;\r
- } else if (x instanceof InputStream) {\r
- setBlob((InputStream) x);\r
- }\r
- throw unsupportedCast(x.getClass(), Blob.class);\r
- case Types.DATE:\r
- setDate(toDate(x), calendar);\r
- break;\r
- case Types.DECIMAL:\r
- case Types.NUMERIC:\r
- setBigDecimal(toBigDecimal(x));\r
- break;\r
- case Types.DISTINCT:\r
- throw notImplemented();\r
- case Types.DOUBLE:\r
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes\r
- setDouble(toDouble(x));\r
- break;\r
- case Types.INTEGER:\r
- setInt(toInt(x));\r
- break;\r
- case Types.JAVA_OBJECT:\r
- setObject(x);\r
- break;\r
- case Types.LONGNVARCHAR:\r
- case Types.LONGVARCHAR:\r
- case Types.NVARCHAR:\r
- case Types.VARCHAR:\r
- case Types.CHAR:\r
- case Types.NCHAR:\r
- setString(toString(x));\r
- break;\r
- case Types.REAL:\r
- setFloat(toFloat(x));\r
- break;\r
- case Types.ROWID:\r
- if (x instanceof RowId) {\r
- setRowId((RowId) x);\r
- break;\r
- }\r
- throw unsupportedCast(x.getClass(), RowId.class);\r
- case Types.SMALLINT:\r
- setShort(toShort(x));\r
- break;\r
- case Types.TIME:\r
- setTime(toTime(x), calendar);\r
- break;\r
- case Types.TIMESTAMP:\r
- setTimestamp(toTimestamp(x), calendar);\r
- break;\r
- case Types.TINYINT:\r
- setByte(toByte(x));\r
- break;\r
- default:\r
- throw notImplemented();\r
- }\r
- }\r
-\r
- /** Similar logic to {@link #setObject}. */\r
- public static Object get(Cursor.Accessor accessor, int targetSqlType,\r
- Calendar localCalendar) throws SQLException {\r
- switch (targetSqlType) {\r
- case Types.CLOB:\r
- return accessor.getClob();\r
- case Types.DATALINK:\r
- case Types.NCLOB:\r
- case Types.REF:\r
- case Types.SQLXML:\r
- case Types.STRUCT:\r
- throw notImplemented();\r
- case Types.ARRAY:\r
- return accessor.getArray();\r
- case Types.BIGINT:\r
- final long aLong = accessor.getLong();\r
- if (aLong == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aLong;\r
- case Types.BINARY:\r
- case Types.LONGVARBINARY:\r
- case Types.VARBINARY:\r
- return accessor.getBytes();\r
- case Types.BIT:\r
- case Types.BOOLEAN:\r
- final boolean aBoolean = accessor.getBoolean();\r
- if (!aBoolean && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aBoolean;\r
- case Types.BLOB:\r
- return accessor.getBlob();\r
- case Types.DATE:\r
- return accessor.getDate(localCalendar);\r
- case Types.DECIMAL:\r
- case Types.NUMERIC:\r
- return accessor.getBigDecimal();\r
- case Types.DISTINCT:\r
- throw notImplemented();\r
- case Types.DOUBLE:\r
- case Types.FLOAT: // yes really; SQL FLOAT is up to 8 bytes\r
- final double aDouble = accessor.getDouble();\r
- if (aDouble == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aDouble;\r
- case Types.INTEGER:\r
- final int anInt = accessor.getInt();\r
- if (anInt == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return anInt;\r
- case Types.JAVA_OBJECT:\r
- case Types.OTHER:\r
- return accessor.getObject();\r
- case Types.LONGNVARCHAR:\r
- case Types.LONGVARCHAR:\r
- case Types.NVARCHAR:\r
- case Types.VARCHAR:\r
- case Types.CHAR:\r
- case Types.NCHAR:\r
- return accessor.getString();\r
- case Types.REAL:\r
- final float aFloat = accessor.getFloat();\r
- if (aFloat == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aFloat;\r
- case Types.ROWID:\r
- throw notImplemented();\r
- case Types.SMALLINT:\r
- final short aShort = accessor.getShort();\r
- if (aShort == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aShort;\r
- case Types.TIME:\r
- return accessor.getTime(localCalendar);\r
- case Types.TIMESTAMP:\r
- return accessor.getTimestamp(localCalendar);\r
- case Types.TINYINT:\r
- final byte aByte = accessor.getByte();\r
- if (aByte == 0 && accessor.wasNull()) {\r
- return null;\r
- }\r
- return aByte;\r
- default:\r
- throw notImplemented();\r
- }\r
- }\r
-\r
- public void setObject(Object x) {\r
- slots[index] = TypedValue.ofJdbc(x, calendar);\r
- }\r
-\r
- public void setNull(int sqlType) {\r
- slots[index] = wrap(ColumnMetaData.Rep.OBJECT, null);\r
- }\r
-\r
- public void setRef(Ref x) {\r
- }\r
-\r
- public void setBlob(Blob x) {\r
- InputStream iStream;\r
- try {\r
- iStream = x.getBinaryStream();\r
- int length =0;\r
- while(iStream.read() != -1)\r
- length ++;\r
- setBytes(x.getBytes(1, length));\r
- \r
- } catch (SQLException | IOException e) {\r
- throw new RuntimeException(e);\r
- }\r
- \r
- }\r
-\r
- public void setClob(Clob x) {\r
- }\r
-\r
- public void setArray(Array x) {\r
- slots[index] = wrap(ColumnMetaData.Rep.ARRAY, x);\r
- }\r
-\r
- public void setNull(int sqlType, String typeName) {\r
- }\r
-\r
- public void setURL(URL x) {\r
- }\r
-\r
- public void setObject(Object x, int targetSqlType,\r
- int scaleOrLength) {\r
- }\r
-\r
- private static RuntimeException unsupportedCast(Class<?> from, Class<?> to) {\r
- return new UnsupportedOperationException("Cannot convert from "\r
- + from.getCanonicalName() + " to " + to.getCanonicalName());\r
- }\r
-\r
- private static RuntimeException notImplemented() {\r
- return new RuntimeException("not implemented");\r
- }\r
-\r
- private static Array toArray(Object x) {\r
- if (x instanceof Array) {\r
- return (Array) x;\r
- }\r
- throw unsupportedCast(x.getClass(), Array.class);\r
- }\r
-\r
- public static BigDecimal toBigDecimal(Object x) {\r
- if (x instanceof BigDecimal) {\r
- return (BigDecimal) x;\r
- } else if (x instanceof BigInteger) {\r
- return new BigDecimal((BigInteger) x);\r
- } else if (x instanceof Number) {\r
- if (x instanceof Double || x instanceof Float) {\r
- return new BigDecimal(((Number) x).doubleValue());\r
- } else {\r
- return new BigDecimal(((Number) x).longValue());\r
- }\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? BigDecimal.ONE : BigDecimal.ZERO;\r
- } else if (x instanceof String) {\r
- return new BigDecimal((String) x);\r
- }\r
- throw unsupportedCast(x.getClass(), BigDecimal.class);\r
- }\r
-\r
- private static boolean toBoolean(Object x) {\r
- if (x instanceof Boolean) {\r
- return (Boolean) x;\r
- } else if (x instanceof Number) {\r
- return ((Number) x).intValue() != 0;\r
- } else if (x instanceof String) {\r
- String s = (String) x;\r
- if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) {\r
- return true;\r
- } else if (s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) {\r
- return false;\r
- }\r
- }\r
- throw unsupportedCast(x.getClass(), Boolean.TYPE);\r
- }\r
-\r
- private static byte toByte(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).byteValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? (byte) 1 : (byte) 0;\r
- } else if (x instanceof String) {\r
- return Byte.parseByte((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Byte.TYPE);\r
- }\r
- }\r
-\r
- private static byte[] toBytes(Object x) {\r
- if (x instanceof byte[]) {\r
- return (byte[]) x;\r
- }\r
- if (x instanceof String) {\r
- return ((String) x).getBytes(StandardCharsets.UTF_8);\r
- }\r
- throw unsupportedCast(x.getClass(), byte[].class);\r
- }\r
-\r
- private static Date toDate(Object x) {\r
- if (x instanceof String) {\r
- return Date.valueOf((String) x);\r
- }\r
- return new Date(toLong(x));\r
- }\r
-\r
- private static Time toTime(Object x) {\r
- if (x instanceof String) {\r
- return Time.valueOf((String) x);\r
- }\r
- return new Time(toLong(x));\r
- }\r
-\r
- private static Timestamp toTimestamp(Object x) {\r
- if (x instanceof String) {\r
- return Timestamp.valueOf((String) x);\r
- }\r
- return new Timestamp(toLong(x));\r
- }\r
-\r
- private static double toDouble(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).doubleValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? 1D : 0D;\r
- } else if (x instanceof String) {\r
- return Double.parseDouble((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Double.TYPE);\r
- }\r
- }\r
-\r
- private static float toFloat(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).floatValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? 1F : 0F;\r
- } else if (x instanceof String) {\r
- return Float.parseFloat((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Float.TYPE);\r
- }\r
- }\r
-\r
- private static int toInt(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).intValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? 1 : 0;\r
- } else if (x instanceof String) {\r
- return Integer.parseInt((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Integer.TYPE);\r
- }\r
- }\r
-\r
- private static long toLong(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).longValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? 1L : 0L;\r
- } else if (x instanceof String) {\r
- return Long.parseLong((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Long.TYPE);\r
- }\r
- }\r
-\r
- private static short toShort(Object x) {\r
- if (x instanceof Number) {\r
- return ((Number) x).shortValue();\r
- } else if (x instanceof Boolean) {\r
- return (Boolean) x ? (short) 1 : (short) 0;\r
- } else if (x instanceof String) {\r
- return Short.parseShort((String) x);\r
- } else {\r
- throw unsupportedCast(x.getClass(), Short.TYPE);\r
- }\r
- }\r
-\r
- private static String toString(Object x) {\r
- if (x instanceof String) {\r
- return (String) x;\r
- } else if (x instanceof Character\r
- || x instanceof Boolean) {\r
- return x.toString();\r
- }\r
- throw unsupportedCast(x.getClass(), String.class);\r
- }\r
-\r
- /** Singleton value to denote parameters that have been set to null (as\r
- * opposed to not set).\r
- *\r
- * <p>Not a valid value for a parameter.\r
- *\r
- * <p>As an enum, it is serializable by Jackson. */\r
- private enum Dummy {\r
- INSTANCE\r
- }\r
-}\r
-\r
-// End AvaticaSite.java\r
+/*
+ * 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