All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.avatica.AvaticaPreparedStatement Maven / Gradle / Ivy

/*
 * 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 com.hazelcast.com.liance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.com.hazelcast.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 com.hazelcast.org.apache.calcite.avatica;

import com.hazelcast.org.apache.calcite.avatica.Meta.Signature;
import com.hazelcast.org.apache.calcite.avatica.remote.TypedValue;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

/**
 * Implementation of {@link java.sql.PreparedStatement}
 * for the Avatica engine.
 *
 * 

This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs; * it is instantiated using {@link AvaticaFactory#newPreparedStatement}.

*/ public abstract class AvaticaPreparedStatement extends AvaticaStatement implements PreparedStatement, ParameterMetaData { private final ResultSetMetaData resultSetMetaData; private Calendar calendar; protected final TypedValue[] slots; protected final List> parameterValueBatch; /** * Creates an AvaticaPreparedStatement. * * @param connection Connection * @param h Statement handle * @param signature Result of preparing statement * @param resultSetType Result set type * @param resultSetConcurrency Result set concurrency * @param resultSetHoldability Result set holdability * @throws SQLException If fails due to underlying implementation reasons. */ protected AvaticaPreparedStatement(AvaticaConnection connection, Meta.StatementHandle h, Meta.Signature signature, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { super(connection, h, resultSetType, resultSetConcurrency, resultSetHoldability, signature); this.slots = new TypedValue[signature.parameters.size()]; this.resultSetMetaData = connection.factory.newResultSetMetaData(this, signature); this.parameterValueBatch = new ArrayList<>(); } @Override protected List getParameterValues() { return Arrays.asList(slots); } /** Returns a copy of the current parameter values. * @return A copied list of the parameter values */ protected List copyParameterValues() { // For implementing batch update, we need to make a copy of slots, not just a thin reference // to it as as list. Otherwise, subsequent setFoo(..) calls will alter the underlying array // and modify our cached TypedValue list. List copy = new ArrayList<>(slots.length); for (TypedValue value : slots) { copy.add(value); } return copy; } /** Returns a calendar in the connection's time zone, creating one the first * time this method is called. * *

Uses the calendar to offset date-time values when calling methods such * as {@link #setDate(int, Date)}. * *

A note on thread-safety. This method does not strictly need to be * {@code synchronized}, because JDBC does not promise thread safety if * different threads are accessing the same statement, or even different * objects within a particular connection. * *

The calendar returned is to be used only within this statement, and * JDBC only allows access to a statement from within one thread, so * therefore does not need to be synchronized when accessed. */ protected synchronized Calendar getCalendar() { if (calendar == null) { calendar = Calendar.getInstance(connection.getTimeZone(), Locale.ROOT); } return calendar; } protected List> getParameterValueBatch() { return this.parameterValueBatch; } // implement PreparedStatement public ResultSet executeQuery() throws SQLException { checkOpen(); this.updateCount = -1; final Signature sig = getSignature(); return getConnection().executeQueryInternal(this, sig, null, new QueryState(sig.sql), false); } public ParameterMetaData getParameterMetaData() throws SQLException { checkOpen(); return this; } public final int executeUpdate() throws SQLException { return AvaticaUtils.toSaturatedInt(executeLargeUpdate()); } public long executeLargeUpdate() throws SQLException { checkOpen(); getConnection().executeQueryInternal(this, null, null, new QueryState(getSignature().sql), true); return updateCount; } public void setNull(int parameterIndex, int sqlType) throws SQLException { getSite(parameterIndex).setNull(sqlType); } public void setBoolean(int parameterIndex, boolean x) throws SQLException { getSite(parameterIndex).setBoolean(x); } public void setByte(int parameterIndex, byte x) throws SQLException { getSite(parameterIndex).setByte(x); } public void setShort(int parameterIndex, short x) throws SQLException { getSite(parameterIndex).setShort(x); } public void setInt(int parameterIndex, int x) throws SQLException { getSite(parameterIndex).setInt(x); } public void setLong(int parameterIndex, long x) throws SQLException { getSite(parameterIndex).setLong(x); } public void setFloat(int parameterIndex, float x) throws SQLException { getSite(parameterIndex).setFloat(x); } public void setDouble(int parameterIndex, double x) throws SQLException { getSite(parameterIndex).setDouble(x); } public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { getSite(parameterIndex).setBigDecimal(x); } public void setString(int parameterIndex, String x) throws SQLException { getSite(parameterIndex).setString(x); } public void setBytes(int parameterIndex, byte[] x) throws SQLException { getSite(parameterIndex).setBytes(x); } public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { getSite(parameterIndex).setAsciiStream(x, length); } @SuppressWarnings("deprecation") public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { getSite(parameterIndex).setUnicodeStream(x, length); } public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { getSite(parameterIndex).setBinaryStream(x, length); } public void clearParameters() throws SQLException { checkOpen(); for (int i = 0; i < slots.length; i++) { slots[i] = null; } } public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { getSite(parameterIndex).setObject(x, targetSqlType); } public void setObject(int parameterIndex, Object x) throws SQLException { getSite(parameterIndex).setObject(x); } public boolean execute() throws SQLException { checkOpen(); this.updateCount = -1; // We don't know if this is actually an update or a query, so call it a query so we pass the // Signature to the server. getConnection().executeQueryInternal(this, getSignature(), null, new QueryState(getSignature().sql), false); // Result set is null for DML or DDL. // Result set is closed if user cancelled the query. return openResultSet != null && !openResultSet.isClosed(); } public void addBatch() throws SQLException { checkOpen(); // Need to copy the parameterValues into a new list, not wrap the array in a list // as getParameterValues does. this.parameterValueBatch.add(copyParameterValues()); } @Override public void clearBatch() throws SQLException { checkOpen(); this.parameterValueBatch.clear(); } @Override public int[] executeBatch() throws SQLException { return AvaticaUtils.toSaturatedInts(executeLargeBatch()); } public long[] executeLargeBatch() throws SQLException { checkOpen(); // Overriding the implementation in AvaticaStatement. try { return getConnection().executeBatchUpdateInternal(this); } finally { // If we failed to send this batch, that's a problem for the user to handle, not us. // Make sure we always clear the statements we collected to submit in one RPC. this.parameterValueBatch.clear(); } } public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { getSite(parameterIndex).setCharacterStream(reader, length); } public void setRef(int parameterIndex, Ref x) throws SQLException { getSite(parameterIndex).setRef(x); } public void setBlob(int parameterIndex, Blob x) throws SQLException { getSite(parameterIndex).setBlob(x); } public void setClob(int parameterIndex, Clob x) throws SQLException { getSite(parameterIndex).setClob(x); } public void setArray(int parameterIndex, Array x) throws SQLException { getSite(parameterIndex).setArray(x); } public ResultSetMetaData getMetaData() throws SQLException { checkOpen(); return resultSetMetaData; } public void setDate(int parameterIndex, Date x, Calendar calendar) throws SQLException { getSite(parameterIndex).setDate(x, calendar); } public void setDate(int parameterIndex, Date x) throws SQLException { setDate(parameterIndex, x, getCalendar()); } public void setTime(int parameterIndex, Time x, Calendar calendar) throws SQLException { getSite(parameterIndex).setTime(x, calendar); } public void setTime(int parameterIndex, Time x) throws SQLException { setTime(parameterIndex, x, getCalendar()); } public void setTimestamp(int parameterIndex, Timestamp x, Calendar calendar) throws SQLException { getSite(parameterIndex).setTimestamp(x, calendar); } public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { setTimestamp(parameterIndex, x, getCalendar()); } public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { getSite(parameterIndex).setNull(sqlType, typeName); } public void setURL(int parameterIndex, URL x) throws SQLException { getSite(parameterIndex).setURL(x); } public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { getSite(parameterIndex).setObject(x, targetSqlType, scaleOrLength); } public void setRowId(int parameterIndex, RowId x) throws SQLException { getSite(parameterIndex).setRowId(x); } public void setNString(int parameterIndex, String value) throws SQLException { getSite(parameterIndex).setNString(value); } public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { getSite(parameterIndex).setNCharacterStream(value, length); } public void setNClob(int parameterIndex, NClob value) throws SQLException { getSite(parameterIndex).setNClob(value); } public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { getSite(parameterIndex).setClob(reader, length); } public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { getSite(parameterIndex).setBlob(inputStream, length); } public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { getSite(parameterIndex).setNClob(reader, length); } public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { getSite(parameterIndex).setSQLXML(xmlObject); } public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { getSite(parameterIndex).setAsciiStream(x, length); } public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { getSite(parameterIndex).setBinaryStream(x, length); } public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { getSite(parameterIndex).setCharacterStream(reader, length); } public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { getSite(parameterIndex).setAsciiStream(x); } public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { getSite(parameterIndex).setBinaryStream(x); } public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { getSite(parameterIndex).setCharacterStream(reader); } public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { getSite(parameterIndex).setNCharacterStream(value); } public void setClob(int parameterIndex, Reader reader) throws SQLException { getSite(parameterIndex).setClob(reader); } public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { getSite(parameterIndex).setBlob(inputStream); } public void setNClob(int parameterIndex, Reader reader) throws SQLException { getSite(parameterIndex).setNClob(reader); } // implement ParameterMetaData protected AvaticaParameter getParameter(int param) throws SQLException { try { return getSignature().parameters.get(param - 1); } catch (IndexOutOfBoundsException e) { //noinspection ThrowableResultOfMethodCallIgnored throw AvaticaConnection.HELPER.toSQLException( AvaticaConnection.HELPER.createException( "parameter ordinal " + param + " out of range")); } } protected AvaticaSite getSite(int param) throws SQLException { checkOpen(); final AvaticaParameter parameter = getParameter(param); return new AvaticaSite(parameter, getCalendar(), param - 1, slots); } public int getParameterCount() { return getSignature().parameters.size(); } public int isNullable(int param) throws SQLException { return ParameterMetaData.parameterNullableUnknown; } public boolean isSigned(int index) throws SQLException { return getParameter(index).signed; } public int getPrecision(int index) throws SQLException { return getParameter(index).precision; } public int getScale(int index) throws SQLException { return getParameter(index).scale; } public int getParameterType(int index) throws SQLException { return getParameter(index).parameterType; } public String getParameterTypeName(int index) throws SQLException { return getParameter(index).typeName; } public String getParameterClassName(int index) throws SQLException { return getParameter(index).className; } public int getParameterMode(int param) throws SQLException { //noinspection UnusedDeclaration AvaticaParameter paramDef = getParameter(param); // forces param range check return ParameterMetaData.parameterModeIn; } } // End AvaticaPreparedStatement.java





© 2015 - 2024 Weber Informatics LLC | Privacy Policy