blob: 1ed61713362076ef2b52de27f8e1adcbf6ba7298 [file] [log] [blame]
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab
package org.mariadb.jdbc.client.result;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.*;
import java.sql.Date;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.*;
import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
import org.mariadb.jdbc.client.result.rowdecoder.BinaryRowDecoder;
import org.mariadb.jdbc.client.result.rowdecoder.RowDecoder;
import org.mariadb.jdbc.client.result.rowdecoder.TextRowDecoder;
import org.mariadb.jdbc.client.util.MutableInt;
import org.mariadb.jdbc.export.ExceptionFactory;
import org.mariadb.jdbc.message.server.ErrorPacket;
import org.mariadb.jdbc.plugin.Codec;
import org.mariadb.jdbc.plugin.codec.*;
import org.mariadb.jdbc.util.constants.ServerStatus;
/** Result-set common */
public abstract class Result implements ResultSet, Completion {
private static BinaryRowDecoder BINARY_ROW_DECODER = new BinaryRowDecoder();
private static TextRowDecoder TEXT_ROW_DECODER = new TextRowDecoder();
/** null length value */
public static final int NULL_LENGTH = -1;
private final int maxIndex;
private final boolean closeOnCompletion;
private boolean forceAlias;
private final boolean traceEnable;
/** result-set type */
protected final int resultSetType;
/** connection exception factory */
protected final ExceptionFactory exceptionFactory;
/** packet reader */
protected final org.mariadb.jdbc.client.socket.Reader reader;
/** connection context */
protected final Context context;
/** columns metadata */
protected final ColumnDecoder[] metadataList;
/** binary/text row decoder */
protected final RowDecoder rowDecoder;
/** data size */
protected int dataSize = 0;
/** rows */
protected byte[][] data;
private byte[] nullBitmap;
/** reusable row buffer decoder */
protected final StandardReadableByteBuf rowBuf = new StandardReadableByteBuf(null, 0);
private int fieldLength;
/** mutable field index */
protected MutableInt fieldIndex = new MutableInt();
private Map<String, Integer> mapper = null;
/** is fully loaded */
protected boolean loaded;
/** is an output parameter result-set */
protected boolean outputParameter;
/** current row pointer */
protected int rowPointer = -1;
/** is result-set closed */
protected boolean closed;
/** statement that initiate this result */
protected Statement statement;
/** row number limit */
protected long maxRows;
/**
* Constructor for server's data
*
* @param stmt statement that initiate this result
* @param binaryProtocol binary encoded rows
* @param maxRows row number limit
* @param metadataList columns metadata
* @param reader packet reader
* @param context connection context
* @param resultSetType result-set type
* @param closeOnCompletion close statement on completion
* @param traceEnable logger enabled
*/
public Result(
org.mariadb.jdbc.Statement stmt,
boolean binaryProtocol,
long maxRows,
ColumnDecoder[] metadataList,
org.mariadb.jdbc.client.socket.Reader reader,
Context context,
int resultSetType,
boolean closeOnCompletion,
boolean traceEnable) {
this.maxRows = maxRows;
this.statement = stmt;
this.closeOnCompletion = closeOnCompletion;
this.metadataList = metadataList;
this.maxIndex = this.metadataList.length;
this.reader = reader;
this.exceptionFactory = context.getExceptionFactory();
this.context = context;
this.resultSetType = resultSetType;
this.traceEnable = traceEnable;
if (binaryProtocol) {
rowDecoder = BINARY_ROW_DECODER;
nullBitmap = new byte[(maxIndex + 9) / 8];
} else {
rowDecoder = TEXT_ROW_DECODER;
}
}
/**
* Internal constructed result-set
*
* @param metadataList column metadata
* @param data raw data
* @param context connection context
*/
public Result(ColumnDecoder[] metadataList, byte[][] data, Context context) {
this.metadataList = metadataList;
this.maxIndex = this.metadataList.length;
this.reader = null;
this.loaded = true;
this.exceptionFactory = context.getExceptionFactory();
this.context = context;
this.data = data;
this.dataSize = data.length;
this.statement = null;
this.resultSetType = TYPE_FORWARD_ONLY;
this.closeOnCompletion = false;
this.traceEnable = false;
rowDecoder = TEXT_ROW_DECODER;
}
/**
* Read new row
*
* @return true if fully loaded
* @throws IOException if any socket error occurs
* @throws SQLException for all other type of errors
*/
@SuppressWarnings("fallthrough")
protected boolean readNext() throws IOException, SQLException {
byte[] buf = reader.readPacket(traceEnable);
switch (buf[0]) {
case (byte) 0xFF:
loaded = true;
ErrorPacket errorPacket = new ErrorPacket(reader.readableBufFromArray(buf), context);
throw exceptionFactory.create(
errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
case (byte) 0xFE:
if ((context.isEofDeprecated() && buf.length < 16777215)
|| (!context.isEofDeprecated() && buf.length < 8)) {
ReadableByteBuf readBuf = reader.readableBufFromArray(buf);
readBuf.skip(); // skip header
int serverStatus;
int warnings;
if (!context.isEofDeprecated()) {
// EOF_Packet
warnings = readBuf.readUnsignedShort();
serverStatus = readBuf.readUnsignedShort();
} else {
// OK_Packet with a 0xFE header
readBuf.readLongLengthEncodedNotNull(); // skip update count
readBuf.readLongLengthEncodedNotNull(); // skip insert id
serverStatus = readBuf.readUnsignedShort();
warnings = readBuf.readUnsignedShort();
}
outputParameter = (serverStatus & ServerStatus.PS_OUT_PARAMETERS) != 0;
context.setServerStatus(serverStatus);
context.setWarning(warnings);
loaded = true;
return false;
}
// continue reading rows
default:
if (dataSize + 1 > data.length) {
growDataArray();
}
data[dataSize++] = buf;
}
return true;
}
/**
* Skip remaining rows to keep connection state ok, without needing remaining data.
*
* @throws IOException if socket error occurs
* @throws SQLException for other kind of error
*/
@SuppressWarnings("fallthrough")
protected void skipRemaining() throws IOException, SQLException {
while (true) {
ReadableByteBuf buf = reader.readReusablePacket(traceEnable);
switch (buf.getUnsignedByte()) {
case 0xFF:
loaded = true;
ErrorPacket errorPacket = new ErrorPacket(buf, context);
throw exceptionFactory.create(
errorPacket.getMessage(), errorPacket.getSqlState(), errorPacket.getErrorCode());
case 0xFE:
if ((context.isEofDeprecated() && buf.readableBytes() < 0xffffff)
|| (!context.isEofDeprecated() && buf.readableBytes() < 8)) {
buf.skip(); // skip header
int serverStatus;
int warnings;
if (!context.isEofDeprecated()) {
// EOF_Packet
warnings = buf.readUnsignedShort();
serverStatus = buf.readUnsignedShort();
} else {
// OK_Packet with a 0xFE header
buf.readLongLengthEncodedNotNull(); // skip update count
buf.readLongLengthEncodedNotNull(); // skip insert id
serverStatus = buf.readUnsignedShort();
warnings = buf.readUnsignedShort();
}
outputParameter = (serverStatus & ServerStatus.PS_OUT_PARAMETERS) != 0;
context.setServerStatus(serverStatus);
context.setWarning(warnings);
loaded = true;
return;
}
}
}
}
/** Grow data array. */
private void growDataArray() {
int newCapacity = data.length + (data.length >> 1);
byte[][] newData = new byte[newCapacity][];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
/**
* Position resultset to next row
*
* @return true if next row exists
* @throws SQLException if any error occurs
*/
@Override
public abstract boolean next() throws SQLException;
/**
* Indicate of current result-set is a streaming result-set
*
* @return if streaming result-set
*/
public abstract boolean streaming();
/**
* Fetch remaining results.
*
* @throws SQLException if issue occurs during data retrieving
*/
public abstract void fetchRemaining() throws SQLException;
/**
* Is result-set fully loaded or still streaming
*
* @return true if fully loaded
*/
public boolean loaded() {
return loaded;
}
/**
* Does result-set contain output parameters
*
* @return true if containing output parameters
*/
public boolean isOutputParameter() {
return outputParameter;
}
/**
* Close current result-set
*
* @throws SQLException if socket error occurs
*/
@Override
public void close() throws SQLException {
if (!loaded) {
try {
skipRemaining();
} catch (IOException ioe) {
throw exceptionFactory.create("Error while streaming resultSet data", "08000", ioe);
}
}
this.closed = true;
if (closeOnCompletion) {
statement.close();
}
}
/**
* Closing result-set due to closing statement that issue command.
*
* @param lock thread locker object
* @throws SQLException if any error occurs
*/
public void closeFromStmtClose(ReentrantLock lock) throws SQLException {
lock.lock();
try {
this.fetchRemaining();
this.closed = true;
} finally {
lock.unlock();
}
}
/** Aborting result-set, without any consideration for connection state. */
public void abort() {
this.closed = true;
}
/**
* return current row RAW data
*
* @return current row RAW data
*/
protected byte[] getCurrentRowData() {
return data[0];
}
/**
* Add a row
*
* @param buf add row
*/
protected void addRowData(byte[] buf) {
if (dataSize + 1 > data.length) {
growDataArray();
}
data[dataSize++] = buf;
}
/**
* Update current row
*
* @param rawData new row
*/
protected void updateRowData(byte[] rawData) {
data[rowPointer] = rawData;
if (rawData == null) {
setNullRowBuf();
} else {
setRow(rawData);
fieldIndex.set(-1);
}
}
private void checkIndex(int index) throws SQLException {
if (index < 1 || index > maxIndex) {
throw new SQLException(
String.format("Wrong index position. Is %s but must be in 1-%s range", index, maxIndex));
}
if (rowBuf.buf == null) {
throw new SQLDataException("wrong row position", "22023");
}
}
/**
* has last data getter return a null value
*
* @return true if was null
*/
@Override
public boolean wasNull() {
return rowDecoder.wasNull(nullBitmap, fieldIndex, fieldLength);
}
@Override
public String getString(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeString(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return false;
}
return rowDecoder.decodeBoolean(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public byte getByte(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0;
}
return rowDecoder.decodeByte(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public short getShort(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0;
}
return rowDecoder.decodeShort(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public int getInt(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0;
}
return rowDecoder.decodeInt(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public long getLong(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0L;
}
return rowDecoder.decodeLong(metadataList, fieldIndex, rowBuf, fieldLength);
}
/**
* Retrieves the value of the designated column in the current row of this ResultSet object as a
* BigInteger.
*
* @param columnIndex index
* @return BigInteger value
* @throws SQLException if cannot be decoded as a BigInteger
*/
public BigInteger getBigInteger(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
BigIntegerCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
/**
* Retrieves the value of the designated column in the current row of this ResultSet object as a
* BigInteger.
*
* @param columnLabel column label
* @return BigInteger value
* @throws SQLException if cannot be decoded as a BigInteger
*/
public BigInteger getBigInteger(String columnLabel) throws SQLException {
return getBigInteger(findColumn(columnLabel));
}
@Override
public float getFloat(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0F;
}
return rowDecoder.decodeFloat(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public double getDouble(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return 0D;
}
return rowDecoder.decodeDouble(metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
@Deprecated
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
BigDecimal d =
rowDecoder.decode(
BigDecimalCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
if (d == null) return null;
return d.setScale(scale, RoundingMode.HALF_DOWN);
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
ByteArrayCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public Date getDate(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeDate(metadataList, fieldIndex, rowBuf, fieldLength, null);
}
@Override
public Time getTime(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeTime(metadataList, fieldIndex, rowBuf, fieldLength, null);
}
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeTimestamp(metadataList, fieldIndex, rowBuf, fieldLength, null);
}
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
@Deprecated
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
StreamCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public String getString(String columnLabel) throws SQLException {
return getString(findColumn(columnLabel));
}
@Override
public boolean getBoolean(String columnLabel) throws SQLException {
return getBoolean(findColumn(columnLabel));
}
@Override
public byte getByte(String columnLabel) throws SQLException {
return getByte(findColumn(columnLabel));
}
@Override
public short getShort(String columnLabel) throws SQLException {
return getShort(findColumn(columnLabel));
}
@Override
public int getInt(String columnLabel) throws SQLException {
return getInt(findColumn(columnLabel));
}
@Override
public long getLong(String columnLabel) throws SQLException {
return getLong(findColumn(columnLabel));
}
@Override
public float getFloat(String columnLabel) throws SQLException {
return getFloat(findColumn(columnLabel));
}
@Override
public double getDouble(String columnLabel) throws SQLException {
return getDouble(findColumn(columnLabel));
}
@Override
@Deprecated
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
return getBigDecimal(findColumn(columnLabel), scale);
}
@Override
public byte[] getBytes(String columnLabel) throws SQLException {
return getBytes(findColumn(columnLabel));
}
@Override
public Date getDate(String columnLabel) throws SQLException {
return getDate(findColumn(columnLabel));
}
@Override
public Time getTime(String columnLabel) throws SQLException {
return getTime(findColumn(columnLabel));
}
@Override
public Timestamp getTimestamp(String columnLabel) throws SQLException {
return getTimestamp(findColumn(columnLabel));
}
@Override
public InputStream getAsciiStream(String columnLabel) throws SQLException {
return getAsciiStream(findColumn(columnLabel));
}
@Override
@Deprecated
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
return getUnicodeStream(findColumn(columnLabel));
}
@Override
public InputStream getBinaryStream(String columnLabel) throws SQLException {
return getBinaryStream(findColumn(columnLabel));
}
@Override
public SQLWarning getWarnings() throws SQLException {
if (this.statement == null) {
return null;
}
return this.statement.getWarnings();
}
@Override
public void clearWarnings() throws SQLException {
if (this.statement != null) {
this.statement.clearWarnings();
}
}
@Override
public String getCursorName() throws SQLException {
throw exceptionFactory.notSupported("Cursors are not supported");
}
@Override
public ResultSetMetaData getMetaData() {
return new ResultSetMetaData(exceptionFactory, metadataList, context.getConf(), forceAlias);
}
@Override
public Object getObject(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.defaultDecode(
context.getConf(), metadataList, fieldIndex, rowBuf, fieldLength);
}
@Override
public Object getObject(String columnLabel) throws SQLException {
return getObject(findColumn(columnLabel));
}
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
ReaderCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public Reader getCharacterStream(String columnLabel) throws SQLException {
return getCharacterStream(findColumn(columnLabel));
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
BigDecimalCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
return getBigDecimal(findColumn(columnLabel));
}
/**
* Verify that result-set is not closed, throwing an exception if closed
*
* @throws SQLException if closed
*/
protected void checkClose() throws SQLException {
if (closed) {
throw exceptionFactory.create("Operation not permit on a closed resultSet", "HY000");
}
}
/**
* Throw an exception if result-set type is ResultSet.TYPE_FORWARD_ONLY
*
* @throws SQLException throw error if type is ResultSet.TYPE_FORWARD_ONLY
*/
protected void checkNotForwardOnly() throws SQLException {
if (resultSetType == ResultSet.TYPE_FORWARD_ONLY) {
throw exceptionFactory.create("Operation not permit on TYPE_FORWARD_ONLY resultSet", "HY000");
}
}
@Override
public boolean isBeforeFirst() throws SQLException {
checkClose();
return rowPointer == -1 && dataSize > 0;
}
@Override
public abstract boolean isAfterLast() throws SQLException;
@Override
public abstract boolean isFirst() throws SQLException;
@Override
public abstract boolean isLast() throws SQLException;
@Override
public abstract void beforeFirst() throws SQLException;
@Override
public abstract void afterLast() throws SQLException;
@Override
public abstract boolean first() throws SQLException;
@Override
public abstract boolean last() throws SQLException;
@Override
public abstract int getRow() throws SQLException;
@Override
public abstract boolean absolute(int row) throws SQLException;
@Override
public abstract boolean relative(int rows) throws SQLException;
@Override
public abstract boolean previous() throws SQLException;
@Override
public int getFetchDirection() {
return FETCH_UNKNOWN;
}
@Override
public void setFetchDirection(int direction) throws SQLException {
if (direction == FETCH_REVERSE) {
throw exceptionFactory.create(
"Invalid operation. Allowed direction are ResultSet.FETCH_FORWARD and"
+ " ResultSet.FETCH_UNKNOWN");
}
}
@Override
public int getType() {
return resultSetType;
}
@Override
public int getConcurrency() {
return CONCUR_READ_ONLY;
}
@Override
public boolean rowUpdated() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public boolean rowInserted() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public boolean rowDeleted() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNull(int columnIndex) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateByte(int columnIndex, byte x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateShort(int columnIndex, short x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateInt(int columnIndex, int x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateLong(int columnIndex, long x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateFloat(int columnIndex, float x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateDouble(int columnIndex, double x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateString(int columnIndex, String x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateDate(int columnIndex, Date x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateTime(int columnIndex, Time x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(int columnIndex, Object x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNull(String columnLabel) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBoolean(String columnLabel, boolean x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateByte(String columnLabel, byte x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateShort(String columnLabel, short x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateInt(String columnLabel, int x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateLong(String columnLabel, long x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateFloat(String columnLabel, float x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateDouble(String columnLabel, double x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateString(String columnLabel, String x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBytes(String columnLabel, byte[] x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateDate(String columnLabel, Date x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateTime(String columnLabel, Time x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x, int length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader, int length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(String columnLabel, Object x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void insertRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void deleteRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void refreshRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void cancelRowUpdates() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void moveToInsertRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void moveToCurrentRow() throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public Statement getStatement() {
return statement;
}
/**
* Update statement that initiate this result-set
*
* @param stmt statement
*/
public void setStatement(Statement stmt) {
statement = stmt;
}
/** Force using alias as name */
public void useAliasAsName() {
for (Column packet : metadataList) {
packet.useAliasAsName();
}
forceAlias = true;
}
@Override
public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
if (map == null || map.isEmpty()) {
return getObject(columnIndex);
}
throw exceptionFactory.notSupported(
"Method ResultSet.getObject(int columnIndex, Map<String, Class<?>> map) not supported for"
+ " non empty map");
}
@Override
public Ref getRef(int columnIndex) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getRef not supported");
}
@Override
public Blob getBlob(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
BlobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
ClobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public Array getArray(int columnIndex) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getArray not supported");
}
@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
if (map == null || map.isEmpty()) {
return getObject(columnLabel);
}
throw exceptionFactory.notSupported(
"Method ResultSet.getObject(String columnLabel, Map<String, Class<?>> map) not supported");
}
@Override
public Ref getRef(String columnLabel) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getRef not supported");
}
@Override
public Blob getBlob(String columnLabel) throws SQLException {
return getBlob(findColumn(columnLabel));
}
@Override
public Clob getClob(String columnLabel) throws SQLException {
return getClob(findColumn(columnLabel));
}
@Override
public Array getArray(String columnLabel) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getArray not supported");
}
@Override
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeDate(metadataList, fieldIndex, rowBuf, fieldLength, cal);
}
@Override
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
return getDate(findColumn(columnLabel), cal);
}
@Override
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeTime(metadataList, fieldIndex, rowBuf, fieldLength, cal);
}
@Override
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
return getTime(findColumn(columnLabel), cal);
}
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decodeTimestamp(metadataList, fieldIndex, rowBuf, fieldLength, cal);
}
@Override
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
return getTimestamp(findColumn(columnLabel), cal);
}
@Override
public URL getURL(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
String s =
rowDecoder.decode(
StringCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
if (s == null) return null;
try {
return new URL(s);
} catch (MalformedURLException e) {
throw exceptionFactory.create(String.format("Could not parse '%s' as URL", s));
}
}
@Override
public URL getURL(String columnLabel) throws SQLException {
return getURL(findColumn(columnLabel));
}
@Override
public void updateRef(int columnIndex, Ref x) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.updateRef not supported");
}
@Override
public void updateRef(String columnLabel, Ref x) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.updateRef not supported");
}
@Override
public void updateBlob(int columnIndex, Blob x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBlob(String columnLabel, Blob x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(int columnIndex, Clob x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(String columnLabel, Clob x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateArray(int columnIndex, Array x) throws SQLException {
throw exceptionFactory.notSupported("Array are not supported");
}
@Override
public void updateArray(String columnLabel, Array x) throws SQLException {
throw exceptionFactory.notSupported("Array are not supported");
}
@Override
public RowId getRowId(int columnIndex) throws SQLException {
throw exceptionFactory.notSupported("RowId are not supported");
}
@Override
public RowId getRowId(String columnLabel) throws SQLException {
throw exceptionFactory.notSupported("RowId are not supported");
}
@Override
public void updateRowId(int columnIndex, RowId x) throws SQLException {
throw exceptionFactory.notSupported("RowId are not supported");
}
@Override
public void updateRowId(String columnLabel, RowId x) throws SQLException {
throw exceptionFactory.notSupported("RowId are not supported");
}
@Override
public int getHoldability() {
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@Override
public boolean isClosed() {
return closed;
}
@Override
public void updateNString(int columnIndex, String nString) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNString(String columnLabel, String nString) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public NClob getNClob(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return (NClob)
rowDecoder.decode(ClobCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public NClob getNClob(String columnLabel) throws SQLException {
return getNClob(findColumn(columnLabel));
}
@Override
public SQLXML getSQLXML(int columnIndex) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getSQLXML not supported");
}
@Override
public SQLXML getSQLXML(String columnLabel) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.getSQLXML not supported");
}
@Override
public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.updateSQLXML not supported");
}
@Override
public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
throw exceptionFactory.notSupported("Method ResultSet.updateSQLXML not supported");
}
@Override
public String getNString(int columnIndex) throws SQLException {
return getString(columnIndex);
}
@Override
public String getNString(String columnLabel) throws SQLException {
return getString(columnLabel);
}
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
if (fieldLength == NULL_LENGTH) {
return null;
}
return rowDecoder.decode(
ReaderCodec.INSTANCE, null, rowBuf, fieldLength, metadataList, fieldIndex);
}
@Override
public Reader getNCharacterStream(String columnLabel) throws SQLException {
return getNCharacterStream(findColumn(columnLabel));
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream, long length)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(int columnIndex, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateClob(String columnLabel, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateNClob(String columnLabel, Reader reader) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
@SuppressWarnings("unchecked")
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
checkIndex(columnIndex);
fieldLength =
rowDecoder.setPosition(
columnIndex - 1, fieldIndex, maxIndex, rowBuf, nullBitmap, metadataList);
Calendar calendar = null;
if (wasNull()) {
if (type.isPrimitive()) {
throw new SQLException(
String.format("Cannot return null for primitive %s", type.getName()));
}
return null;
}
Configuration conf = context.getConf();
ColumnDecoder column = metadataList[columnIndex - 1];
// type generic, return "natural" java type
if (Object.class.equals(type) || type == null) {
return (T) rowDecoder.defaultDecode(conf, metadataList, fieldIndex, rowBuf, fieldLength);
}
for (Codec<?> codec : conf.codecs()) {
if (codec.canDecode(column, type)) {
return rowDecoder.decode(
(Codec<T>) codec, calendar, rowBuf, fieldLength, metadataList, fieldIndex);
}
}
rowBuf.skip(fieldLength);
throw new SQLException(
String.format("Type %s not supported type for %s type", type, column.getType().name()));
}
@Override
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
return getObject(findColumn(columnLabel), type);
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
if (isWrapperFor(iface)) {
return iface.cast(this);
}
throw new SQLException("The receiver is not a wrapper for " + iface.getName());
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface.isInstance(this);
}
@Override
public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
@Override
public void updateObject(String columnLabel, Object x, SQLType targetSqlType)
throws SQLException {
throw exceptionFactory.notSupported("Not supported when using CONCUR_READ_ONLY concurrency");
}
/** Set row buffer to null (no row) */
protected void setNullRowBuf() {
rowBuf.buf(null, 0, 0);
}
/**
* set row decoder to current row data
*
* @param row row
*/
public void setRow(byte[] row) {
rowBuf.buf(row, row.length, 0);
fieldIndex.set(-1);
}
public int findColumn(String label) throws SQLException {
if (label == null) throw new SQLException("null is not a valid label value");
if (mapper == null) {
mapper = new HashMap<>();
for (int i = 0; i < maxIndex; i++) {
Column ci = metadataList[i];
String columnAlias = ci.getColumnAlias();
if (columnAlias != null) {
columnAlias = columnAlias.toLowerCase(Locale.ROOT);
mapper.putIfAbsent(columnAlias, i + 1);
String tableAlias = ci.getTableAlias();
String tableLabel = tableAlias != null ? tableAlias : ci.getTable();
mapper.putIfAbsent(tableLabel.toLowerCase(Locale.ROOT) + "." + columnAlias, i + 1);
}
}
}
Integer ind = mapper.get(label.toLowerCase(Locale.ROOT));
if (ind == null) {
String keys = Arrays.toString(mapper.keySet().toArray(new String[0]));
throw new SQLException(String.format("Unknown label '%s'. Possible value %s", label, keys));
}
return ind;
}
}