?? resultsetrow.java
字號:
/*
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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -