Added:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRow.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRow.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetRow.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataCursor.java
Removed:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java
Modified:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowData.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataKeyset.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataStatic.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/UpdatableResultSet.java
Log:
Some renames around the Row(Holder) classes.
Row navigation now causes any streams/readers open on the result set
to be closed, as in some cases we're reading directly from a shared network
packet and it will be overwritten by the "next" row.
Copied: branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRow.java (from rev 6449, branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java)
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java 2007-06-14 16:11:19 UTC (rev 6449)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRow.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -0,0 +1,696 @@
+/*
+ Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ There are special exceptions to the terms and conditions of the GPL
+ as it is applied to this software. View the full text of the
+ exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
+ software distribution.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+package com.mysql.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * A RowHolder implementation that holds one row packet (which is re-used by the
+ * driver, and thus saves memory allocations), and tries when possible to avoid
+ * allocations to break out the results as individual byte[]s.
+ *
+ * (this isn't possible when doing things like reading floating point values).
+ *
+ * @version $Id: $
+ */
+public class BufferRow extends ResultSetRow {
+ private Buffer rowFromServer;
+
+ /**
+ * The beginning of the row packet
+ */
+ private int homePosition = 0;
+
+ /**
+ * The last-requested index, used as an optimization, if you ask for the
+ * same index, we won't seek to find it. If you ask for an index that is >
+ * than the last one requested, we start seeking from the last requested
+ * index.
+ */
+ private int lastRequestedIndex = -1;
+
+ /**
+ * The position of the last-requested index, optimization in concert with
+ * lastRequestedIndex.
+ */
+ private int lastRequestedPos;
+
+ /**
+ * The metadata of the fields of this result set.
+ */
+ private Field[] metadata;
+
+ /**
+ * Is this a row from a server-side prepared statement? If so, they're
+ * encoded differently, so we have different ways of finding where each
+ * column is, and unpacking them.
+ */
+ private boolean isBinaryEncoded;
+
+ /**
+ * If binary-encoded, the NULL status of each column is at the beginning of
+ * the row, so we
+ */
+ private boolean[] isNull;
+
+ private List openStreams;
+
+ public BufferRow(Buffer buf, Field[] fields, boolean isBinaryEncoded)
+ throws SQLException {
+ this.rowFromServer = buf;
+ this.metadata = fields;
+ this.isBinaryEncoded = isBinaryEncoded;
+ this.homePosition = this.rowFromServer.getPosition();
+
+ if (fields != null) {
+ setMetadata(fields);
+ }
+ }
+
+ public synchronized void closeOpenStreams() {
+ if (this.openStreams != null) {
+ // This would've looked slicker in a "for" loop
+ // but we want to skip over streams that fail to
+ // close (they probably won't ever)
+ // to be more robust and close everything we _can_
+
+ Iterator iter = this.openStreams.iterator();
+
+ while (iter.hasNext()) {
+
+ try {
+ ((InputStream) iter.next()).close();
+ } catch (IOException e) {
+ // ignore - it can't really happen in this case
+ }
+ }
+
+ this.openStreams.clear();
+ }
+ }
+
+ private int findAndSeekToOffset(int index) throws SQLException {
+ if (!this.isBinaryEncoded) {
+
+ if (index == 0) {
+ this.lastRequestedIndex = 0;
+ this.lastRequestedPos = this.homePosition;
+ this.rowFromServer.setPosition(this.homePosition);
+
+ return 0;
+ }
+
+ if (index == this.lastRequestedIndex) {
+ this.rowFromServer.setPosition(this.lastRequestedPos);
+
+ return this.lastRequestedPos;
+ }
+
+ int startingIndex = 0;
+
+ if (index > this.lastRequestedIndex) {
+ startingIndex = this.lastRequestedIndex;
+ this.rowFromServer.setPosition(this.lastRequestedPos);
+ } else {
+ this.rowFromServer.setPosition(this.homePosition);
+ }
+
+ for (int i = startingIndex; i < index; i++) {
+ this.rowFromServer.fastSkipLenByteArray();
+ }
+
+ this.lastRequestedIndex = index;
+ this.lastRequestedPos = this.rowFromServer.getPosition();
+
+ return this.lastRequestedPos;
+ }
+
+ return findAndSeekToOffsetForBinaryEncoding(index);
+ }
+
+ private int findAndSeekToOffsetForBinaryEncoding(int index)
+ throws SQLException {
+ if (index == 0) {
+ this.lastRequestedIndex = 0;
+ this.lastRequestedPos = this.homePosition;
+
+ return 0;
+ }
+
+ if (index == this.lastRequestedIndex) {
+ this.rowFromServer.setPosition(this.lastRequestedPos);
+
+ return this.lastRequestedPos;
+ }
+
+ int startingIndex = 0;
+
+ if (index > this.lastRequestedIndex) {
+ startingIndex = this.lastRequestedIndex;
+ this.rowFromServer.setPosition(this.lastRequestedPos);
+ } else {
+ this.rowFromServer.setPosition(this.homePosition);
+ }
+
+ for (int i = startingIndex; i < index; i++) {
+ if (this.isNull[i]) {
+ continue;
+ }
+
+ int curPosition = this.rowFromServer.getPosition();
+
+ switch (this.metadata[i].getMysqlType()) {
+ case MysqlDefs.FIELD_TYPE_NULL:
+ break; // for dummy binds
+
+ case MysqlDefs.FIELD_TYPE_TINY:
+
+ this.rowFromServer.setPosition(curPosition + 1);
+ break;
+
+ case MysqlDefs.FIELD_TYPE_SHORT:
+ case MysqlDefs.FIELD_TYPE_YEAR:
+ this.rowFromServer.setPosition(curPosition + 2);
+
+ break;
+ case MysqlDefs.FIELD_TYPE_LONG:
+ case MysqlDefs.FIELD_TYPE_INT24:
+ this.rowFromServer.setPosition(curPosition + 4);
+
+ break;
+ case MysqlDefs.FIELD_TYPE_LONGLONG:
+ this.rowFromServer.setPosition(curPosition + 8);
+
+ break;
+ case MysqlDefs.FIELD_TYPE_FLOAT:
+ this.rowFromServer.setPosition(curPosition + 4);
+
+ break;
+ case MysqlDefs.FIELD_TYPE_DOUBLE:
+ this.rowFromServer.setPosition(curPosition + 8);
+
+ break;
+ case MysqlDefs.FIELD_TYPE_TIME:
+ this.rowFromServer.fastSkipLenByteArray();
+
+ break;
+ case MysqlDefs.FIELD_TYPE_DATE:
+
+ this.rowFromServer.fastSkipLenByteArray();
+
+ break;
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ this.rowFromServer.fastSkipLenByteArray();
+
+ break;
+ case MysqlDefs.FIELD_TYPE_TINY_BLOB:
+ case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
+ case MysqlDefs.FIELD_TYPE_LONG_BLOB:
+ case MysqlDefs.FIELD_TYPE_BLOB:
+ case MysqlDefs.FIELD_TYPE_VAR_STRING:
+ case MysqlDefs.FIELD_TYPE_VARCHAR:
+ case MysqlDefs.FIELD_TYPE_STRING:
+ case MysqlDefs.FIELD_TYPE_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_GEOMETRY:
+ case MysqlDefs.FIELD_TYPE_BIT:
+ this.rowFromServer.fastSkipLenByteArray();
+
+ break;
+
+ default:
+ throw SQLError.createSQLException(Messages
+ .getString("MysqlIO.97") //$NON-NLS-1$
+ + this.metadata[i].getMysqlType()
+ + Messages.getString("MysqlIO.98")
+ + (i + 1)
+ + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
+ + this.metadata.length
+ + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
+ }
+
+ this.lastRequestedIndex = index;
+ this.lastRequestedPos = this.rowFromServer.getPosition();
+
+ return this.lastRequestedPos;
+ }
+
+ public synchronized InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ InputStream stream = new ByteArrayInputStream(this.rowFromServer
+ .getByteBuffer(), offset, (int) length);
+
+ if (this.openStreams == null) {
+ this.openStreams = new LinkedList();
+ }
+
+ return stream;
+ }
+
+ public byte[] getColumnValue(int index) throws SQLException {
+ findAndSeekToOffset(index);
+
+ if (!this.isBinaryEncoded) {
+ return this.rowFromServer.readLenByteArray(0);
+ }
+
+ if (this.isNull[index]) {
+ return null;
+ }
+
+ switch (this.metadata[index].getMysqlType()) {
+ case MysqlDefs.FIELD_TYPE_NULL:
+ return null;
+
+ case MysqlDefs.FIELD_TYPE_TINY:
+ return new byte[] { this.rowFromServer.readByte() };
+
+ case MysqlDefs.FIELD_TYPE_SHORT:
+ case MysqlDefs.FIELD_TYPE_YEAR:
+ return this.rowFromServer.getBytes(2);
+
+ case MysqlDefs.FIELD_TYPE_LONG:
+ case MysqlDefs.FIELD_TYPE_INT24:
+ return this.rowFromServer.getBytes(4);
+
+ case MysqlDefs.FIELD_TYPE_LONGLONG:
+ return this.rowFromServer.getBytes(8);
+
+ case MysqlDefs.FIELD_TYPE_FLOAT:
+ return this.rowFromServer.getBytes(4);
+
+ case MysqlDefs.FIELD_TYPE_DOUBLE:
+ return this.rowFromServer.getBytes(8);
+
+ case MysqlDefs.FIELD_TYPE_TIME:
+ case MysqlDefs.FIELD_TYPE_DATE:
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ case MysqlDefs.FIELD_TYPE_TINY_BLOB:
+ case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
+ case MysqlDefs.FIELD_TYPE_LONG_BLOB:
+ case MysqlDefs.FIELD_TYPE_BLOB:
+ case MysqlDefs.FIELD_TYPE_VAR_STRING:
+ case MysqlDefs.FIELD_TYPE_VARCHAR:
+ case MysqlDefs.FIELD_TYPE_STRING:
+ case MysqlDefs.FIELD_TYPE_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_GEOMETRY:
+ case MysqlDefs.FIELD_TYPE_BIT:
+ return this.rowFromServer.readLenByteArray(0);
+
+ default:
+ throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$
+ + this.metadata[index].getMysqlType()
+ + Messages.getString("MysqlIO.98")
+ + (index + 1)
+ + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
+ + this.metadata.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
+ }
+
+ public int getInt(int columnIndex) throws SQLException {
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return StringUtils.getInt(this.rowFromServer.getByteBuffer(), offset,
+ offset + (int) length);
+ }
+
+ public long getLong(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return StringUtils.getLong(this.rowFromServer.getByteBuffer(), offset,
+ offset + (int) length);
+ }
+
+ public double getNativeDouble(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return getNativeDouble(this.rowFromServer.getByteBuffer(), offset);
+ }
+
+ public float getNativeFloat(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return getNativeFloat(this.rowFromServer.getByteBuffer(), offset);
+ }
+
+ public int getNativeInt(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return getNativeInt(this.rowFromServer.getByteBuffer(), offset);
+ }
+
+ public long getNativeLong(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return getNativeLong(this.rowFromServer.getByteBuffer(), offset);
+ }
+
+ public short getNativeShort(int columnIndex) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return getNativeShort(this.rowFromServer.getByteBuffer(), offset);
+ }
+
+ public Timestamp getNativeTimestamp(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeTimestamp(this.rowFromServer.getByteBuffer(), offset,
+ (int) length, targetCalendar, tz, rollForward, conn, rs);
+ }
+
+ public Reader getReader(int columnIndex) throws SQLException {
+ InputStream stream = getBinaryInputStream(columnIndex);
+
+ if (stream == null) {
+ return null;
+ }
+
+ try {
+ return new InputStreamReader(stream, this.metadata[columnIndex]
+ .getCharacterSet());
+ } catch (UnsupportedEncodingException e) {
+ SQLException sqlEx = SQLError.createSQLException("");
+
+ sqlEx.initCause(e);
+
+ throw sqlEx;
+ }
+ }
+
+ public String getString(int index, String encoding, ConnectionImpl conn)
+ throws SQLException {
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ if (length == 0) {
+ return "";
+ }
+
+ // TODO: I don't like this, would like to push functionality back
+ // to the buffer class somehow
+
+ int offset = this.rowFromServer.getPosition();
+
+ return getString(encoding, conn, this.rowFromServer.getByteBuffer(),
+ offset, (int) length);
+ }
+
+ public Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getTimeFast(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, length, targetCalendar, tz, rollForward, conn, rs);
+ }
+
+ public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getTimestampFast(columnIndex,
+ this.rowFromServer.getByteBuffer(), offset, length, targetCalendar, tz,
+ rollForward, conn, rs);
+ }
+
+ public boolean isFloatingPointNumber(int index) throws SQLException {
+ if (this.isBinaryEncoded) {
+ switch (this.metadata[index].getSQLType()) {
+ case Types.FLOAT:
+ case Types.DOUBLE:
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return false;
+ }
+
+ if (length == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < (int) length; i++) {
+ char c = (char) this.rowFromServer.readByte();
+
+ if ((c == 'e') || (c == 'E')) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isNull(int index) throws SQLException {
+ if (!this.isBinaryEncoded) {
+ findAndSeekToOffset(index);
+
+ return this.rowFromServer.readFieldLength() == Buffer.NULL_LENGTH;
+ }
+
+ return this.isNull[index];
+ }
+
+ public long length(int index) throws SQLException {
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return length;
+ }
+
+ public void setColumnValue(int index, byte[] value) throws SQLException {
+ throw new OperationNotSupportedException();
+ }
+
+ public void setMetadata(Field[] f) throws SQLException {
+ super.setMetadata(f);
+
+ if (this.isBinaryEncoded) {
+ setupIsNullBitmask();
+ }
+ }
+
+ /**
+ * Unpacks the bitmask at the head of the row packet that tells us what
+ * columns hold null values, and sets the "home" position directly after the
+ * bitmask.
+ */
+ private void setupIsNullBitmask() throws SQLException {
+ int nullCount = (this.metadata.length + 9) / 8;
+
+ byte[] nullBitMask = new byte[nullCount];
+
+ for (int i = 0; i < nullCount; i++) {
+ nullBitMask[i] = this.rowFromServer.readByte();
+ }
+
+ this.homePosition = this.rowFromServer.getPosition();
+
+ this.isNull = new boolean[this.metadata.length];
+
+ int nullMaskPos = 0;
+ int bit = 4; // first two bits are reserved for future use
+
+ for (int i = 0; i < this.metadata.length; i++) {
+
+ this.isNull[i] = ((nullBitMask[nullMaskPos] & bit) != 0);
+
+ if (((bit <<= 1) & 255) == 0) {
+ bit = 1; /* To next byte */
+
+ nullMaskPos++;
+ }
+ }
+ }
+
+ public Date getDateFast(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getDateFast(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, length, conn, rs);
+ }
+
+ public java.sql.Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeDate(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, (int) length, conn, rs);
+ }
+
+ public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
+ int jdbcType, int mysqlType, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeDateTimeValue(columnIndex, this.rowFromServer
+ .getByteBuffer(), offset, (int) length, targetCalendar, jdbcType,
+ mysqlType, tz, rollForward, conn, rs);
+ }
+
+ public Time getNativeTime(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeTime(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, (int) length, targetCalendar, tz, rollForward, conn, rs);
+ }
+}
\ No newline at end of file
Deleted: branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1,696 +0,0 @@
-/*
- Copyright (C) 2007 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- There are special exceptions to the terms and conditions of the GPL
- as it is applied to this software. View the full text of the
- exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
- software distribution.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- */
-package com.mysql.jdbc;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.sql.Date;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.TimeZone;
-
-/**
- * A RowHolder implementation that holds one row packet (which is re-used by the
- * driver, and thus saves memory allocations), and tries when possible to avoid
- * allocations to break out the results as individual byte[]s.
- *
- * (this isn't possible when doing things like reading floating point values).
- *
- * @version $Id: $
- */
-public class BufferRowHolder extends RowHolder {
- private Buffer rowFromServer;
-
- /**
- * The beginning of the row packet
- */
- private int homePosition = 0;
-
- /**
- * The last-requested index, used as an optimization, if you ask for the
- * same index, we won't seek to find it. If you ask for an index that is >
- * than the last one requested, we start seeking from the last requested
- * index.
- */
- private int lastRequestedIndex = -1;
-
- /**
- * The position of the last-requested index, optimization in concert with
- * lastRequestedIndex.
- */
- private int lastRequestedPos;
-
- /**
- * The metadata of the fields of this result set.
- */
- private Field[] metadata;
-
- /**
- * Is this a row from a server-side prepared statement? If so, they're
- * encoded differently, so we have different ways of finding where each
- * column is, and unpacking them.
- */
- private boolean isBinaryEncoded;
-
- /**
- * If binary-encoded, the NULL status of each column is at the beginning of
- * the row, so we
- */
- private boolean[] isNull;
-
- private List openStreams;
-
- public BufferRowHolder(Buffer buf, Field[] fields, boolean isBinaryEncoded)
- throws SQLException {
- this.rowFromServer = buf;
- this.metadata = fields;
- this.isBinaryEncoded = isBinaryEncoded;
- this.homePosition = this.rowFromServer.getPosition();
-
- if (fields != null) {
- setMetadata(fields);
- }
- }
-
- public synchronized void closeOpenStreams() {
- if (this.openStreams != null) {
- // This would've looked slicker in a "for" loop
- // but we want to skip over streams that fail to
- // close (they probably won't ever)
- // to be more robust and close everything we _can_
-
- Iterator iter = this.openStreams.iterator();
-
- while (iter.hasNext()) {
-
- try {
- ((InputStream) iter.next()).close();
- } catch (IOException e) {
- // ignore - it can't really happen in this case
- }
- }
-
- this.openStreams.clear();
- }
- }
-
- private int findAndSeekToOffset(int index) throws SQLException {
- if (!this.isBinaryEncoded) {
-
- if (index == 0) {
- this.lastRequestedIndex = 0;
- this.lastRequestedPos = this.homePosition;
- this.rowFromServer.setPosition(this.homePosition);
-
- return 0;
- }
-
- if (index == this.lastRequestedIndex) {
- this.rowFromServer.setPosition(this.lastRequestedPos);
-
- return this.lastRequestedPos;
- }
-
- int startingIndex = 0;
-
- if (index > this.lastRequestedIndex) {
- startingIndex = this.lastRequestedIndex;
- this.rowFromServer.setPosition(this.lastRequestedPos);
- } else {
- this.rowFromServer.setPosition(this.homePosition);
- }
-
- for (int i = startingIndex; i < index; i++) {
- this.rowFromServer.fastSkipLenByteArray();
- }
-
- this.lastRequestedIndex = index;
- this.lastRequestedPos = this.rowFromServer.getPosition();
-
- return this.lastRequestedPos;
- }
-
- return findAndSeekToOffsetForBinaryEncoding(index);
- }
-
- private int findAndSeekToOffsetForBinaryEncoding(int index)
- throws SQLException {
- if (index == 0) {
- this.lastRequestedIndex = 0;
- this.lastRequestedPos = this.homePosition;
-
- return 0;
- }
-
- if (index == this.lastRequestedIndex) {
- this.rowFromServer.setPosition(this.lastRequestedPos);
-
- return this.lastRequestedPos;
- }
-
- int startingIndex = 0;
-
- if (index > this.lastRequestedIndex) {
- startingIndex = this.lastRequestedIndex;
- this.rowFromServer.setPosition(this.lastRequestedPos);
- } else {
- this.rowFromServer.setPosition(this.homePosition);
- }
-
- for (int i = startingIndex; i < index; i++) {
- if (this.isNull[i]) {
- continue;
- }
-
- int curPosition = this.rowFromServer.getPosition();
-
- switch (this.metadata[i].getMysqlType()) {
- case MysqlDefs.FIELD_TYPE_NULL:
- break; // for dummy binds
-
- case MysqlDefs.FIELD_TYPE_TINY:
-
- this.rowFromServer.setPosition(curPosition + 1);
- break;
-
- case MysqlDefs.FIELD_TYPE_SHORT:
- case MysqlDefs.FIELD_TYPE_YEAR:
- this.rowFromServer.setPosition(curPosition + 2);
-
- break;
- case MysqlDefs.FIELD_TYPE_LONG:
- case MysqlDefs.FIELD_TYPE_INT24:
- this.rowFromServer.setPosition(curPosition + 4);
-
- break;
- case MysqlDefs.FIELD_TYPE_LONGLONG:
- this.rowFromServer.setPosition(curPosition + 8);
-
- break;
- case MysqlDefs.FIELD_TYPE_FLOAT:
- this.rowFromServer.setPosition(curPosition + 4);
-
- break;
- case MysqlDefs.FIELD_TYPE_DOUBLE:
- this.rowFromServer.setPosition(curPosition + 8);
-
- break;
- case MysqlDefs.FIELD_TYPE_TIME:
- this.rowFromServer.fastSkipLenByteArray();
-
- break;
- case MysqlDefs.FIELD_TYPE_DATE:
-
- this.rowFromServer.fastSkipLenByteArray();
-
- break;
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- this.rowFromServer.fastSkipLenByteArray();
-
- break;
- case MysqlDefs.FIELD_TYPE_TINY_BLOB:
- case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
- case MysqlDefs.FIELD_TYPE_LONG_BLOB:
- case MysqlDefs.FIELD_TYPE_BLOB:
- case MysqlDefs.FIELD_TYPE_VAR_STRING:
- case MysqlDefs.FIELD_TYPE_VARCHAR:
- case MysqlDefs.FIELD_TYPE_STRING:
- case MysqlDefs.FIELD_TYPE_DECIMAL:
- case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
- case MysqlDefs.FIELD_TYPE_GEOMETRY:
- case MysqlDefs.FIELD_TYPE_BIT:
- this.rowFromServer.fastSkipLenByteArray();
-
- break;
-
- default:
- throw SQLError.createSQLException(Messages
- .getString("MysqlIO.97") //$NON-NLS-1$
- + this.metadata[i].getMysqlType()
- + Messages.getString("MysqlIO.98")
- + (i + 1)
- + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
- + this.metadata.length
- + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
-
- this.lastRequestedIndex = index;
- this.lastRequestedPos = this.rowFromServer.getPosition();
-
- return this.lastRequestedPos;
- }
-
- public synchronized InputStream getBinaryInputStream(int columnIndex)
- throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- InputStream stream = new ByteArrayInputStream(this.rowFromServer
- .getByteBuffer(), offset, (int) length);
-
- if (this.openStreams == null) {
- this.openStreams = new LinkedList();
- }
-
- return stream;
- }
-
- public byte[] getColumnValue(int index) throws SQLException {
- findAndSeekToOffset(index);
-
- if (!this.isBinaryEncoded) {
- return this.rowFromServer.readLenByteArray(0);
- }
-
- if (this.isNull[index]) {
- return null;
- }
-
- switch (this.metadata[index].getMysqlType()) {
- case MysqlDefs.FIELD_TYPE_NULL:
- return null;
-
- case MysqlDefs.FIELD_TYPE_TINY:
- return new byte[] { this.rowFromServer.readByte() };
-
- case MysqlDefs.FIELD_TYPE_SHORT:
- case MysqlDefs.FIELD_TYPE_YEAR:
- return this.rowFromServer.getBytes(2);
-
- case MysqlDefs.FIELD_TYPE_LONG:
- case MysqlDefs.FIELD_TYPE_INT24:
- return this.rowFromServer.getBytes(4);
-
- case MysqlDefs.FIELD_TYPE_LONGLONG:
- return this.rowFromServer.getBytes(8);
-
- case MysqlDefs.FIELD_TYPE_FLOAT:
- return this.rowFromServer.getBytes(4);
-
- case MysqlDefs.FIELD_TYPE_DOUBLE:
- return this.rowFromServer.getBytes(8);
-
- case MysqlDefs.FIELD_TYPE_TIME:
- case MysqlDefs.FIELD_TYPE_DATE:
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- case MysqlDefs.FIELD_TYPE_TINY_BLOB:
- case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
- case MysqlDefs.FIELD_TYPE_LONG_BLOB:
- case MysqlDefs.FIELD_TYPE_BLOB:
- case MysqlDefs.FIELD_TYPE_VAR_STRING:
- case MysqlDefs.FIELD_TYPE_VARCHAR:
- case MysqlDefs.FIELD_TYPE_STRING:
- case MysqlDefs.FIELD_TYPE_DECIMAL:
- case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
- case MysqlDefs.FIELD_TYPE_GEOMETRY:
- case MysqlDefs.FIELD_TYPE_BIT:
- return this.rowFromServer.readLenByteArray(0);
-
- default:
- throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$
- + this.metadata[index].getMysqlType()
- + Messages.getString("MysqlIO.98")
- + (index + 1)
- + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
- + this.metadata.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
-
- public int getInt(int columnIndex) throws SQLException {
-
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return StringUtils.getInt(this.rowFromServer.getByteBuffer(), offset,
- offset + (int) length);
- }
-
- public long getLong(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return StringUtils.getLong(this.rowFromServer.getByteBuffer(), offset,
- offset + (int) length);
- }
-
- public double getNativeDouble(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return getNativeDouble(this.rowFromServer.getByteBuffer(), offset);
- }
-
- public float getNativeFloat(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return getNativeFloat(this.rowFromServer.getByteBuffer(), offset);
- }
-
- public int getNativeInt(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return getNativeInt(this.rowFromServer.getByteBuffer(), offset);
- }
-
- public long getNativeLong(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return getNativeLong(this.rowFromServer.getByteBuffer(), offset);
- }
-
- public short getNativeShort(int columnIndex) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return getNativeShort(this.rowFromServer.getByteBuffer(), offset);
- }
-
- public Timestamp getNativeTimestamp(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- return getNativeTimestamp(this.rowFromServer.getByteBuffer(), offset,
- (int) length, targetCalendar, tz, rollForward, conn, rs);
- }
-
- public Reader getReader(int columnIndex) throws SQLException {
- InputStream stream = getBinaryInputStream(columnIndex);
-
- if (stream == null) {
- return null;
- }
-
- try {
- return new InputStreamReader(stream, this.metadata[columnIndex]
- .getCharacterSet());
- } catch (UnsupportedEncodingException e) {
- SQLException sqlEx = SQLError.createSQLException("");
-
- sqlEx.initCause(e);
-
- throw sqlEx;
- }
- }
-
- public String getString(int index, String encoding, ConnectionImpl conn)
- throws SQLException {
- findAndSeekToOffset(index);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- if (length == 0) {
- return "";
- }
-
- // TODO: I don't like this, would like to push functionality back
- // to the buffer class somehow
-
- int offset = this.rowFromServer.getPosition();
-
- return getString(encoding, conn, this.rowFromServer.getByteBuffer(),
- offset, (int) length);
- }
-
- public Time getTimeFast(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- if (isNull(columnIndex)) {
- return null;
- }
-
- int offset = findAndSeekToOffset(columnIndex);
-
- int length = (int) this.rowFromServer.readFieldLength();
-
- return getTimeFast(columnIndex, this.rowFromServer.getByteBuffer(),
- offset, length, targetCalendar, tz, rollForward, conn, rs);
- }
-
- public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- if (isNull(columnIndex)) {
- return null;
- }
-
- int offset = findAndSeekToOffset(columnIndex);
-
- int length = (int) this.rowFromServer.readFieldLength();
-
- return getTimestampFast(columnIndex,
- this.rowFromServer.getByteBuffer(), offset, length, targetCalendar, tz,
- rollForward, conn, rs);
- }
-
- public boolean isFloatingPointNumber(int index) throws SQLException {
- if (this.isBinaryEncoded) {
- switch (this.metadata[index].getSQLType()) {
- case Types.FLOAT:
- case Types.DOUBLE:
- case Types.DECIMAL:
- case Types.NUMERIC:
- return true;
- default:
- return false;
- }
- }
-
- findAndSeekToOffset(index);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return false;
- }
-
- if (length == 0) {
- return false;
- }
-
- for (int i = 0; i < (int) length; i++) {
- char c = (char) this.rowFromServer.readByte();
-
- if ((c == 'e') || (c == 'E')) {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean isNull(int index) throws SQLException {
- if (!this.isBinaryEncoded) {
- findAndSeekToOffset(index);
-
- return this.rowFromServer.readFieldLength() == Buffer.NULL_LENGTH;
- }
-
- return this.isNull[index];
- }
-
- public long length(int index) throws SQLException {
- findAndSeekToOffset(index);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return 0;
- }
-
- return length;
- }
-
- public void setColumnValue(int index, byte[] value) throws SQLException {
- throw new OperationNotSupportedException();
- }
-
- public void setMetadata(Field[] f) throws SQLException {
- super.setMetadata(f);
-
- if (this.isBinaryEncoded) {
- setupIsNullBitmask();
- }
- }
-
- /**
- * Unpacks the bitmask at the head of the row packet that tells us what
- * columns hold null values, and sets the "home" position directly after the
- * bitmask.
- */
- private void setupIsNullBitmask() throws SQLException {
- int nullCount = (this.metadata.length + 9) / 8;
-
- byte[] nullBitMask = new byte[nullCount];
-
- for (int i = 0; i < nullCount; i++) {
- nullBitMask[i] = this.rowFromServer.readByte();
- }
-
- this.homePosition = this.rowFromServer.getPosition();
-
- this.isNull = new boolean[this.metadata.length];
-
- int nullMaskPos = 0;
- int bit = 4; // first two bits are reserved for future use
-
- for (int i = 0; i < this.metadata.length; i++) {
-
- this.isNull[i] = ((nullBitMask[nullMaskPos] & bit) != 0);
-
- if (((bit <<= 1) & 255) == 0) {
- bit = 1; /* To next byte */
-
- nullMaskPos++;
- }
- }
- }
-
- public Date getDateFast(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- if (isNull(columnIndex)) {
- return null;
- }
-
- int offset = findAndSeekToOffset(columnIndex);
-
- int length = (int) this.rowFromServer.readFieldLength();
-
- return getDateFast(columnIndex, this.rowFromServer.getByteBuffer(),
- offset, length, conn, rs);
- }
-
- public java.sql.Date getNativeDate(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- return getNativeDate(columnIndex, this.rowFromServer.getByteBuffer(),
- offset, (int) length, conn, rs);
- }
-
- public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
- int jdbcType, int mysqlType, TimeZone tz,
- boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- return getNativeDateTimeValue(columnIndex, this.rowFromServer
- .getByteBuffer(), offset, (int) length, targetCalendar, jdbcType,
- mysqlType, tz, rollForward, conn, rs);
- }
-
- public Time getNativeTime(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- int offset = findAndSeekToOffset(columnIndex);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- return getNativeTime(columnIndex, this.rowFromServer.getByteBuffer(),
- offset, (int) length, targetCalendar, tz, rollForward, conn, rs);
- }
-}
\ No newline at end of file
Copied: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRow.java (from rev 6449, branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java)
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java 2007-06-14 16:11:19 UTC (rev 6449)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRow.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -0,0 +1,278 @@
+/*
+ Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ There are special exceptions to the terms and conditions of the GPL
+ as it is applied to this software. View the full text of the
+ exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
+ software distribution.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+package com.mysql.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * A RowHolder implementation that is for cached results (a-la
+ * mysql_store_result()).
+ *
+ * @version $Id: $
+ */
+public class ByteArrayRow extends ResultSetRow {
+
+ byte[][] internalRowData;
+
+ public ByteArrayRow(byte[][] internalRowData) {
+ this.internalRowData = internalRowData;
+ }
+
+ public byte[] getColumnValue(int index) throws SQLException {
+ return this.internalRowData[index];
+ }
+
+ public void setColumnValue(int index, byte[] value) throws SQLException {
+ this.internalRowData[index] = value;
+ }
+
+ public String getString(int index, String encoding, ConnectionImpl conn)
+ throws SQLException {
+ byte[] columnData = this.internalRowData[index];
+
+ if (columnData == null) {
+ return null;
+ }
+
+ return getString(encoding, conn, columnData, 0, columnData.length);
+ }
+
+ public boolean isNull(int index) throws SQLException {
+ return this.internalRowData[index] == null;
+ }
+
+ public boolean isFloatingPointNumber(int index) throws SQLException {
+ byte[] numAsBytes = this.internalRowData[index];
+
+ if (this.internalRowData[index] == null
+ || this.internalRowData[index].length == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < numAsBytes.length; i++) {
+ if (((char) numAsBytes[i] == 'e') || ((char) numAsBytes[i] == 'E')) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public long length(int index) throws SQLException {
+ if (this.internalRowData[index] == null) {
+ return 0;
+ }
+
+ return this.internalRowData[index].length;
+ }
+
+ public int getInt(int columnIndex) {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return StringUtils.getInt(this.internalRowData[columnIndex]);
+ }
+
+ public long getLong(int columnIndex) {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return StringUtils.getLong(this.internalRowData[columnIndex]);
+ }
+
+ public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getTimestampFast(columnIndex, this.internalRowData[columnIndex],
+ 0, columnValue.length, targetCalendar, tz, rollForward, conn,
+ rs);
+ }
+
+ public double getNativeDouble(int columnIndex) throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return getNativeDouble(this.internalRowData[columnIndex], 0);
+ }
+
+ public float getNativeFloat(int columnIndex) throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return getNativeFloat(this.internalRowData[columnIndex], 0);
+ }
+
+ public int getNativeInt(int columnIndex) throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return getNativeInt(this.internalRowData[columnIndex], 0);
+ }
+
+ public long getNativeLong(int columnIndex) throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return getNativeLong(this.internalRowData[columnIndex], 0);
+ }
+
+ public short getNativeShort(int columnIndex) throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return 0;
+ }
+
+ return getNativeShort(this.internalRowData[columnIndex], 0);
+ }
+
+ public Timestamp getNativeTimestamp(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+ byte[] bits = this.internalRowData[columnIndex];
+
+ if (bits == null) {
+ return null;
+ }
+
+ return getNativeTimestamp(bits, 0, bits.length, targetCalendar, tz,
+ rollForward, conn, rs);
+ }
+
+ public void closeOpenStreams() {
+ // no-op for this type
+ }
+
+ public InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return null;
+ }
+
+ return new ByteArrayInputStream(this.internalRowData[columnIndex]);
+ }
+
+ public Reader getReader(int columnIndex) throws SQLException {
+ InputStream stream = getBinaryInputStream(columnIndex);
+
+ if (stream == null) {
+ return null;
+ }
+
+ try {
+ return new InputStreamReader(stream, this.metadata[columnIndex]
+ .getCharacterSet());
+ } catch (UnsupportedEncodingException e) {
+ SQLException sqlEx = SQLError.createSQLException("");
+
+ sqlEx.initCause(e);
+
+ throw sqlEx;
+ }
+ }
+
+ public Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getTimeFast(columnIndex, this.internalRowData[columnIndex], 0,
+ columnValue.length, targetCalendar, tz, rollForward, conn, rs);
+ }
+
+ public Date getDateFast(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getDateFast(columnIndex, this.internalRowData[columnIndex], 0,
+ columnValue.length, conn, rs);
+ }
+
+ public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
+ int jdbcType, int mysqlType, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeDateTimeValue(columnIndex, columnValue, 0,
+ columnValue.length, targetCalendar, jdbcType, mysqlType, tz,
+ rollForward, conn, rs);
+ }
+
+ public Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeDate(columnIndex, columnValue, 0, columnValue.length,
+ conn, rs);
+ }
+
+ public Time getNativeTime(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeTime(columnIndex, columnValue, 0, columnValue.length,
+ targetCalendar, tz, rollForward, conn, rs);
+ }
+}
\ No newline at end of file
Deleted: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1,278 +0,0 @@
-/*
- Copyright (C) 2007 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- There are special exceptions to the terms and conditions of the GPL
- as it is applied to this software. View the full text of the
- exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
- software distribution.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- */
-package com.mysql.jdbc;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.sql.Date;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-/**
- * A RowHolder implementation that is for cached results (a-la
- * mysql_store_result()).
- *
- * @version $Id: $
- */
-public class ByteArrayRowHolder extends RowHolder {
-
- byte[][] internalRowData;
-
- public ByteArrayRowHolder(byte[][] internalRowData) {
- this.internalRowData = internalRowData;
- }
-
- public byte[] getColumnValue(int index) throws SQLException {
- return this.internalRowData[index];
- }
-
- public void setColumnValue(int index, byte[] value) throws SQLException {
- this.internalRowData[index] = value;
- }
-
- public String getString(int index, String encoding, ConnectionImpl conn)
- throws SQLException {
- byte[] columnData = this.internalRowData[index];
-
- if (columnData == null) {
- return null;
- }
-
- return getString(encoding, conn, columnData, 0, columnData.length);
- }
-
- public boolean isNull(int index) throws SQLException {
- return this.internalRowData[index] == null;
- }
-
- public boolean isFloatingPointNumber(int index) throws SQLException {
- byte[] numAsBytes = this.internalRowData[index];
-
- if (this.internalRowData[index] == null
- || this.internalRowData[index].length == 0) {
- return false;
- }
-
- for (int i = 0; i < numAsBytes.length; i++) {
- if (((char) numAsBytes[i] == 'e') || ((char) numAsBytes[i] == 'E')) {
- return true;
- }
- }
-
- return false;
- }
-
- public long length(int index) throws SQLException {
- if (this.internalRowData[index] == null) {
- return 0;
- }
-
- return this.internalRowData[index].length;
- }
-
- public int getInt(int columnIndex) {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return StringUtils.getInt(this.internalRowData[columnIndex]);
- }
-
- public long getLong(int columnIndex) {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return StringUtils.getLong(this.internalRowData[columnIndex]);
- }
-
- public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getTimestampFast(columnIndex, this.internalRowData[columnIndex],
- 0, columnValue.length, targetCalendar, tz, rollForward, conn,
- rs);
- }
-
- public double getNativeDouble(int columnIndex) throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return getNativeDouble(this.internalRowData[columnIndex], 0);
- }
-
- public float getNativeFloat(int columnIndex) throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return getNativeFloat(this.internalRowData[columnIndex], 0);
- }
-
- public int getNativeInt(int columnIndex) throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return getNativeInt(this.internalRowData[columnIndex], 0);
- }
-
- public long getNativeLong(int columnIndex) throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return getNativeLong(this.internalRowData[columnIndex], 0);
- }
-
- public short getNativeShort(int columnIndex) throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return 0;
- }
-
- return getNativeShort(this.internalRowData[columnIndex], 0);
- }
-
- public Timestamp getNativeTimestamp(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
- byte[] bits = this.internalRowData[columnIndex];
-
- if (bits == null) {
- return null;
- }
-
- return getNativeTimestamp(bits, 0, bits.length, targetCalendar, tz,
- rollForward, conn, rs);
- }
-
- public void closeOpenStreams() {
- // no-op for this type
- }
-
- public InputStream getBinaryInputStream(int columnIndex)
- throws SQLException {
- if (this.internalRowData[columnIndex] == null) {
- return null;
- }
-
- return new ByteArrayInputStream(this.internalRowData[columnIndex]);
- }
-
- public Reader getReader(int columnIndex) throws SQLException {
- InputStream stream = getBinaryInputStream(columnIndex);
-
- if (stream == null) {
- return null;
- }
-
- try {
- return new InputStreamReader(stream, this.metadata[columnIndex]
- .getCharacterSet());
- } catch (UnsupportedEncodingException e) {
- SQLException sqlEx = SQLError.createSQLException("");
-
- sqlEx.initCause(e);
-
- throw sqlEx;
- }
- }
-
- public Time getTimeFast(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getTimeFast(columnIndex, this.internalRowData[columnIndex], 0,
- columnValue.length, targetCalendar, tz, rollForward, conn, rs);
- }
-
- public Date getDateFast(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getDateFast(columnIndex, this.internalRowData[columnIndex], 0,
- columnValue.length, conn, rs);
- }
-
- public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
- int jdbcType, int mysqlType, TimeZone tz,
- boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getNativeDateTimeValue(columnIndex, columnValue, 0,
- columnValue.length, targetCalendar, jdbcType, mysqlType, tz,
- rollForward, conn, rs);
- }
-
- public Date getNativeDate(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getNativeDate(columnIndex, columnValue, 0, columnValue.length,
- conn, rs);
- }
-
- public Time getNativeTime(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
- byte[] columnValue = this.internalRowData[columnIndex];
-
- if (columnValue == null) {
- return null;
- }
-
- return getNativeTime(columnIndex, columnValue, 0, columnValue.length,
- targetCalendar, tz, rollForward, conn, rs);
- }
-}
\ No newline at end of file
Deleted: branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1,476 +0,0 @@
-/*
- Copyright (C) 2002-2006 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- There are special exceptions to the terms and conditions of the GPL
- as it is applied to this software. View the full text of the
- exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
- software distribution.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-package com.mysql.jdbc;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Model for result set data backed by a cursor. Only works for forward-only
- * result sets (but still works with updatable concurrency).
- *
- * @version $Id: CursorRowProvider.java,v 1.1.2.1 2005/05/19 18:31:49 mmatthews
- * Exp $
- */
-public class CursorRowProvider implements RowData {
-
- private final static int BEFORE_START_OF_ROWS = -1;
-
- /**
- * The cache of rows we have retrieved from the server.
- */
- private List fetchedRows;
-
- /**
- * Where we are positionaly in the entire result set, used mostly to
- * facilitate easy 'isBeforeFirst()' and 'isFirst()' methods.
- */
- private int currentPositionInEntireResult = BEFORE_START_OF_ROWS;
-
- /**
- * Position in cache of rows, used to determine if we need to fetch more
- * rows from the server to satisfy a request for the next row.
- */
- private int currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
-
- /**
- * The result set that we 'belong' to.
- */
- private ResultSetImpl owner;
-
- /**
- * Have we been told from the server that we have seen the last row?
- */
- private boolean lastRowFetched = false;
-
- /**
- * Field-level metadata from the server. We need this, because it is not
- * sent for each batch of rows, but we need the metadata to unpack the
- * results for each field.
- */
- private Field[] metadata;
-
- /**
- * Communications channel to the server
- */
- private MysqlIO mysql;
-
- /**
- * Identifier for the statement that created this cursor.
- */
- private long statementIdOnServer;
-
- /**
- * The prepared statement that created this cursor.
- */
- private ServerPreparedStatement prepStmt;
-
- /**
- * The server status for 'last-row-sent'...This might belong in mysqldefs,
- * but it it only ever referenced from here.
- */
- private static final int SERVER_STATUS_LAST_ROW_SENT = 128;
-
- /**
- * Have we attempted to fetch any rows yet?
- */
- private boolean firstFetchCompleted = false;
-
- private boolean wasEmpty = false;
-
- /**
- * Creates a new cursor-backed row provider.
- *
- * @param ioChannel
- * connection to the server.
- * @param creatingStatement
- * statement that opened the cursor.
- * @param metadata
- * field-level metadata for the results that this cursor covers.
- */
- public CursorRowProvider(MysqlIO ioChannel,
- ServerPreparedStatement creatingStatement, Field[] metadata) {
- this.currentPositionInEntireResult = BEFORE_START_OF_ROWS;
- this.metadata = metadata;
- this.mysql = ioChannel;
- this.statementIdOnServer = creatingStatement.getServerStatementId();
- this.prepStmt = creatingStatement;
- }
-
- /**
- * Returns true if we got the last element.
- *
- * @return DOCUMENT ME!
- */
- public boolean isAfterLast() {
- return lastRowFetched
- && this.currentPositionInFetchedRows > this.fetchedRows.size();
- }
-
- /**
- * Only works on non dynamic result sets.
- *
- * @param index
- * row number to get at
- * @return row data at index
- * @throws SQLException
- * if a database error occurs
- */
- public RowHolder getAt(int ind) throws SQLException {
- notSupported();
-
- return null;
- }
-
- /**
- * Returns if iteration has not occured yet.
- *
- * @return true if before first row
- * @throws SQLException
- * if a database error occurs
- */
- public boolean isBeforeFirst() throws SQLException {
- return this.currentPositionInEntireResult < 0;
- }
-
- /**
- * Moves the current position in the result set to the given row number.
- *
- * @param rowNumber
- * row to move to
- * @throws SQLException
- * if a database error occurs
- */
- public void setCurrentRow(int rowNumber) throws SQLException {
- notSupported();
- }
-
- /**
- * Returns the current position in the result set as a row number.
- *
- * @return the current row number
- * @throws SQLException
- * if a database error occurs
- */
- public int getCurrentRowNumber() throws SQLException {
- return this.currentPositionInEntireResult + 1;
- }
-
- /**
- * Returns true if the result set is dynamic.
- *
- * This means that move back and move forward won't work because we do not
- * hold on to the records.
- *
- * @return true if this result set is streaming from the server
- */
- public boolean isDynamic() {
- return true;
- }
-
- /**
- * Has no records.
- *
- * @return true if no records
- * @throws SQLException
- * if a database error occurs
- */
- public boolean isEmpty() throws SQLException {
- return this.isBeforeFirst() && this.isAfterLast();
- }
-
- /**
- * Are we on the first row of the result set?
- *
- * @return true if on first row
- * @throws SQLException
- * if a database error occurs
- */
- public boolean isFirst() throws SQLException {
- return this.currentPositionInEntireResult == 0;
- }
-
- /**
- * Are we on the last row of the result set?
- *
- * @return true if on last row
- * @throws SQLException
- * if a database error occurs
- */
- public boolean isLast() throws SQLException {
- return this.lastRowFetched
- && this.currentPositionInFetchedRows == (this.fetchedRows
- .size() - 1);
- }
-
- /**
- * Adds a row to this row data.
- *
- * @param row
- * the row to add
- * @throws SQLException
- * if a database error occurs
- */
- public void addRow(RowHolder row) throws SQLException {
- notSupported();
- }
-
- /**
- * Moves to after last.
- *
- * @throws SQLException
- * if a database error occurs
- */
- public void afterLast() throws SQLException {
- notSupported();
- }
-
- /**
- * Moves to before first.
- *
- * @throws SQLException
- * if a database error occurs
- */
- public void beforeFirst() throws SQLException {
- notSupported();
- }
-
- /**
- * Moves to before last so next el is the last el.
- *
- * @throws SQLException
- * if a database error occurs
- */
- public void beforeLast() throws SQLException {
- notSupported();
- }
-
- /**
- * We're done.
- *
- * @throws SQLException
- * if a database error occurs
- */
- public void close() throws SQLException {
-
- this.metadata = null;
- this.owner = null;
- }
-
- /**
- * Returns true if another row exists.
- *
- * @return true if more rows
- * @throws SQLException
- * if a database error occurs
- */
- public boolean hasNext() throws SQLException {
-
- if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
- return false;
- }
-
- if (this.owner != null && this.owner.owningStatement != null) {
- int maxRows = this.owner.owningStatement.maxRows;
-
- if (maxRows != -1 && this.currentPositionInEntireResult + 1 > maxRows) {
- return false;
- }
- }
-
- if (this.currentPositionInEntireResult != BEFORE_START_OF_ROWS) {
- // Case, we've fetched some rows, but are not at end of fetched
- // block
- if (this.currentPositionInFetchedRows < (this.fetchedRows.size() - 1)) {
- return true;
- } else if (this.currentPositionInFetchedRows == this.fetchedRows
- .size()
- && this.lastRowFetched) {
- return false;
- } else {
- // need to fetch to determine
- fetchMoreRows();
-
- return (this.fetchedRows.size() > 0);
- }
- }
-
- // Okay, no rows _yet_, so fetch 'em
-
- fetchMoreRows();
-
- return this.fetchedRows.size() > 0;
- }
-
- /**
- * Moves the current position relative 'rows' from the current position.
- *
- * @param rows
- * the relative number of rows to move
- * @throws SQLException
- * if a database error occurs
- */
- public void moveRowRelative(int rows) throws SQLException {
- notSupported();
- }
-
- /**
- * Returns the next row.
- *
- * @return the next row value
- * @throws SQLException
- * if a database error occurs
- */
- public RowHolder next() throws SQLException {
- if (this.fetchedRows == null && this.currentPositionInEntireResult != BEFORE_START_OF_ROWS) {
- throw SQLError.createSQLException(
- Messages
- .getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
-
- if (!hasNext()) {
- return null;
- }
-
- this.currentPositionInEntireResult++;
- this.currentPositionInFetchedRows++;
-
- // Catch the forced scroll-passed-end
- if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
- return null;
- }
-
- if (this.currentPositionInFetchedRows > (this.fetchedRows.size() - 1)) {
- fetchMoreRows();
- this.currentPositionInFetchedRows = 0;
- }
-
- RowHolder row = (RowHolder) this.fetchedRows
- .get(this.currentPositionInFetchedRows);
-
- row.setMetadata(this.metadata);
-
- return row;
- }
-
- /**
- *
- */
- private void fetchMoreRows() throws SQLException {
- if (this.lastRowFetched) {
- this.fetchedRows = new ArrayList(0);
- return;
- }
-
- synchronized (this.owner.connection.getMutex()) {
- boolean oldFirstFetchCompleted = this.firstFetchCompleted;
-
- if (!this.firstFetchCompleted) {
- this.firstFetchCompleted = true;
- }
-
- int numRowsToFetch = this.owner.getFetchSize();
-
- if (numRowsToFetch == 0) {
- numRowsToFetch = this.prepStmt.getFetchSize();
- }
-
- if (numRowsToFetch == Integer.MIN_VALUE) {
- // Handle the case where the user used 'old'
- // streaming result sets
-
- numRowsToFetch = 1;
- }
-
- this.fetchedRows = this.mysql.fetchRowsViaCursor(this.fetchedRows,
- this.statementIdOnServer, this.metadata, numRowsToFetch);
- this.currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
-
- if ((this.mysql.getServerStatus() & SERVER_STATUS_LAST_ROW_SENT) != 0) {
- this.lastRowFetched = true;
-
- if (!oldFirstFetchCompleted && this.fetchedRows.size() == 0) {
- this.wasEmpty = true;
- }
- }
- }
- }
-
- /**
- * Removes the row at the given index.
- *
- * @param index
- * the row to move to
- * @throws SQLException
- * if a database error occurs
- */
- public void removeRow(int ind) throws SQLException {
- notSupported();
- }
-
- /**
- * Only works on non dynamic result sets.
- *
- * @return the size of this row data
- */
- public int size() {
- return RESULT_SET_SIZE_UNKNOWN;
- }
-
- private void nextRecord() throws SQLException {
-
- }
-
- private void notSupported() throws SQLException {
- throw new OperationNotSupportedException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.mysql.jdbc.RowProvider#setOwner(com.mysql.jdbc.ResultSet)
- */
- public void setOwner(ResultSetImpl rs) {
- this.owner = rs;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.mysql.jdbc.RowProvider#getOwner()
- */
- public ResultSetInternalMethods getOwner() {
- return this.owner;
- }
-
- public boolean wasEmpty() {
- return this.wasEmpty;
- }
-
- public void setMetadata(Field[] metadata) {
- this.metadata = metadata;
- }
-
-}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/DatabaseMetaData.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -771,7 +771,7 @@
rowData[5] = s2b(functionName); // SPECFIC NAME
}
- procedureRowsOrderedByName.put(functionName, new ByteArrayRowHolder(rowData));
+ procedureRowsOrderedByName.put(functionName, new ByteArrayRow(rowData));
}
}
}
@@ -816,12 +816,12 @@
.toString(procedureReturnsResult) : Integer
.toString(procedureResultUnknown));
- procedureRowsOrderedByName.put(procedureName, new ByteArrayRowHolder(rowData));
+ procedureRowsOrderedByName.put(procedureName, new ByteArrayRow(rowData));
}
}
}
- private RowHolder convertTypeDescriptorToProcedureRow(
+ private ResultSetRow convertTypeDescriptorToProcedureRow(
byte[] procNameAsBytes, String paramName, boolean isOutParam,
boolean isInParam, boolean isReturnParam, TypeDescriptor typeDesc,
boolean forGetFunctionColumns,
@@ -893,7 +893,7 @@
row[16] = s2b(paramName);
}
- return new ByteArrayRowHolder(row);
+ return new ByteArrayRow(row);
}
/**
@@ -1098,7 +1098,7 @@
}
row[2] = s2b(commentBuf.toString());
- rows.add(new ByteArrayRowHolder(row));
+ rows.add(new ByteArrayRow(row));
return rows;
}
@@ -1390,7 +1390,7 @@
java.sql.DatabaseMetaData.bestRowNotPseudo)
.getBytes();
- rows.add(new ByteArrayRowHolder(rowVal));
+ rows.add(new ByteArrayRow(rowVal));
}
}
}
@@ -1792,7 +1792,7 @@
parameterNamePattern);
if (wildCompareRes != StringUtils.WILD_COMPARE_NO_MATCH) {
- RowHolder row = convertTypeDescriptorToProcedureRow(
+ ResultSetRow row = convertTypeDescriptorToProcedureRow(
procNameAsBytes, paramName, isOutParam,
isInParam, false, typeDesc, forGetFunctionColumns,
ordinal++);
@@ -2036,7 +2036,7 @@
while (results.next()) {
byte[][] rowVal = new byte[1][];
rowVal[0] = results.getBytes(1);
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
}
return buildResultSet(fields, tuples);
@@ -2210,7 +2210,7 @@
tuple[5] = s2b(fullUser.toString());
tuple[6] = s2b(privilege);
tuple[7] = null;
- grantRows.add(new ByteArrayRowHolder(tuple));
+ grantRows.add(new ByteArrayRow(tuple));
}
}
}
@@ -2551,7 +2551,7 @@
rowVal[17] = s2b(typeDesc.isNullable);
- rows.add(new ByteArrayRowHolder(rowVal));
+ rows.add(new ByteArrayRow(rowVal));
}
} finally {
if (results != null) {
@@ -2808,7 +2808,7 @@
.toString(
java.sql.DatabaseMetaData.importedKeyNotDeferrable)
.getBytes();
- tuples.add(new ByteArrayRowHolder(tuple));
+ tuples.add(new ByteArrayRow(tuple));
keySeq++;
}
}
@@ -3553,11 +3553,11 @@
if (unique) {
if (indexIsUnique) {
- rows.add(new ByteArrayRowHolder(row));
+ rows.add(new ByteArrayRow(row));
}
} else {
// All rows match
- rows.add(new ByteArrayRowHolder(row));
+ rows.add(new ByteArrayRow(row));
}
}
} finally {
@@ -3922,7 +3922,7 @@
Iterator sortedIterator = sortMap.values().iterator();
while (sortedIterator.hasNext()) {
- rows.add(new ByteArrayRowHolder((byte[][])sortedIterator.next()));
+ rows.add(new ByteArrayRow((byte[][])sortedIterator.next()));
}
} finally {
@@ -4395,7 +4395,7 @@
tuple[PK_NAME] = null; // not available from show table status
tuple[DEFERRABILITY] = s2b(Integer
.toString(java.sql.DatabaseMetaData.importedKeyNotDeferrable));
- tuples.add(new ByteArrayRowHolder(tuple));
+ tuples.add(new ByteArrayRow(tuple));
}
}
@@ -4676,7 +4676,7 @@
tuple[4] = s2b(fullUser.toString());
tuple[5] = s2b(privilege);
tuple[6] = null;
- grantRows.add(new ByteArrayRowHolder(tuple));
+ grantRows.add(new ByteArrayRow(tuple));
}
} finally {
if (columnResults != null) {
@@ -4934,7 +4934,7 @@
.iterator();
while (tablesIter.hasNext()) {
- tuples.add(new ByteArrayRowHolder((byte[][])tablesIter.next()));
+ tuples.add(new ByteArrayRow((byte[][])tablesIter.next()));
}
}
@@ -4943,7 +4943,7 @@
.iterator();
while (viewsIter.hasNext()) {
- tuples.add(new ByteArrayRowHolder((byte[][])viewsIter.next()));
+ tuples.add(new ByteArrayRow((byte[][])viewsIter.next()));
}
}
@@ -4996,17 +4996,17 @@
byte[][] tableTypeRow = new byte[1][];
tableTypeRow[0] = TABLE_AS_BYTES;
- tuples.add(new ByteArrayRowHolder(tableTypeRow));
+ tuples.add(new ByteArrayRow(tableTypeRow));
if (this.conn.versionMeetsMinimum(5, 0, 1)) {
byte[][] viewTypeRow = new byte[1][];
viewTypeRow[0] = VIEW_AS_BYTES;
- tuples.add(new ByteArrayRowHolder(viewTypeRow));
+ tuples.add(new ByteArrayRow(viewTypeRow));
}
byte[][] tempTypeRow = new byte[1][];
tempTypeRow[0] = s2b("LOCAL TEMPORARY");
- tuples.add(new ByteArrayRowHolder(tempTypeRow));
+ tuples.add(new ByteArrayRow(tempTypeRow));
return buildResultSet(fields, tuples);
}
@@ -5185,7 +5185,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: BOOL (silently converted to TINYINT(1)) JDBC Type: BIT
@@ -5217,7 +5217,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TINYINT JDBC Type: TINYINT
@@ -5249,7 +5249,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: BIGINT JDBC Type: BIGINT
@@ -5281,7 +5281,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: LONG VARBINARY JDBC Type: LONGVARBINARY
@@ -5313,7 +5313,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: MEDIUMBLOB JDBC Type: LONGVARBINARY
@@ -5345,7 +5345,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: LONGBLOB JDBC Type: LONGVARBINARY
@@ -5379,7 +5379,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: BLOB JDBC Type: LONGVARBINARY
@@ -5411,7 +5411,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TINYBLOB JDBC Type: LONGVARBINARY
@@ -5443,7 +5443,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: VARBINARY (sliently converted to VARCHAR(M) BINARY) JDBC
@@ -5476,7 +5476,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: BINARY (silently converted to CHAR(M) BINARY) JDBC Type:
@@ -5509,7 +5509,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: LONG VARCHAR JDBC Type: LONGVARCHAR
@@ -5541,7 +5541,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: MEDIUMTEXT JDBC Type: LONGVARCHAR
@@ -5573,7 +5573,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: LONGTEXT JDBC Type: LONGVARCHAR
@@ -5607,7 +5607,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TEXT JDBC Type: LONGVARCHAR
@@ -5639,7 +5639,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TINYTEXT JDBC Type: LONGVARCHAR
@@ -5671,7 +5671,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: CHAR JDBC Type: CHAR
@@ -5703,7 +5703,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: NUMERIC (silently converted to DECIMAL) JDBC Type:
@@ -5736,7 +5736,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: DECIMAL JDBC Type: DECIMAL
@@ -5768,7 +5768,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: INTEGER JDBC Type: INTEGER
@@ -5800,7 +5800,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: INT JDBC Type: INTEGER
@@ -5832,7 +5832,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: MEDIUMINT JDBC Type: INTEGER
@@ -5864,7 +5864,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: SMALLINT JDBC Type: SMALLINT
@@ -5896,7 +5896,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: FLOAT JDBC Type: REAL (this is the SINGLE PERCISION
@@ -5929,7 +5929,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: DOUBLE JDBC Type: DOUBLE
@@ -5961,7 +5961,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: DOUBLE PRECISION JDBC Type: DOUBLE
@@ -5993,7 +5993,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: REAL (does not map to Types.REAL) JDBC Type: DOUBLE
@@ -6025,7 +6025,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: VARCHAR JDBC Type: VARCHAR
@@ -6057,7 +6057,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: ENUM JDBC Type: VARCHAR
@@ -6089,7 +6089,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: SET JDBC Type: VARCHAR
@@ -6121,7 +6121,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: DATE JDBC Type: DATE
@@ -6153,7 +6153,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TIME JDBC Type: TIME
@@ -6185,7 +6185,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: DATETIME JDBC Type: TIMESTAMP
@@ -6217,7 +6217,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
/*
* MySQL Type: TIMESTAMP JDBC Type: TIMESTAMP
@@ -6249,7 +6249,7 @@
rowVal[15] = s2b("0"); // SQL Data Type (not used)
rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used)
rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10)
- tuples.add(new ByteArrayRowHolder(rowVal));
+ tuples.add(new ByteArrayRow(rowVal));
return buildResultSet(fields, tuples);
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -448,7 +448,7 @@
}
if (usingCursor) {
- RowData rows = new CursorRowProvider(
+ RowData rows = new RowDataCursor(
this,
prepStmt,
fields);
@@ -1372,7 +1372,7 @@
*
* @throws SQLException DOCUMENT ME!
*/
- final RowHolder nextRow(Field[] fields, int columnCount,
+ final ResultSetRow nextRow(Field[] fields, int columnCount,
boolean isBinaryEncoded, int resultSetConcurrency,
boolean useBufferRowHolderIfPossible,
boolean reuseRowPacket,
@@ -1416,14 +1416,14 @@
rowData[i] = rowPacket.readLenByteArray(0);
}
- return new ByteArrayRowHolder(rowData);
+ return new ByteArrayRow(rowData);
}
if (!reuseRowPacket) {
this.reusablePacket = new Buffer(rowPacket.getBufLength());
}
- return new BufferRowHolder(rowPacket, fields, false);
+ return new BufferRow(rowPacket, fields, false);
}
@@ -1447,7 +1447,7 @@
this.reusablePacket = new Buffer(rowPacket.getBufLength());
}
- return new BufferRowHolder(rowPacket, fields, true);
+ return new BufferRow(rowPacket, fields, true);
}
rowPacket.setPosition(rowPacket.getPosition() - 1);
@@ -1456,7 +1456,7 @@
return null;
}
- final RowHolder nextRowFast(Field[] fields, int columnCount,
+ final ResultSetRow nextRowFast(Field[] fields, int columnCount,
boolean isBinaryEncoded, int resultSetConcurrency,
boolean useBufferRowHolderIfPossible,
boolean reuseRowPacket)
@@ -1590,7 +1590,7 @@
skipFully(this.mysqlInput, remaining);
}
- return new ByteArrayRowHolder(rowData);
+ return new ByteArrayRow(rowData);
} catch (IOException ioEx) {
throw SQLError.createCommunicationsException(this.connection,
this.lastPacketSentTimeMs, ioEx);
@@ -3743,7 +3743,7 @@
*
* @throws SQLException DOCUMENT ME!
*/
- private final RowHolder unpackBinaryResultSetRow(Field[] fields,
+ private final ResultSetRow unpackBinaryResultSetRow(Field[] fields,
Buffer binaryData, int resultSetConcurrency) throws SQLException {
int numFields = fields.length;
@@ -3790,7 +3790,7 @@
}
}
- return new ByteArrayRowHolder(unpackedRowData);
+ return new ByteArrayRow(unpackedRowData);
}
@@ -4321,7 +4321,7 @@
sendCommand(MysqlDefs.COM_FETCH, null, this.sharedSendPacket, true,
null);
- RowHolder row = null;
+ ResultSetRow row = null;
while ((row = nextRow(columnTypes, columnTypes.length, true,
ResultSet.CONCUR_READ_ONLY, false, true, null)) != null) {
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1318,7 +1318,7 @@
while (rs.next()) {
this.batchedGeneratedKeys
- .add(new ByteArrayRowHolder(new byte[][] { rs.getBytes(1) }));
+ .add(new ByteArrayRow(new byte[][] { rs.getBytes(1) }));
}
} finally {
if (rs != null) {
@@ -4558,7 +4558,7 @@
typeMetadata[i] = parameterMetadata;
}
- rows.add(new ByteArrayRowHolder(rowData));
+ rows.add(new ByteArrayRow(rowData));
this.bindingsAsRs = new ResultSetImpl(connection.getCatalog(),
typeMetadata, new RowDataStatic(rows), connection, null);
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -294,7 +294,7 @@
PreparedStatement statementUsedForFetchingRows;
/** Pointer to current row data */
- protected RowHolder thisRow = null; // Values for current row
+ protected ResultSetRow thisRow = null; // Values for current row
// These are longs for
// recent versions of the MySQL server.
@@ -586,6 +586,10 @@
this.doingUpdates = false;
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
if (row == 1) {
b = first();
} else if (row == -1) {
@@ -639,6 +643,10 @@
this.doingUpdates = false;
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
if (this.rowData.size() != 0) {
this.rowData.afterLast();
this.thisRow = null;
@@ -672,6 +680,10 @@
return;
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
this.rowData.beforeFirst();
this.thisRow = null;
}
@@ -6913,6 +6925,10 @@
this.doingUpdates = false;
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
this.rowData.beforeLast();
this.thisRow = this.rowData.next();
@@ -6997,6 +7013,10 @@
SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
if (this.rowData.size() == 0) {
b = false;
} else {
@@ -7010,17 +7030,6 @@
b = true;
}
-
- /*
- if (!this.rowData.hasNext()) {
- // force scroll past end
- this.rowData.next();
- b = false;
- } else {
- clearWarnings();
- this.thisRow = this.rowData.next();
- b = true;
- } */
}
return b;
@@ -7245,6 +7254,10 @@
int rowIndex = this.rowData.getCurrentRowNumber();
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
if ((rowIndex - 1) >= 0) {
rowIndex--;
this.rowData.setCurrentRow(rowIndex);
@@ -7535,6 +7548,10 @@
return false;
}
+ if (this.thisRow != null) {
+ this.thisRow.closeOpenStreams();
+ }
+
this.rowData.moveRowRelative(rows);
this.thisRow = this.rowData.getAt(this.rowData.getCurrentRowNumber());
Copied: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetRow.java (from rev 6449, branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java)
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java 2007-06-14 16:11:19 UTC (rev 6449)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetRow.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -0,0 +1,1371 @@
+/*
+ Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ There are special exceptions to the terms and conditions of the GPL
+ as it is applied to this software. View the full text of the
+ exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
+ software distribution.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+package com.mysql.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+/**
+ * Classes that implement this interface represent one row of data from the
+ * MySQL server that might be stored in different ways depending on whether the
+ * result set was streaming (so they wrap a reusable packet), or whether the
+ * result set was cached or via a server-side cursor (so they represent a
+ * byte[][]).
+ *
+ * Notice that <strong>no</strong> bounds checking is expected for implementors
+ * of this interface, it happens in ResultSetImpl.
+ *
+ * @version $Id: $
+ */
+public abstract class ResultSetRow {
+ /**
+ * The metadata of the fields of this result set.
+ */
+ protected Field[] metadata;
+
+ /**
+ * Called during navigation to next row to close all open
+ * streams.
+ */
+ public abstract void closeOpenStreams();
+
+ /**
+ * Returns data at the given index as an InputStream with no
+ * character conversion.
+ *
+ * @param columnIndex
+ * of the column value (starting at 0) to return.
+ * @return the value at the given index as an InputStream or null
+ * if null.
+ *
+ * @throws SQLException if an error occurs while retrieving the value.
+ */
+ public abstract InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException;
+
+ /**
+ * Returns the value at the given column (index starts at 0) "raw" (i.e.
+ * as-returned by the server).
+ *
+ * @param index
+ * of the column value (starting at 0) to return.
+ * @return the value for the given column (including NULL if it is)
+ * @throws SQLException
+ * if an error occurs while retrieving the value.
+ */
+ public abstract byte[] getColumnValue(int index) throws SQLException;
+
+ protected final java.sql.Date getDateFast(int columnIndex,
+ byte[] dateAsBytes, int offset, int length, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ try {
+ if (dateAsBytes == null) {
+ return null;
+ }
+
+ boolean allZeroDate = true;
+
+ boolean onlyTimePresent = false;
+
+ for (int i = 0; i < length; i++) {
+ if (dateAsBytes[offset + i] == ':') {
+ onlyTimePresent = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ byte b = dateAsBytes[offset + i];
+
+ if (b == ' ' || b == '-' || b == '/') {
+ onlyTimePresent = false;
+ }
+
+ if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
+ && b != '.') {
+ allZeroDate = false;
+
+ break;
+ }
+ }
+
+ if (!onlyTimePresent && allZeroDate) {
+
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError.createSQLException("Value '"
+ + new String(dateAsBytes)
+ + "' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ // We're left with the case of 'round' to a date Java _can_
+ // represent, which is '0001-01-01'.
+ return rs.fastDateCreate(null, 1, 1, 1);
+
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
+ // Convert from TIMESTAMP
+ switch (length) {
+ case 21:
+ case 19: { // java.sql.Timestamp format
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 5,
+ offset + 7);
+ day = StringUtils.getInt(dateAsBytes, offset + 8,
+ offset + 10);
+
+ return rs.fastDateCreate(null, year, month, day);
+ }
+
+ case 14:
+ case 8: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 4,
+ offset + 6);
+ day = StringUtils.getInt(dateAsBytes, offset + 6,
+ offset + 8);
+
+ return rs.fastDateCreate(null, year, month, day);
+ }
+
+ case 12:
+ case 10:
+ case 6: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 2);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ month = StringUtils.getInt(dateAsBytes, offset + 2,
+ offset + 4);
+ day = StringUtils.getInt(dateAsBytes, offset + 4,
+ offset + 6);
+
+ return rs.fastDateCreate(null, year + 1900, month, day);
+ }
+
+ case 4: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ month = StringUtils.getInt(dateAsBytes, offset + 2,
+ offset + 4);
+
+ return rs.fastDateCreate(null, year + 1900, month, 1);
+ }
+
+ case 2: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 2);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ return rs.fastDateCreate(null, year + 1900, 1, 1);
+ }
+
+ default:
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString(
+ "ResultSet.Bad_format_for_Date",
+ new Object[] {
+ new String(
+ dateAsBytes),
+ Constants
+ .integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ } /* endswitch */
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
+
+ if (length == 2 || length == 1) {
+ year = StringUtils.getInt(dateAsBytes, offset, offset
+ + length);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ year += 1900;
+ } else {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ }
+
+ return rs.fastDateCreate(null, year, 1, 1);
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
+ return rs.fastDateCreate(null, 1970, 1, 1); // Return EPOCH
+ } else {
+ if (length < 10) {
+ if (length == 8) {
+ return rs.fastDateCreate(null, 1970, 1, 1); // Return
+ // EPOCH for
+ // TIME
+ }
+
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString(
+ "ResultSet.Bad_format_for_Date",
+ new Object[] {
+ new String(
+ dateAsBytes),
+ Constants
+ .integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ }
+
+ if (length != 18) {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 5,
+ offset + 7);
+ day = StringUtils.getInt(dateAsBytes, offset + 8,
+ offset + 10);
+ } else {
+ // JDK-1.3 timestamp format, not real easy to parse
+ // positionally :p
+ StringTokenizer st = new StringTokenizer(new String(
+ dateAsBytes, offset, length, "ISO8859_1"), "- ");
+
+ year = Integer.parseInt(st.nextToken());
+ month = Integer.parseInt(st.nextToken());
+ day = Integer.parseInt(st.nextToken());
+ }
+ }
+
+ return rs.fastDateCreate(null, year, month, day);
+ } catch (SQLException sqlEx) {
+ throw sqlEx; // don't re-wrap
+ } catch (Exception e) {
+ throw SQLError.createSQLException(Messages.getString(
+ "ResultSet.Bad_format_for_Date", new Object[] {
+ new String(dateAsBytes),
+ Constants.integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ }
+ }
+
+ public abstract java.sql.Date getDateFast(int columnIndex,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ /**
+ * Returns the value at the given column (index starts at 0) as an int. *
+ *
+ * @param index
+ * of the column value (starting at 0) to return.
+ * @return the value for the given column (returns 0 if NULL, use isNull()
+ * to determine if the value was actually NULL)
+ * @throws SQLException
+ * if an error occurs while retrieving the value.
+ */
+ public abstract int getInt(int columnIndex) throws SQLException;
+
+ /**
+ * Returns the value at the given column (index starts at 0) as a long. *
+ *
+ * @param index
+ * of the column value (starting at 0) to return.
+ * @return the value for the given column (returns 0 if NULL, use isNull()
+ * to determine if the value was actually NULL)
+ * @throws SQLException
+ * if an error occurs while retrieving the value.
+ */
+ public abstract long getLong(int columnIndex) throws SQLException;
+
+ protected java.sql.Date getNativeDate(int columnIndex, byte[] bits,
+ int offset, int length, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
+
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+ }
+
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError
+ .createSQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ return rs.fastDateCreate(rs.getCalendarInstanceForSessionOrNew(), year,
+ month, day);
+ }
+
+ public abstract Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException;
+
+ protected Object getNativeDateTimeValue(int columnIndex, byte[] bits,
+ int offset, int length, Calendar targetCalendar, int jdbcType,
+ int mysqlType, TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ int nanos = 0;
+
+ if (bits == null) {
+
+ return null;
+ }
+
+ Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
+ .getUtcCalendar()
+ : rs.getCalendarInstanceForSessionOrNew();
+
+ boolean populatedFromDateTimeValue = false;
+
+ switch (mysqlType) {
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ populatedFromDateTimeValue = true;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+
+ if (length > 4) {
+ hour = bits[offset + 4];
+ minute = bits[offset + 5];
+ seconds = bits[offset + 6];
+ }
+
+ if (length > 7) {
+ // MySQL uses microseconds
+ nanos = ((bits[offset + 7] & 0xff)
+ | ((bits[offset + 8] & 0xff) << 8)
+ | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
+ }
+ }
+
+ break;
+ case MysqlDefs.FIELD_TYPE_DATE:
+ populatedFromDateTimeValue = true;
+
+ if (bits.length != 0) {
+ year = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+ }
+
+ break;
+ case MysqlDefs.FIELD_TYPE_TIME:
+ populatedFromDateTimeValue = true;
+
+ if (bits.length != 0) {
+ // bits[0] // skip tm->neg
+ // binaryData.readLong(); // skip daysPart
+ hour = bits[offset + 5];
+ minute = bits[offset + 6];
+ seconds = bits[offset + 7];
+ }
+
+ year = 1970;
+ month = 1;
+ day = 1;
+
+ break;
+ default:
+ populatedFromDateTimeValue = false;
+ }
+
+ switch (jdbcType) {
+ case Types.TIME:
+ if (populatedFromDateTimeValue) {
+ Time time = TimeUtil.fastTimeCreate(rs
+ .getCalendarInstanceForSessionOrNew(), hour, minute,
+ seconds);
+
+ Time adjustedTime = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, time, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTime;
+ }
+
+ return rs.getNativeTimeViaParseConversion(columnIndex + 1,
+ targetCalendar, tz, rollForward);
+
+ case Types.DATE:
+ if (populatedFromDateTimeValue) {
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw new SQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ return rs
+ .fastDateCreate(
+ rs.getCalendarInstanceForSessionOrNew(), year,
+ month, day);
+ }
+
+ return rs.getNativeDateViaParseConversion(columnIndex + 1);
+ case Types.TIMESTAMP:
+ if (populatedFromDateTimeValue) {
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw new SQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Timestamp",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ Timestamp ts = rs.fastTimestampCreate(rs
+ .getCalendarInstanceForSessionOrNew(), year, month,
+ day, hour, minute, seconds, nanos);
+
+ Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, ts, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTs;
+ }
+
+ return rs.getNativeTimestampViaParseConversion(columnIndex + 1,
+ targetCalendar, tz, rollForward);
+
+ default:
+ throw new SQLException(
+ "Internal error - conversion method doesn't support this type",
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
+ }
+
+ public abstract Object getNativeDateTimeValue(int columnIndex,
+ Calendar targetCalendar, int jdbcType, int mysqlType,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException;
+
+ protected double getNativeDouble(byte[] bits, int offset) {
+ long valueAsLong = (bits[offset + 0] & 0xff)
+ | ((long) (bits[offset + 1] & 0xff) << 8)
+ | ((long) (bits[offset + 2] & 0xff) << 16)
+ | ((long) (bits[offset + 3] & 0xff) << 24)
+ | ((long) (bits[offset + 4] & 0xff) << 32)
+ | ((long) (bits[offset + 5] & 0xff) << 40)
+ | ((long) (bits[offset + 6] & 0xff) << 48)
+ | ((long) (bits[offset + 7] & 0xff) << 56);
+
+ return Double.longBitsToDouble(valueAsLong);
+ }
+
+ public abstract double getNativeDouble(int columnIndex) throws SQLException;
+
+ protected float getNativeFloat(byte[] bits, int offset) {
+ int asInt = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8)
+ | ((bits[offset + 2] & 0xff) << 16)
+ | ((bits[offset + 3] & 0xff) << 24);
+
+ return Float.intBitsToFloat(asInt);
+ }
+
+ public abstract float getNativeFloat(int columnIndex) throws SQLException;
+
+ protected int getNativeInt(byte[] bits, int offset) {
+
+ int valueAsInt = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8)
+ | ((bits[offset + 2] & 0xff) << 16)
+ | ((bits[offset + 3] & 0xff) << 24);
+
+ return valueAsInt;
+ }
+
+ public abstract int getNativeInt(int columnIndex) throws SQLException;
+
+ protected long getNativeLong(byte[] bits, int offset) {
+ long valueAsLong = (bits[offset + 0] & 0xff)
+ | ((long) (bits[offset + 1] & 0xff) << 8)
+ | ((long) (bits[offset + 2] & 0xff) << 16)
+ | ((long) (bits[offset + 3] & 0xff) << 24)
+ | ((long) (bits[offset + 4] & 0xff) << 32)
+ | ((long) (bits[offset + 5] & 0xff) << 40)
+ | ((long) (bits[offset + 6] & 0xff) << 48)
+ | ((long) (bits[offset + 7] & 0xff) << 56);
+
+ return valueAsLong;
+ }
+
+ public abstract long getNativeLong(int columnIndex) throws SQLException;
+
+ protected short getNativeShort(byte[] bits, int offset) {
+ short asShort = (short) ((bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8));
+
+ return asShort;
+ }
+
+ public abstract short getNativeShort(int columnIndex) throws SQLException;
+
+ protected Time getNativeTime(int columnIndex, byte[] bits, int offset,
+ int length, Calendar targetCalendar, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ if (length != 0) {
+ // bits[0] // skip tm->neg
+ // binaryData.readLong(); // skip daysPart
+ hour = bits[offset + 5];
+ minute = bits[offset + 6];
+ seconds = bits[offset + 7];
+ }
+
+ Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ Time time = TimeUtil.fastTimeCreate(sessionCalendar, hour, minute,
+ seconds);
+
+ Time adjustedTime = TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, time, conn.getServerTimezoneTZ(), tz,
+ rollForward);
+
+ return adjustedTime;
+ }
+ }
+
+ public abstract Time getNativeTime(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ int nanos = 0;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[2];
+ day = bits[3];
+
+ if (length > 4) {
+ hour = bits[offset + 4];
+ minute = bits[offset + 5];
+ seconds = bits[offset + 6];
+ }
+
+ if (length > 7) {
+ // MySQL uses microseconds
+ nanos = ((bits[offset + 7] & 0xff)
+ | ((bits[offset + 8] & 0xff) << 8)
+ | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
+ }
+ }
+
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError
+ .createSQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Timestamp",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
+ .getUtcCalendar()
+ : rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ Timestamp ts = rs.fastTimestampCreate(sessionCalendar, year, month,
+ day, hour, minute, seconds, nanos);
+
+ Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, ts, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTs;
+ }
+ }
+
+ public abstract Timestamp getNativeTimestamp(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ public abstract Reader getReader(int columnIndex) throws SQLException;
+
+ /**
+ * Returns the value at the given column (index starts at 0) as a
+ * java.lang.String with the requested encoding, using the given
+ * ConnectionImpl to find character converters.
+ *
+ * @param index
+ * of the column value (starting at 0) to return.
+ * @param encoding
+ * the Java name for the character encoding
+ * @param conn
+ * the connection that created this result set row
+ *
+ * @return the value for the given column (including NULL if it is) as a
+ * String
+ *
+ * @throws SQLException
+ * if an error occurs while retrieving the value.
+ */
+ public abstract String getString(int index, String encoding,
+ ConnectionImpl conn) throws SQLException;
+
+ /**
+ * Convenience method for turning a byte[] into a string with the given
+ * encoding.
+ *
+ * @param encoding
+ * the Java encoding name for the byte[] -> char conversion
+ * @param conn
+ * the ConnectionImpl that created the result set
+ * @param value
+ * the String value as a series of bytes, encoded using
+ * "encoding"
+ * @param offset
+ * where to start the decoding
+ * @param length
+ * how many bytes to decode
+ *
+ * @return the String as decoded from bytes with the given encoding
+ *
+ * @throws SQLException
+ * if an error occurs
+ */
+ protected String getString(String encoding, ConnectionImpl conn,
+ byte[] value, int offset, int length) throws SQLException {
+ String stringVal = null;
+
+ if ((conn != null) && conn.getUseUnicode()) {
+ try {
+ if (encoding == null) {
+ stringVal = new String(value);
+ } else {
+ SingleByteCharsetConverter converter = conn
+ .getCharsetConverter(encoding);
+
+ if (converter != null) {
+ stringVal = converter.toString(value, offset, length);
+ } else {
+ stringVal = new String(value, offset, length, encoding);
+ }
+ }
+ } catch (java.io.UnsupportedEncodingException E) {
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
+ + encoding + "'.", "0S100");
+ }
+ } else {
+ stringVal = StringUtils.toAsciiString(value, offset, length);
+ }
+
+ return stringVal;
+ }
+
+ protected Time getTimeFast(int columnIndex, byte[] timeAsBytes, int offset,
+ int length, Calendar targetCalendar, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int hr = 0;
+ int min = 0;
+ int sec = 0;
+
+ try {
+
+ if (timeAsBytes == null) {
+ return null;
+ }
+
+ boolean allZeroTime = true;
+ boolean onlyTimePresent = false;
+
+ for (int i = 0; i < length; i++) {
+ if (timeAsBytes[offset + i] == ':') {
+ onlyTimePresent = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ byte b = timeAsBytes[offset + i];
+
+ if (b == ' ' || b == '-' || b == '/') {
+ onlyTimePresent = false;
+ }
+
+ if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
+ && b != '.') {
+ allZeroTime = false;
+
+ break;
+ }
+ }
+
+ if (!onlyTimePresent && allZeroTime) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError.createSQLException("Value '"
+ + new String(timeAsBytes)
+ + "' can not be represented as java.sql.Time",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ // We're left with the case of 'round' to a time Java _can_
+ // represent, which is '00:00:00'
+ return rs.fastTimeCreate(null, 0, 0, 0);
+ }
+
+ Field timeColField = this.metadata[columnIndex];
+
+ if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
+
+ switch (length) {
+ case 19: { // YYYY-MM-DD hh:mm:ss
+
+ hr = StringUtils.getInt(timeAsBytes, offset + length - 8,
+ offset + length - 6);
+ min = StringUtils.getInt(timeAsBytes, offset + length - 5,
+ offset + length - 3);
+ sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
+ offset + length);
+ }
+
+ break;
+ case 14:
+ case 12: {
+ hr = StringUtils.getInt(timeAsBytes, offset + length - 6,
+ offset + length - 4);
+ min = StringUtils.getInt(timeAsBytes, offset + length - 4,
+ offset + length - 2);
+ sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
+ offset + length);
+ }
+
+ break;
+
+ case 10: {
+ hr = StringUtils
+ .getInt(timeAsBytes, offset + 6, offset + 8);
+ min = StringUtils.getInt(timeAsBytes, offset + 8,
+ offset + 10);
+ sec = 0;
+ }
+
+ break;
+
+ default:
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
+ + (columnIndex + 1)
+ + "("
+ + timeColField + ").",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ } /* endswitch */
+
+ SQLWarning precisionLost = new SQLWarning(
+ Messages
+ .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
+ + columnIndex + "(" + timeColField + ").");
+ /*
+ * if (this.warningChain == null) { this.warningChain =
+ * precisionLost; } else {
+ * this.warningChain.setNextWarning(precisionLost); }
+ */
+ } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
+ hr = StringUtils.getInt(timeAsBytes, offset + 11, offset + 13);
+ min = StringUtils.getInt(timeAsBytes, offset + 14, offset + 16);
+ sec = StringUtils.getInt(timeAsBytes, offset + 17, offset + 19);
+
+ SQLWarning precisionLost = new SQLWarning(
+ Messages
+ .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
+ + (columnIndex + 1) + "(" + timeColField + ").");
+
+ /*
+ * if (this.warningChain == null) { this.warningChain =
+ * precisionLost; } else {
+ * this.warningChain.setNextWarning(precisionLost); }
+ */
+ } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
+ return rs.fastTimeCreate(null, 0, 0, 0); // midnight on the
+ // given
+ // date
+ } else {
+ // convert a String to a Time
+ if ((length != 5) && (length != 8)) {
+ throw SQLError.createSQLException(Messages
+ .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
+ + new String(timeAsBytes)
+ + Messages.getString("ResultSet.___in_column__268")
+ + (columnIndex + 1),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2);
+ min = StringUtils.getInt(timeAsBytes, offset + 3, offset + 5);
+ sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes,
+ offset + 6, offset + 8);
+ }
+
+ Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ return TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimeCreate(sessionCalendar, hr,
+ min, sec), conn.getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+ } catch (Exception ex) {
+ throw SQLError.createSQLException(ex.toString(),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+ }
+
+ public abstract Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException;
+
+ protected Timestamp getTimestampFast(int columnIndex,
+ byte[] timestampAsBytes, int offset, int length,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+
+ try {
+ Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
+ .getUtcCalendar()
+ : rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ boolean allZeroTimestamp = true;
+
+ boolean onlyTimePresent = false;
+
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == ':') {
+ onlyTimePresent = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ byte b = timestampAsBytes[offset + i];
+
+ if (b == ' ' || b == '-' || b == '/') {
+ onlyTimePresent = false;
+ }
+
+ if (b != '0' && b != ' ' && b != ':' && b != '-'
+ && b != '/' && b != '.') {
+ allZeroTimestamp = false;
+
+ break;
+ }
+ }
+
+ if (!onlyTimePresent && allZeroTimestamp) {
+
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError
+ .createSQLException(
+ "Value '"
+ + timestampAsBytes
+ + "' can not be represented as java.sql.Timestamp",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ // We're left with the case of 'round' to a date Java _can_
+ // represent, which is '0001-01-01'.
+ return rs.fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);
+
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
+
+ return TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, StringUtils.getInt(
+ timestampAsBytes, offset, 4), 1, 1,
+ 0, 0, 0, 0), conn.getServerTimezoneTZ(),
+ tz, rollForward);
+
+ } else {
+ if (timestampAsBytes[offset + length - 1] == '.') {
+ length--;
+ }
+
+ // Convert from TIMESTAMP or DATE
+ switch (length) {
+ case 26:
+ case 25:
+ case 24:
+ case 23:
+ case 22:
+ case 21:
+ case 20:
+ case 19: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 4);
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 5, offset + 7);
+ int day = StringUtils.getInt(timestampAsBytes,
+ offset + 8, offset + 10);
+ int hour = StringUtils.getInt(timestampAsBytes,
+ offset + 11, offset + 13);
+ int minutes = StringUtils.getInt(timestampAsBytes,
+ offset + 14, offset + 16);
+ int seconds = StringUtils.getInt(timestampAsBytes,
+ offset + 17, offset + 19);
+
+ int nanos = 0;
+
+ if (length > 19) {
+ int decimalIndex = -1;
+
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == '.') {
+ decimalIndex = i;
+ }
+ }
+
+ if (decimalIndex != -1) {
+ if ((decimalIndex + 2) <= length) {
+ nanos = StringUtils.getInt(
+ timestampAsBytes, decimalIndex + 1,
+ offset + length);
+ } else {
+ throw new IllegalArgumentException(); // re-thrown
+ // further
+ // down
+ // with
+ // a
+ // much better error message
+ }
+ }
+ }
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year, month,
+ day, hour, minutes, seconds,
+ nanos), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 14: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 4);
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 4, offset + 6);
+ int day = StringUtils.getInt(timestampAsBytes,
+ offset + 6, offset + 8);
+ int hour = StringUtils.getInt(timestampAsBytes,
+ offset + 8, offset + 10);
+ int minutes = StringUtils.getInt(timestampAsBytes,
+ offset + 10, offset + 12);
+ int seconds = StringUtils.getInt(timestampAsBytes,
+ offset + 12, offset + 14);
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar,
+ rs.fastTimestampCreate(sessionCalendar,
+ year, month, day, hour,
+ minutes, seconds, 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 12: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+
+ if (year <= 69) {
+ year = (year + 100);
+ }
+
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 2, offset + 4);
+ int day = StringUtils.getInt(timestampAsBytes,
+ offset + 4, offset + 6);
+ int hour = StringUtils.getInt(timestampAsBytes,
+ offset + 6, offset + 8);
+ int minutes = StringUtils.getInt(timestampAsBytes,
+ offset + 8, offset + 10);
+ int seconds = StringUtils.getInt(timestampAsBytes,
+ offset + 10, offset + 12);
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year + 1900,
+ month, day, hour, minutes,
+ seconds, 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 10: {
+ int year;
+ int month;
+ int day;
+ int hour;
+ int minutes;
+
+ boolean hasDash = false;
+
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == '-') {
+ hasDash = true;
+ break;
+ }
+ }
+
+ if ((this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
+ || hasDash) {
+ year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 4);
+ month = StringUtils.getInt(timestampAsBytes,
+ offset + 5, offset + 7);
+ day = StringUtils.getInt(timestampAsBytes,
+ offset + 8, offset + 10);
+ hour = 0;
+ minutes = 0;
+ } else {
+ year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+
+ if (year <= 69) {
+ year = (year + 100);
+ }
+
+ month = StringUtils.getInt(timestampAsBytes,
+ offset + 2, offset + 4);
+ day = StringUtils.getInt(timestampAsBytes,
+ offset + 4, offset + 6);
+ hour = StringUtils.getInt(timestampAsBytes,
+ offset + 6, offset + 8);
+ minutes = StringUtils.getInt(timestampAsBytes,
+ offset + 8, offset + 10);
+
+ year += 1900; // two-digit year
+ }
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year, month,
+ day, hour, minutes, 0, 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 8: {
+ boolean hasColon = false;
+
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == ':') {
+ hasColon = true;
+ break;
+ }
+ }
+
+ if (hasColon) {
+ int hour = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+ int minutes = StringUtils.getInt(timestampAsBytes,
+ offset + 3, offset + 5);
+ int seconds = StringUtils.getInt(timestampAsBytes,
+ offset + 6, offset + 8);
+
+ return TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, rs
+ .fastTimestampCreate(
+ sessionCalendar, 1970, 1,
+ 1, hour, minutes, seconds,
+ 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+
+ }
+
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 4);
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 4, offset + 6);
+ int day = StringUtils.getInt(timestampAsBytes,
+ offset + 6, offset + 8);
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year - 1900,
+ month - 1, day, 0, 0, 0, 0),
+ conn.getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 6: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+
+ if (year <= 69) {
+ year = (year + 100);
+ }
+
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 2, offset + 4);
+ int day = StringUtils.getInt(timestampAsBytes,
+ offset + 4, offset + 6);
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year + 1900,
+ month, day, 0, 0, 0, 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ case 4: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+
+ if (year <= 69) {
+ year = (year + 100);
+ }
+
+ int month = StringUtils.getInt(timestampAsBytes,
+ offset + 2, offset + 4);
+
+ return TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ sessionCalendar, year + 1900, month, 1,
+ 0, 0, 0, 0),
+ conn.getServerTimezoneTZ(), tz, rollForward);
+ }
+
+ case 2: {
+ int year = StringUtils.getInt(timestampAsBytes,
+ offset + 0, offset + 2);
+
+ if (year <= 69) {
+ year = (year + 100);
+ }
+
+ return TimeUtil
+ .changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimestampCreate(
+ null, year + 1900, 1, 1, 0, 0,
+ 0, 0), conn
+ .getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+
+ default:
+ throw new java.sql.SQLException(
+ "Bad format for Timestamp '"
+ + new String(timestampAsBytes)
+ + "' in column " + (columnIndex + 1)
+ + ".",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new java.sql.SQLException("Cannot convert value '"
+ + getString(columnIndex, "ISO8859_1", conn)
+ + "' from column " + (columnIndex + 1) + " to TIMESTAMP.",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+ }
+
+ public abstract Timestamp getTimestampFast(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ /**
+ * Could the column value at the given index (which starts at 0) be
+ * interpreted as a floating-point number (has +/-/E/e in it)?
+ *
+ * @param index
+ * of the column value (starting at 0) to check.
+ *
+ * @return true if the column value at the given index looks like it might
+ * be a floating-point number, false if not.
+ *
+ * @throws SQLException
+ * if an error occurs
+ */
+ public abstract boolean isFloatingPointNumber(int index)
+ throws SQLException;
+
+ /**
+ * Is the column value at the given index (which starts at 0) NULL?
+ *
+ * @param index
+ * of the column value (starting at 0) to check.
+ *
+ * @return true if the column value is NULL, false if not.
+ *
+ * @throws SQLException
+ * if an error occurs
+ */
+ public abstract boolean isNull(int index) throws SQLException;
+
+ /**
+ * Returns the length of the column at the given index (which starts at 0).
+ *
+ * @param index
+ * of the column value (starting at 0) for which to return the
+ * length.
+ * @return the length of the requested column, 0 if null (clients of this
+ * interface should use isNull() beforehand to determine status of
+ * NULL values in the column).
+ *
+ * @throws SQLException
+ */
+ public abstract long length(int index) throws SQLException;
+
+ /**
+ * Sets the given column value (only works currently with
+ * ByteArrayRowHolder).
+ *
+ * @param index
+ * index of the column value (starting at 0) to set.
+ * @param value
+ * the (raw) value to set
+ *
+ * @throws SQLException
+ * if an error occurs, or the concrete RowHolder doesn't support
+ * this operation.
+ */
+ public abstract void setColumnValue(int index, byte[] value)
+ throws SQLException;
+
+ public void setMetadata(Field[] f) throws SQLException {
+ this.metadata = f;
+ }
+}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowData.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowData.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowData.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -49,7 +49,7 @@
* @throws SQLException
* if a database error occurs
*/
- void addRow(RowHolder row) throws SQLException;
+ void addRow(ResultSetRow row) throws SQLException;
/**
* Moves to after last.
@@ -92,7 +92,7 @@
* @throws SQLException
* if a database error occurs
*/
- RowHolder getAt(int index) throws SQLException;
+ ResultSetRow getAt(int index) throws SQLException;
/**
* Returns the current position in the result set as a row number.
@@ -191,7 +191,7 @@
* @throws SQLException
* if a database error occurs
*/
- RowHolder next() throws SQLException;
+ ResultSetRow next() throws SQLException;
/**
* Removes the row at the given index.
Copied: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataCursor.java (from rev 6449, branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java)
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/CursorRowProvider.java 2007-06-14 16:11:19 UTC (rev 6449)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataCursor.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -0,0 +1,476 @@
+/*
+ Copyright (C) 2002-2006 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ There are special exceptions to the terms and conditions of the GPL
+ as it is applied to this software. View the full text of the
+ exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
+ software distribution.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.mysql.jdbc;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Model for result set data backed by a cursor. Only works for forward-only
+ * result sets (but still works with updatable concurrency).
+ *
+ * @version $Id: CursorRowProvider.java,v 1.1.2.1 2005/05/19 18:31:49 mmatthews
+ * Exp $
+ */
+public class RowDataCursor implements RowData {
+
+ private final static int BEFORE_START_OF_ROWS = -1;
+
+ /**
+ * The cache of rows we have retrieved from the server.
+ */
+ private List fetchedRows;
+
+ /**
+ * Where we are positionaly in the entire result set, used mostly to
+ * facilitate easy 'isBeforeFirst()' and 'isFirst()' methods.
+ */
+ private int currentPositionInEntireResult = BEFORE_START_OF_ROWS;
+
+ /**
+ * Position in cache of rows, used to determine if we need to fetch more
+ * rows from the server to satisfy a request for the next row.
+ */
+ private int currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
+
+ /**
+ * The result set that we 'belong' to.
+ */
+ private ResultSetImpl owner;
+
+ /**
+ * Have we been told from the server that we have seen the last row?
+ */
+ private boolean lastRowFetched = false;
+
+ /**
+ * Field-level metadata from the server. We need this, because it is not
+ * sent for each batch of rows, but we need the metadata to unpack the
+ * results for each field.
+ */
+ private Field[] metadata;
+
+ /**
+ * Communications channel to the server
+ */
+ private MysqlIO mysql;
+
+ /**
+ * Identifier for the statement that created this cursor.
+ */
+ private long statementIdOnServer;
+
+ /**
+ * The prepared statement that created this cursor.
+ */
+ private ServerPreparedStatement prepStmt;
+
+ /**
+ * The server status for 'last-row-sent'...This might belong in mysqldefs,
+ * but it it only ever referenced from here.
+ */
+ private static final int SERVER_STATUS_LAST_ROW_SENT = 128;
+
+ /**
+ * Have we attempted to fetch any rows yet?
+ */
+ private boolean firstFetchCompleted = false;
+
+ private boolean wasEmpty = false;
+
+ /**
+ * Creates a new cursor-backed row provider.
+ *
+ * @param ioChannel
+ * connection to the server.
+ * @param creatingStatement
+ * statement that opened the cursor.
+ * @param metadata
+ * field-level metadata for the results that this cursor covers.
+ */
+ public RowDataCursor(MysqlIO ioChannel,
+ ServerPreparedStatement creatingStatement, Field[] metadata) {
+ this.currentPositionInEntireResult = BEFORE_START_OF_ROWS;
+ this.metadata = metadata;
+ this.mysql = ioChannel;
+ this.statementIdOnServer = creatingStatement.getServerStatementId();
+ this.prepStmt = creatingStatement;
+ }
+
+ /**
+ * Returns true if we got the last element.
+ *
+ * @return DOCUMENT ME!
+ */
+ public boolean isAfterLast() {
+ return lastRowFetched
+ && this.currentPositionInFetchedRows > this.fetchedRows.size();
+ }
+
+ /**
+ * Only works on non dynamic result sets.
+ *
+ * @param index
+ * row number to get at
+ * @return row data at index
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public ResultSetRow getAt(int ind) throws SQLException {
+ notSupported();
+
+ return null;
+ }
+
+ /**
+ * Returns if iteration has not occured yet.
+ *
+ * @return true if before first row
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public boolean isBeforeFirst() throws SQLException {
+ return this.currentPositionInEntireResult < 0;
+ }
+
+ /**
+ * Moves the current position in the result set to the given row number.
+ *
+ * @param rowNumber
+ * row to move to
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void setCurrentRow(int rowNumber) throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Returns the current position in the result set as a row number.
+ *
+ * @return the current row number
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public int getCurrentRowNumber() throws SQLException {
+ return this.currentPositionInEntireResult + 1;
+ }
+
+ /**
+ * Returns true if the result set is dynamic.
+ *
+ * This means that move back and move forward won't work because we do not
+ * hold on to the records.
+ *
+ * @return true if this result set is streaming from the server
+ */
+ public boolean isDynamic() {
+ return true;
+ }
+
+ /**
+ * Has no records.
+ *
+ * @return true if no records
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public boolean isEmpty() throws SQLException {
+ return this.isBeforeFirst() && this.isAfterLast();
+ }
+
+ /**
+ * Are we on the first row of the result set?
+ *
+ * @return true if on first row
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public boolean isFirst() throws SQLException {
+ return this.currentPositionInEntireResult == 0;
+ }
+
+ /**
+ * Are we on the last row of the result set?
+ *
+ * @return true if on last row
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public boolean isLast() throws SQLException {
+ return this.lastRowFetched
+ && this.currentPositionInFetchedRows == (this.fetchedRows
+ .size() - 1);
+ }
+
+ /**
+ * Adds a row to this row data.
+ *
+ * @param row
+ * the row to add
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void addRow(ResultSetRow row) throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Moves to after last.
+ *
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void afterLast() throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Moves to before first.
+ *
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void beforeFirst() throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Moves to before last so next el is the last el.
+ *
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void beforeLast() throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * We're done.
+ *
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void close() throws SQLException {
+
+ this.metadata = null;
+ this.owner = null;
+ }
+
+ /**
+ * Returns true if another row exists.
+ *
+ * @return true if more rows
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public boolean hasNext() throws SQLException {
+
+ if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
+ return false;
+ }
+
+ if (this.owner != null && this.owner.owningStatement != null) {
+ int maxRows = this.owner.owningStatement.maxRows;
+
+ if (maxRows != -1 && this.currentPositionInEntireResult + 1 > maxRows) {
+ return false;
+ }
+ }
+
+ if (this.currentPositionInEntireResult != BEFORE_START_OF_ROWS) {
+ // Case, we've fetched some rows, but are not at end of fetched
+ // block
+ if (this.currentPositionInFetchedRows < (this.fetchedRows.size() - 1)) {
+ return true;
+ } else if (this.currentPositionInFetchedRows == this.fetchedRows
+ .size()
+ && this.lastRowFetched) {
+ return false;
+ } else {
+ // need to fetch to determine
+ fetchMoreRows();
+
+ return (this.fetchedRows.size() > 0);
+ }
+ }
+
+ // Okay, no rows _yet_, so fetch 'em
+
+ fetchMoreRows();
+
+ return this.fetchedRows.size() > 0;
+ }
+
+ /**
+ * Moves the current position relative 'rows' from the current position.
+ *
+ * @param rows
+ * the relative number of rows to move
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void moveRowRelative(int rows) throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Returns the next row.
+ *
+ * @return the next row value
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public ResultSetRow next() throws SQLException {
+ if (this.fetchedRows == null && this.currentPositionInEntireResult != BEFORE_START_OF_ROWS) {
+ throw SQLError.createSQLException(
+ Messages
+ .getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
+
+ if (!hasNext()) {
+ return null;
+ }
+
+ this.currentPositionInEntireResult++;
+ this.currentPositionInFetchedRows++;
+
+ // Catch the forced scroll-passed-end
+ if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
+ return null;
+ }
+
+ if (this.currentPositionInFetchedRows > (this.fetchedRows.size() - 1)) {
+ fetchMoreRows();
+ this.currentPositionInFetchedRows = 0;
+ }
+
+ ResultSetRow row = (ResultSetRow) this.fetchedRows
+ .get(this.currentPositionInFetchedRows);
+
+ row.setMetadata(this.metadata);
+
+ return row;
+ }
+
+ /**
+ *
+ */
+ private void fetchMoreRows() throws SQLException {
+ if (this.lastRowFetched) {
+ this.fetchedRows = new ArrayList(0);
+ return;
+ }
+
+ synchronized (this.owner.connection.getMutex()) {
+ boolean oldFirstFetchCompleted = this.firstFetchCompleted;
+
+ if (!this.firstFetchCompleted) {
+ this.firstFetchCompleted = true;
+ }
+
+ int numRowsToFetch = this.owner.getFetchSize();
+
+ if (numRowsToFetch == 0) {
+ numRowsToFetch = this.prepStmt.getFetchSize();
+ }
+
+ if (numRowsToFetch == Integer.MIN_VALUE) {
+ // Handle the case where the user used 'old'
+ // streaming result sets
+
+ numRowsToFetch = 1;
+ }
+
+ this.fetchedRows = this.mysql.fetchRowsViaCursor(this.fetchedRows,
+ this.statementIdOnServer, this.metadata, numRowsToFetch);
+ this.currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
+
+ if ((this.mysql.getServerStatus() & SERVER_STATUS_LAST_ROW_SENT) != 0) {
+ this.lastRowFetched = true;
+
+ if (!oldFirstFetchCompleted && this.fetchedRows.size() == 0) {
+ this.wasEmpty = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the row at the given index.
+ *
+ * @param index
+ * the row to move to
+ * @throws SQLException
+ * if a database error occurs
+ */
+ public void removeRow(int ind) throws SQLException {
+ notSupported();
+ }
+
+ /**
+ * Only works on non dynamic result sets.
+ *
+ * @return the size of this row data
+ */
+ public int size() {
+ return RESULT_SET_SIZE_UNKNOWN;
+ }
+
+ private void nextRecord() throws SQLException {
+
+ }
+
+ private void notSupported() throws SQLException {
+ throw new OperationNotSupportedException();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.mysql.jdbc.RowProvider#setOwner(com.mysql.jdbc.ResultSet)
+ */
+ public void setOwner(ResultSetImpl rs) {
+ this.owner = rs;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.mysql.jdbc.RowProvider#getOwner()
+ */
+ public ResultSetInternalMethods getOwner() {
+ return this.owner;
+ }
+
+ public boolean wasEmpty() {
+ return this.wasEmpty;
+ }
+
+ public void setMetadata(Field[] metadata) {
+ this.metadata = metadata;
+ }
+
+}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -58,7 +58,7 @@
private boolean isBinaryEncoded = false;
- private RowHolder nextRow;
+ private ResultSetRow nextRow;
private ResultSetImpl owner;
@@ -97,7 +97,7 @@
* @throws SQLException
* if a database error occurs
*/
- public void addRow(RowHolder row) throws SQLException {
+ public void addRow(ResultSetRow row) throws SQLException {
notSupported();
}
@@ -243,7 +243,7 @@
* @throws SQLException
* if a database error occurs
*/
- public RowHolder getAt(int ind) throws SQLException {
+ public ResultSetRow getAt(int ind) throws SQLException {
notSupported();
return null;
@@ -379,7 +379,7 @@
* @throws SQLException
* if a database error occurs
*/
- public RowHolder next() throws SQLException {
+ public ResultSetRow next() throws SQLException {
nextRecord();
@@ -402,8 +402,7 @@
private void nextRecord() throws SQLException {
try {
- if (!this.isAtEnd) {
-
+ if (!this.isAtEnd) {
this.nextRow = this.io.nextRow(this.fields, this.columnCount,
this.isBinaryEncoded,
java.sql.ResultSet.CONCUR_READ_ONLY, true, true, null);
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataKeyset.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataKeyset.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataKeyset.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -44,7 +44,7 @@
return canonicalSql.substring(whereClausePos);
}
- public void addRow(RowHolder row) throws SQLException {
+ public void addRow(ResultSetRow row) throws SQLException {
// TODO Auto-generated method stub
}
@@ -82,7 +82,7 @@
}
}
- public RowHolder getAt(int index) throws SQLException {
+ public ResultSetRow getAt(int index) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@@ -137,7 +137,7 @@
}
- public RowHolder next() throws SQLException {
+ public ResultSetRow next() throws SQLException {
// TODO Auto-generated method stub
return null;
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataStatic.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataStatic.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataStatic.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -60,7 +60,7 @@
* @param row
* DOCUMENT ME!
*/
- public void addRow(RowHolder row) {
+ public void addRow(ResultSetRow row) {
this.rows.add(row);
}
@@ -99,12 +99,12 @@
*
* @return DOCUMENT ME!
*/
- public RowHolder getAt(int atIndex) {
+ public ResultSetRow getAt(int atIndex) {
if ((atIndex < 0) || (atIndex >= this.rows.size())) {
return null;
}
- return (RowHolder) this.rows.get(atIndex);
+ return (ResultSetRow) this.rows.get(atIndex);
}
/**
@@ -211,11 +211,11 @@
*
* @return DOCUMENT ME!
*/
- public RowHolder next() throws SQLException {
+ public ResultSetRow next() throws SQLException {
this.index++;
if (this.index < this.rows.size()) {
- RowHolder row = (RowHolder) this.rows.get(this.index);
+ ResultSetRow row = (ResultSetRow) this.rows.get(this.index);
row.setMetadata(this.metadata);
return row;
Deleted: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1,1356 +0,0 @@
-/*
- Copyright (C) 2007 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-
- There are special exceptions to the terms and conditions of the GPL
- as it is applied to this software. View the full text of the
- exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
- software distribution.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- */
-package com.mysql.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.sql.Date;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-
-/**
- * Classes that implement this interface represent one row of data from the
- * MySQL server that might be stored in different ways depending on whether the
- * result set was streaming (so they wrap a reusable packet), or whether the
- * result set was cached or via a server-side cursor (so they represent a
- * byte[][]).
- *
- * Notice that <strong>no</strong> bounds checking is expected for implementors
- * of this interface, it happens in ResultSetImpl.
- *
- * @version $Id: $
- */
-public abstract class RowHolder {
- /**
- * The metadata of the fields of this result set.
- */
- protected Field[] metadata;
-
- public abstract void closeOpenStreams();
-
- public abstract InputStream getBinaryInputStream(int columnIndex)
- throws SQLException;
-
- /**
- * Returns the value at the given column (index starts at 0) "raw" (i.e.
- * as-returned by the server).
- *
- * @param index
- * of the column value (starting at 0) to return.
- * @return the value for the given column (including NULL if it is)
- * @throws SQLException
- * if an error occurs while retrieving the value.
- */
- public abstract byte[] getColumnValue(int index) throws SQLException;
-
- protected final java.sql.Date getDateFast(int columnIndex,
- byte[] dateAsBytes, int offset, int length, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
-
- int year = 0;
- int month = 0;
- int day = 0;
-
- try {
- if (dateAsBytes == null) {
- return null;
- }
-
- boolean allZeroDate = true;
-
- boolean onlyTimePresent = false;
-
- for (int i = 0; i < length; i++) {
- if (dateAsBytes[offset + i] == ':') {
- onlyTimePresent = true;
- break;
- }
- }
-
- for (int i = 0; i < length; i++) {
- byte b = dateAsBytes[offset + i];
-
- if (b == ' ' || b == '-' || b == '/') {
- onlyTimePresent = false;
- }
-
- if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
- && b != '.') {
- allZeroDate = false;
-
- break;
- }
- }
-
- if (!onlyTimePresent && allZeroDate) {
-
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError.createSQLException("Value '"
- + new String(dateAsBytes)
- + "' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- // We're left with the case of 'round' to a date Java _can_
- // represent, which is '0001-01-01'.
- return rs.fastDateCreate(null, 1, 1, 1);
-
- } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
- // Convert from TIMESTAMP
- switch (length) {
- case 21:
- case 19: { // java.sql.Timestamp format
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 4);
- month = StringUtils.getInt(dateAsBytes, offset + 5,
- offset + 7);
- day = StringUtils.getInt(dateAsBytes, offset + 8,
- offset + 10);
-
- return rs.fastDateCreate(null, year, month, day);
- }
-
- case 14:
- case 8: {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 4);
- month = StringUtils.getInt(dateAsBytes, offset + 4,
- offset + 6);
- day = StringUtils.getInt(dateAsBytes, offset + 6,
- offset + 8);
-
- return rs.fastDateCreate(null, year, month, day);
- }
-
- case 12:
- case 10:
- case 6: {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 2);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- month = StringUtils.getInt(dateAsBytes, offset + 2,
- offset + 4);
- day = StringUtils.getInt(dateAsBytes, offset + 4,
- offset + 6);
-
- return rs.fastDateCreate(null, year + 1900, month, day);
- }
-
- case 4: {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 4);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- month = StringUtils.getInt(dateAsBytes, offset + 2,
- offset + 4);
-
- return rs.fastDateCreate(null, year + 1900, month, 1);
- }
-
- case 2: {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 2);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- return rs.fastDateCreate(null, year + 1900, 1, 1);
- }
-
- default:
- throw SQLError
- .createSQLException(
- Messages
- .getString(
- "ResultSet.Bad_format_for_Date",
- new Object[] {
- new String(
- dateAsBytes),
- Constants
- .integerValueOf(columnIndex + 1) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- } /* endswitch */
- } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
-
- if (length == 2 || length == 1) {
- year = StringUtils.getInt(dateAsBytes, offset, offset
- + length);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- year += 1900;
- } else {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 4);
- }
-
- return rs.fastDateCreate(null, year, 1, 1);
- } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
- return rs.fastDateCreate(null, 1970, 1, 1); // Return EPOCH
- } else {
- if (length < 10) {
- if (length == 8) {
- return rs.fastDateCreate(null, 1970, 1, 1); // Return
- // EPOCH for
- // TIME
- }
-
- throw SQLError
- .createSQLException(
- Messages
- .getString(
- "ResultSet.Bad_format_for_Date",
- new Object[] {
- new String(
- dateAsBytes),
- Constants
- .integerValueOf(columnIndex + 1) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- }
-
- if (length != 18) {
- year = StringUtils.getInt(dateAsBytes, offset + 0,
- offset + 4);
- month = StringUtils.getInt(dateAsBytes, offset + 5,
- offset + 7);
- day = StringUtils.getInt(dateAsBytes, offset + 8,
- offset + 10);
- } else {
- // JDK-1.3 timestamp format, not real easy to parse
- // positionally :p
- StringTokenizer st = new StringTokenizer(new String(
- dateAsBytes, offset, length, "ISO8859_1"), "- ");
-
- year = Integer.parseInt(st.nextToken());
- month = Integer.parseInt(st.nextToken());
- day = Integer.parseInt(st.nextToken());
- }
- }
-
- return rs.fastDateCreate(null, year, month, day);
- } catch (SQLException sqlEx) {
- throw sqlEx; // don't re-wrap
- } catch (Exception e) {
- throw SQLError.createSQLException(Messages.getString(
- "ResultSet.Bad_format_for_Date", new Object[] {
- new String(dateAsBytes),
- Constants.integerValueOf(columnIndex + 1) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- }
- }
-
- public abstract java.sql.Date getDateFast(int columnIndex,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
-
- /**
- * Returns the value at the given column (index starts at 0) as an int. *
- *
- * @param index
- * of the column value (starting at 0) to return.
- * @return the value for the given column (returns 0 if NULL, use isNull()
- * to determine if the value was actually NULL)
- * @throws SQLException
- * if an error occurs while retrieving the value.
- */
- public abstract int getInt(int columnIndex) throws SQLException;
-
- /**
- * Returns the value at the given column (index starts at 0) as a long. *
- *
- * @param index
- * of the column value (starting at 0) to return.
- * @return the value for the given column (returns 0 if NULL, use isNull()
- * to determine if the value was actually NULL)
- * @throws SQLException
- * if an error occurs while retrieving the value.
- */
- public abstract long getLong(int columnIndex) throws SQLException;
-
- protected java.sql.Date getNativeDate(int columnIndex, byte[] bits,
- int offset, int length, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException {
-
- int year = 0;
- int month = 0;
- int day = 0;
-
- if (length != 0) {
- year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
-
- month = bits[offset + 2];
- day = bits[offset + 3];
- }
-
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError
- .createSQLException(
- "Value '0000-00-00' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- return rs.fastDateCreate(rs.getCalendarInstanceForSessionOrNew(), year,
- month, day);
- }
-
- public abstract Date getNativeDate(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException;
-
- protected Object getNativeDateTimeValue(int columnIndex, byte[] bits,
- int offset, int length, Calendar targetCalendar, int jdbcType,
- int mysqlType, TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException {
-
- int year = 0;
- int month = 0;
- int day = 0;
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- int nanos = 0;
-
- if (bits == null) {
-
- return null;
- }
-
- Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
- .getUtcCalendar()
- : rs.getCalendarInstanceForSessionOrNew();
-
- boolean populatedFromDateTimeValue = false;
-
- switch (mysqlType) {
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- populatedFromDateTimeValue = true;
-
- if (length != 0) {
- year = (bits[offset + 0] & 0xff)
- | ((bits[offset + 1] & 0xff) << 8);
- month = bits[offset + 2];
- day = bits[offset + 3];
-
- if (length > 4) {
- hour = bits[offset + 4];
- minute = bits[offset + 5];
- seconds = bits[offset + 6];
- }
-
- if (length > 7) {
- // MySQL uses microseconds
- nanos = ((bits[offset + 7] & 0xff)
- | ((bits[offset + 8] & 0xff) << 8)
- | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
- }
- }
-
- break;
- case MysqlDefs.FIELD_TYPE_DATE:
- populatedFromDateTimeValue = true;
-
- if (bits.length != 0) {
- year = (bits[offset + 0] & 0xff)
- | ((bits[offset + 1] & 0xff) << 8);
- month = bits[offset + 2];
- day = bits[offset + 3];
- }
-
- break;
- case MysqlDefs.FIELD_TYPE_TIME:
- populatedFromDateTimeValue = true;
-
- if (bits.length != 0) {
- // bits[0] // skip tm->neg
- // binaryData.readLong(); // skip daysPart
- hour = bits[offset + 5];
- minute = bits[offset + 6];
- seconds = bits[offset + 7];
- }
-
- year = 1970;
- month = 1;
- day = 1;
-
- break;
- default:
- populatedFromDateTimeValue = false;
- }
-
- switch (jdbcType) {
- case Types.TIME:
- if (populatedFromDateTimeValue) {
- Time time = TimeUtil.fastTimeCreate(rs
- .getCalendarInstanceForSessionOrNew(), hour, minute,
- seconds);
-
- Time adjustedTime = TimeUtil.changeTimezone(conn,
- sessionCalendar, targetCalendar, time, conn
- .getServerTimezoneTZ(), tz, rollForward);
-
- return adjustedTime;
- }
-
- return rs.getNativeTimeViaParseConversion(columnIndex + 1,
- targetCalendar, tz, rollForward);
-
- case Types.DATE:
- if (populatedFromDateTimeValue) {
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw new SQLException(
- "Value '0000-00-00' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- return rs
- .fastDateCreate(
- rs.getCalendarInstanceForSessionOrNew(), year,
- month, day);
- }
-
- return rs.getNativeDateViaParseConversion(columnIndex + 1);
- case Types.TIMESTAMP:
- if (populatedFromDateTimeValue) {
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw new SQLException(
- "Value '0000-00-00' can not be represented as java.sql.Timestamp",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- Timestamp ts = rs.fastTimestampCreate(rs
- .getCalendarInstanceForSessionOrNew(), year, month,
- day, hour, minute, seconds, nanos);
-
- Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
- sessionCalendar, targetCalendar, ts, conn
- .getServerTimezoneTZ(), tz, rollForward);
-
- return adjustedTs;
- }
-
- return rs.getNativeTimestampViaParseConversion(columnIndex + 1,
- targetCalendar, tz, rollForward);
-
- default:
- throw new SQLException(
- "Internal error - conversion method doesn't support this type",
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
-
- public abstract Object getNativeDateTimeValue(int columnIndex,
- Calendar targetCalendar, int jdbcType, int mysqlType,
- TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException;
-
- protected double getNativeDouble(byte[] bits, int offset) {
- long valueAsLong = (bits[offset + 0] & 0xff)
- | ((long) (bits[offset + 1] & 0xff) << 8)
- | ((long) (bits[offset + 2] & 0xff) << 16)
- | ((long) (bits[offset + 3] & 0xff) << 24)
- | ((long) (bits[offset + 4] & 0xff) << 32)
- | ((long) (bits[offset + 5] & 0xff) << 40)
- | ((long) (bits[offset + 6] & 0xff) << 48)
- | ((long) (bits[offset + 7] & 0xff) << 56);
-
- return Double.longBitsToDouble(valueAsLong);
- }
-
- public abstract double getNativeDouble(int columnIndex) throws SQLException;
-
- protected float getNativeFloat(byte[] bits, int offset) {
- int asInt = (bits[offset + 0] & 0xff)
- | ((bits[offset + 1] & 0xff) << 8)
- | ((bits[offset + 2] & 0xff) << 16)
- | ((bits[offset + 3] & 0xff) << 24);
-
- return Float.intBitsToFloat(asInt);
- }
-
- public abstract float getNativeFloat(int columnIndex) throws SQLException;
-
- protected int getNativeInt(byte[] bits, int offset) {
-
- int valueAsInt = (bits[offset + 0] & 0xff)
- | ((bits[offset + 1] & 0xff) << 8)
- | ((bits[offset + 2] & 0xff) << 16)
- | ((bits[offset + 3] & 0xff) << 24);
-
- return valueAsInt;
- }
-
- public abstract int getNativeInt(int columnIndex) throws SQLException;
-
- protected long getNativeLong(byte[] bits, int offset) {
- long valueAsLong = (bits[offset + 0] & 0xff)
- | ((long) (bits[offset + 1] & 0xff) << 8)
- | ((long) (bits[offset + 2] & 0xff) << 16)
- | ((long) (bits[offset + 3] & 0xff) << 24)
- | ((long) (bits[offset + 4] & 0xff) << 32)
- | ((long) (bits[offset + 5] & 0xff) << 40)
- | ((long) (bits[offset + 6] & 0xff) << 48)
- | ((long) (bits[offset + 7] & 0xff) << 56);
-
- return valueAsLong;
- }
-
- public abstract long getNativeLong(int columnIndex) throws SQLException;
-
- protected short getNativeShort(byte[] bits, int offset) {
- short asShort = (short) ((bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8));
-
- return asShort;
- }
-
- public abstract short getNativeShort(int columnIndex) throws SQLException;
-
- protected Time getNativeTime(int columnIndex, byte[] bits, int offset,
- int length, Calendar targetCalendar, TimeZone tz,
- boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException {
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- if (length != 0) {
- // bits[0] // skip tm->neg
- // binaryData.readLong(); // skip daysPart
- hour = bits[offset + 5];
- minute = bits[offset + 6];
- seconds = bits[offset + 7];
- }
-
- Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- Time time = TimeUtil.fastTimeCreate(sessionCalendar, hour, minute,
- seconds);
-
- Time adjustedTime = TimeUtil.changeTimezone(conn, sessionCalendar,
- targetCalendar, time, conn.getServerTimezoneTZ(), tz,
- rollForward);
-
- return adjustedTime;
- }
- }
-
- public abstract Time getNativeTime(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
-
- protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
- int year = 0;
- int month = 0;
- int day = 0;
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- int nanos = 0;
-
- if (length != 0) {
- year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
- month = bits[2];
- day = bits[3];
-
- if (length > 4) {
- hour = bits[offset + 4];
- minute = bits[offset + 5];
- seconds = bits[offset + 6];
- }
-
- if (length > 7) {
- // MySQL uses microseconds
- nanos = ((bits[offset + 7] & 0xff)
- | ((bits[offset + 8] & 0xff) << 8)
- | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
- }
- }
-
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError
- .createSQLException(
- "Value '0000-00-00' can not be represented as java.sql.Timestamp",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
- .getUtcCalendar()
- : rs.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- Timestamp ts = rs.fastTimestampCreate(sessionCalendar, year, month,
- day, hour, minute, seconds, nanos);
-
- Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
- sessionCalendar, targetCalendar, ts, conn
- .getServerTimezoneTZ(), tz, rollForward);
-
- return adjustedTs;
- }
- }
-
- public abstract Timestamp getNativeTimestamp(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
-
- public abstract Reader getReader(int columnIndex) throws SQLException;
-
- /**
- * Returns the value at the given column (index starts at 0) as a
- * java.lang.String with the requested encoding, using the given
- * ConnectionImpl to find character converters.
- *
- * @param index
- * of the column value (starting at 0) to return.
- * @param encoding
- * the Java name for the character encoding
- * @param conn
- * the connection that created this result set row
- *
- * @return the value for the given column (including NULL if it is) as a
- * String
- *
- * @throws SQLException
- * if an error occurs while retrieving the value.
- */
- public abstract String getString(int index, String encoding,
- ConnectionImpl conn) throws SQLException;
-
- /**
- * Convenience method for turning a byte[] into a string with the given
- * encoding.
- *
- * @param encoding
- * the Java encoding name for the byte[] -> char conversion
- * @param conn
- * the ConnectionImpl that created the result set
- * @param value
- * the String value as a series of bytes, encoded using
- * "encoding"
- * @param offset
- * where to start the decoding
- * @param length
- * how many bytes to decode
- *
- * @return the String as decoded from bytes with the given encoding
- *
- * @throws SQLException
- * if an error occurs
- */
- protected String getString(String encoding, ConnectionImpl conn,
- byte[] value, int offset, int length) throws SQLException {
- String stringVal = null;
-
- if ((conn != null) && conn.getUseUnicode()) {
- try {
- if (encoding == null) {
- stringVal = new String(value);
- } else {
- SingleByteCharsetConverter converter = conn
- .getCharsetConverter(encoding);
-
- if (converter != null) {
- stringVal = converter.toString(value, offset, length);
- } else {
- stringVal = new String(value, offset, length, encoding);
- }
- }
- } catch (java.io.UnsupportedEncodingException E) {
- throw SQLError
- .createSQLException(
- Messages
- .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
- + encoding + "'.", "0S100");
- }
- } else {
- stringVal = StringUtils.toAsciiString(value, offset, length);
- }
-
- return stringVal;
- }
-
- protected Time getTimeFast(int columnIndex, byte[] timeAsBytes, int offset,
- int length, Calendar targetCalendar, TimeZone tz,
- boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
- throws SQLException {
-
- int hr = 0;
- int min = 0;
- int sec = 0;
-
- try {
-
- if (timeAsBytes == null) {
- return null;
- }
-
- boolean allZeroTime = true;
- boolean onlyTimePresent = false;
-
- for (int i = 0; i < length; i++) {
- if (timeAsBytes[offset + i] == ':') {
- onlyTimePresent = true;
- break;
- }
- }
-
- for (int i = 0; i < length; i++) {
- byte b = timeAsBytes[offset + i];
-
- if (b == ' ' || b == '-' || b == '/') {
- onlyTimePresent = false;
- }
-
- if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
- && b != '.') {
- allZeroTime = false;
-
- break;
- }
- }
-
- if (!onlyTimePresent && allZeroTime) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError.createSQLException("Value '"
- + new String(timeAsBytes)
- + "' can not be represented as java.sql.Time",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- // We're left with the case of 'round' to a time Java _can_
- // represent, which is '00:00:00'
- return rs.fastTimeCreate(null, 0, 0, 0);
- }
-
- Field timeColField = this.metadata[columnIndex];
-
- if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
-
- switch (length) {
- case 19: { // YYYY-MM-DD hh:mm:ss
-
- hr = StringUtils.getInt(timeAsBytes, offset + length - 8,
- offset + length - 6);
- min = StringUtils.getInt(timeAsBytes, offset + length - 5,
- offset + length - 3);
- sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
- offset + length);
- }
-
- break;
- case 14:
- case 12: {
- hr = StringUtils.getInt(timeAsBytes, offset + length - 6,
- offset + length - 4);
- min = StringUtils.getInt(timeAsBytes, offset + length - 4,
- offset + length - 2);
- sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
- offset + length);
- }
-
- break;
-
- case 10: {
- hr = StringUtils
- .getInt(timeAsBytes, offset + 6, offset + 8);
- min = StringUtils.getInt(timeAsBytes, offset + 8,
- offset + 10);
- sec = 0;
- }
-
- break;
-
- default:
- throw SQLError
- .createSQLException(
- Messages
- .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
- + (columnIndex + 1)
- + "("
- + timeColField + ").",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- } /* endswitch */
-
- SQLWarning precisionLost = new SQLWarning(
- Messages
- .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
- + columnIndex + "(" + timeColField + ").");
- /*
- * if (this.warningChain == null) { this.warningChain =
- * precisionLost; } else {
- * this.warningChain.setNextWarning(precisionLost); }
- */
- } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
- hr = StringUtils.getInt(timeAsBytes, offset + 11, offset + 13);
- min = StringUtils.getInt(timeAsBytes, offset + 14, offset + 16);
- sec = StringUtils.getInt(timeAsBytes, offset + 17, offset + 19);
-
- SQLWarning precisionLost = new SQLWarning(
- Messages
- .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
- + (columnIndex + 1) + "(" + timeColField + ").");
-
- /*
- * if (this.warningChain == null) { this.warningChain =
- * precisionLost; } else {
- * this.warningChain.setNextWarning(precisionLost); }
- */
- } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
- return rs.fastTimeCreate(null, 0, 0, 0); // midnight on the
- // given
- // date
- } else {
- // convert a String to a Time
- if ((length != 5) && (length != 8)) {
- throw SQLError.createSQLException(Messages
- .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
- + new String(timeAsBytes)
- + Messages.getString("ResultSet.___in_column__268")
- + (columnIndex + 1),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2);
- min = StringUtils.getInt(timeAsBytes, offset + 3, offset + 5);
- sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes,
- offset + 6, offset + 8);
- }
-
- Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- return TimeUtil.changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimeCreate(sessionCalendar, hr,
- min, sec), conn.getServerTimezoneTZ(), tz,
- rollForward);
- }
- } catch (Exception ex) {
- throw SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
-
- public abstract Time getTimeFast(int columnIndex, Calendar targetCalendar,
- TimeZone tz, boolean rollForward, ConnectionImpl conn,
- ResultSetImpl rs) throws SQLException;
-
- protected Timestamp getTimestampFast(int columnIndex,
- byte[] timestampAsBytes, int offset, int length,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
-
- try {
- Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
- .getUtcCalendar()
- : rs.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- boolean allZeroTimestamp = true;
-
- boolean onlyTimePresent = false;
-
- for (int i = 0; i < length; i++) {
- if (timestampAsBytes[offset + i] == ':') {
- onlyTimePresent = true;
- break;
- }
- }
-
- for (int i = 0; i < length; i++) {
- byte b = timestampAsBytes[offset + i];
-
- if (b == ' ' || b == '-' || b == '/') {
- onlyTimePresent = false;
- }
-
- if (b != '0' && b != ' ' && b != ':' && b != '-'
- && b != '/' && b != '.') {
- allZeroTimestamp = false;
-
- break;
- }
- }
-
- if (!onlyTimePresent && allZeroTimestamp) {
-
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError
- .createSQLException(
- "Value '"
- + timestampAsBytes
- + "' can not be represented as java.sql.Timestamp",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- // We're left with the case of 'round' to a date Java _can_
- // represent, which is '0001-01-01'.
- return rs.fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);
-
- } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
-
- return TimeUtil.changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, StringUtils.getInt(
- timestampAsBytes, offset, 4), 1, 1,
- 0, 0, 0, 0), conn.getServerTimezoneTZ(),
- tz, rollForward);
-
- } else {
- if (timestampAsBytes[offset + length - 1] == '.') {
- length--;
- }
-
- // Convert from TIMESTAMP or DATE
- switch (length) {
- case 26:
- case 25:
- case 24:
- case 23:
- case 22:
- case 21:
- case 20:
- case 19: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 4);
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 5, offset + 7);
- int day = StringUtils.getInt(timestampAsBytes,
- offset + 8, offset + 10);
- int hour = StringUtils.getInt(timestampAsBytes,
- offset + 11, offset + 13);
- int minutes = StringUtils.getInt(timestampAsBytes,
- offset + 14, offset + 16);
- int seconds = StringUtils.getInt(timestampAsBytes,
- offset + 17, offset + 19);
-
- int nanos = 0;
-
- if (length > 19) {
- int decimalIndex = -1;
-
- for (int i = 0; i < length; i++) {
- if (timestampAsBytes[offset + i] == '.') {
- decimalIndex = i;
- }
- }
-
- if (decimalIndex != -1) {
- if ((decimalIndex + 2) <= length) {
- nanos = StringUtils.getInt(
- timestampAsBytes, decimalIndex + 1,
- offset + length);
- } else {
- throw new IllegalArgumentException(); // re-thrown
- // further
- // down
- // with
- // a
- // much better error message
- }
- }
- }
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year, month,
- day, hour, minutes, seconds,
- nanos), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 14: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 4);
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 4, offset + 6);
- int day = StringUtils.getInt(timestampAsBytes,
- offset + 6, offset + 8);
- int hour = StringUtils.getInt(timestampAsBytes,
- offset + 8, offset + 10);
- int minutes = StringUtils.getInt(timestampAsBytes,
- offset + 10, offset + 12);
- int seconds = StringUtils.getInt(timestampAsBytes,
- offset + 12, offset + 14);
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar,
- rs.fastTimestampCreate(sessionCalendar,
- year, month, day, hour,
- minutes, seconds, 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 12: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
-
- if (year <= 69) {
- year = (year + 100);
- }
-
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 2, offset + 4);
- int day = StringUtils.getInt(timestampAsBytes,
- offset + 4, offset + 6);
- int hour = StringUtils.getInt(timestampAsBytes,
- offset + 6, offset + 8);
- int minutes = StringUtils.getInt(timestampAsBytes,
- offset + 8, offset + 10);
- int seconds = StringUtils.getInt(timestampAsBytes,
- offset + 10, offset + 12);
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year + 1900,
- month, day, hour, minutes,
- seconds, 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 10: {
- int year;
- int month;
- int day;
- int hour;
- int minutes;
-
- boolean hasDash = false;
-
- for (int i = 0; i < length; i++) {
- if (timestampAsBytes[offset + i] == '-') {
- hasDash = true;
- break;
- }
- }
-
- if ((this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
- || hasDash) {
- year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 4);
- month = StringUtils.getInt(timestampAsBytes,
- offset + 5, offset + 7);
- day = StringUtils.getInt(timestampAsBytes,
- offset + 8, offset + 10);
- hour = 0;
- minutes = 0;
- } else {
- year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
-
- if (year <= 69) {
- year = (year + 100);
- }
-
- month = StringUtils.getInt(timestampAsBytes,
- offset + 2, offset + 4);
- day = StringUtils.getInt(timestampAsBytes,
- offset + 4, offset + 6);
- hour = StringUtils.getInt(timestampAsBytes,
- offset + 6, offset + 8);
- minutes = StringUtils.getInt(timestampAsBytes,
- offset + 8, offset + 10);
-
- year += 1900; // two-digit year
- }
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year, month,
- day, hour, minutes, 0, 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 8: {
- boolean hasColon = false;
-
- for (int i = 0; i < length; i++) {
- if (timestampAsBytes[offset + i] == ':') {
- hasColon = true;
- break;
- }
- }
-
- if (hasColon) {
- int hour = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
- int minutes = StringUtils.getInt(timestampAsBytes,
- offset + 3, offset + 5);
- int seconds = StringUtils.getInt(timestampAsBytes,
- offset + 6, offset + 8);
-
- return TimeUtil.changeTimezone(conn,
- sessionCalendar, targetCalendar, rs
- .fastTimestampCreate(
- sessionCalendar, 1970, 1,
- 1, hour, minutes, seconds,
- 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
-
- }
-
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 4);
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 4, offset + 6);
- int day = StringUtils.getInt(timestampAsBytes,
- offset + 6, offset + 8);
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year - 1900,
- month - 1, day, 0, 0, 0, 0),
- conn.getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 6: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
-
- if (year <= 69) {
- year = (year + 100);
- }
-
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 2, offset + 4);
- int day = StringUtils.getInt(timestampAsBytes,
- offset + 4, offset + 6);
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year + 1900,
- month, day, 0, 0, 0, 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- case 4: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
-
- if (year <= 69) {
- year = (year + 100);
- }
-
- int month = StringUtils.getInt(timestampAsBytes,
- offset + 2, offset + 4);
-
- return TimeUtil.changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- sessionCalendar, year + 1900, month, 1,
- 0, 0, 0, 0),
- conn.getServerTimezoneTZ(), tz, rollForward);
- }
-
- case 2: {
- int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, offset + 2);
-
- if (year <= 69) {
- year = (year + 100);
- }
-
- return TimeUtil
- .changeTimezone(conn, sessionCalendar,
- targetCalendar, rs.fastTimestampCreate(
- null, year + 1900, 1, 1, 0, 0,
- 0, 0), conn
- .getServerTimezoneTZ(), tz,
- rollForward);
- }
-
- default:
- throw new java.sql.SQLException(
- "Bad format for Timestamp '"
- + new String(timestampAsBytes)
- + "' in column " + (columnIndex + 1)
- + ".",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
- }
- } catch (Exception e) {
- throw new java.sql.SQLException("Cannot convert value '"
- + getString(columnIndex, "ISO8859_1", conn)
- + "' from column " + (columnIndex + 1) + " to TIMESTAMP.",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
-
- public abstract Timestamp getTimestampFast(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
-
- /**
- * Could the column value at the given index (which starts at 0) be
- * interpreted as a floating-point number (has +/-/E/e in it)?
- *
- * @param index
- * of the column value (starting at 0) to check.
- *
- * @return true if the column value at the given index looks like it might
- * be a floating-point number, false if not.
- *
- * @throws SQLException
- * if an error occurs
- */
- public abstract boolean isFloatingPointNumber(int index)
- throws SQLException;
-
- /**
- * Is the column value at the given index (which starts at 0) NULL?
- *
- * @param index
- * of the column value (starting at 0) to check.
- *
- * @return true if the column value is NULL, false if not.
- *
- * @throws SQLException
- * if an error occurs
- */
- public abstract boolean isNull(int index) throws SQLException;
-
- /**
- * Returns the length of the column at the given index (which starts at 0).
- *
- * @param index
- * of the column value (starting at 0) for which to return the
- * length.
- * @return the length of the requested column, 0 if null (clients of this
- * interface should use isNull() beforehand to determine status of
- * NULL values in the column).
- *
- * @throws SQLException
- */
- public abstract long length(int index) throws SQLException;
-
- /**
- * Sets the given column value (only works currently with
- * ByteArrayRowHolder).
- *
- * @param index
- * index of the column value (starting at 0) to set.
- * @param value
- * the (raw) value to set
- *
- * @throws SQLException
- * if an error occurs, or the concrete RowHolder doesn't support
- * this operation.
- */
- public abstract void setColumnValue(int index, byte[] value)
- throws SQLException;
-
- public void setMetadata(Field[] f) throws SQLException {
- this.metadata = f;
- }
-}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -696,7 +696,7 @@
while (rs.next()) {
this.batchedGeneratedKeys
- .add(new ByteArrayRowHolder(new byte[][] { rs
+ .add(new ByteArrayRow(new byte[][] { rs
.getBytes(1) }));
}
} finally {
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -1597,7 +1597,7 @@
for (int i = 0; i < numKeys; i++) {
byte[][] row = new byte[1][];
row[0] = Long.toString(beginAt++).getBytes();
- rowSet.add(new ByteArrayRowHolder(row));
+ rowSet.add(new ByteArrayRow(row));
}
}
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/UpdatableResultSet.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/UpdatableResultSet.java 2007-06-15 01:10:23 UTC (rev 6450)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/UpdatableResultSet.java 2007-06-15 01:24:27 UTC (rev 6451)
@@ -85,7 +85,7 @@
private String refreshSQL = null;
/** The binary data for the 'current' row */
- private RowHolder savedCurrentRow;
+ private ResultSetRow savedCurrentRow;
private String tableOnlyName;
@@ -780,11 +780,11 @@
}
}
- RowHolder rowHolder = new ByteArrayRowHolder(newRow);
+ ResultSetRow resultSetRow = new ByteArrayRow(newRow);
- refreshRow(this.inserter, rowHolder);
+ refreshRow(this.inserter, resultSetRow);
- this.rowData.addRow(rowHolder);
+ this.rowData.addRow(resultSetRow);
resetInserter();
}
@@ -947,7 +947,7 @@
this.doingUpdates = false;
this.savedCurrentRow = this.thisRow;
byte[][] newRowData = new byte[numFields][];
- this.thisRow = new ByteArrayRowHolder(newRowData);
+ this.thisRow = new ByteArrayRow(newRowData);
for (int i = 0; i < numFields; i++) {
if (!this.populateInserterWithDefaultValues) {
@@ -1178,7 +1178,7 @@
}
private synchronized void refreshRow(PreparedStatement updateInsertStmt,
- RowHolder rowToRefresh) throws SQLException {
+ ResultSetRow rowToRefresh) throws SQLException {
if (this.refresher == null) {
if (this.refreshSQL == null) {
generateStatements();
| Thread |
|---|
| • Connector/J commit: r6451 - branches/branch_5_1/connector-j/src/com/mysql/jdbc | mmatthews | 15 Jun |