?? mysqlio.java
字號:
* method uses the specified character encoding to get the bytes from the
* query string.
*
* @param query DOCUMENT ME!
* @param maxRows DOCUMENT ME!
* @param characterEncoding DOCUMENT ME!
* @param conn DOCUMENT ME!
* @param resultSetType DOCUMENT ME!
* @param streamResults DOCUMENT ME!
* @param catalog DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
final ResultSet sqlQuery(String query, int maxRows,
String characterEncoding, Connection conn, int resultSetType,
boolean streamResults, String catalog) throws Exception {
// We don't know exactly how many bytes we're going to get
// from the query. Since we're dealing with Unicode, the
// max is 2, so pad it (2 * query) + space for headers
int packLength = HEADER_LENGTH + 1 + (query.length() * 2) + 2;
if (this.sendPacket == null) {
this.sendPacket = new Buffer(packLength);
} else {
this.sendPacket.clear();
}
this.sendPacket.writeByte((byte) MysqlDefs.QUERY);
if (characterEncoding != null) {
SingleByteCharsetConverter converter = this.connection
.getCharsetConverter(characterEncoding);
if (this.platformDbCharsetMatches) {
this.sendPacket.writeStringNoNull(query, characterEncoding,
converter);
} else {
if (StringUtils.startsWithIgnoreCaseAndWs(query, "LOAD DATA")) {
this.sendPacket.writeBytesNoNull(query.getBytes());
} else {
this.sendPacket.writeStringNoNull(query, characterEncoding,
converter);
}
}
} else {
this.sendPacket.writeStringNoNull(query);
}
return sqlQueryDirect(this.sendPacket, maxRows, conn, resultSetType,
streamResults, catalog);
}
/**
* Send a query stored in a packet directly to the server.
*
* @param queryPacket DOCUMENT ME!
* @param maxRows DOCUMENT ME!
* @param conn DOCUMENT ME!
* @param resultSetType DOCUMENT ME!
* @param streamResults DOCUMENT ME!
* @param catalog DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws Exception DOCUMENT ME!
*/
final ResultSet sqlQueryDirect(Buffer queryPacket, int maxRows,
Connection conn, int resultSetType, boolean streamResults,
String catalog) throws Exception {
StringBuffer profileMsgBuf = null; // used if profiling
long queryStartTime = 0;
if (this.profileSql) {
profileMsgBuf = new StringBuffer();
queryStartTime = System.currentTimeMillis();
byte[] queryBuf = queryPacket.getByteBuffer();
// Extract the actual query from the network packet
String query = new String(queryBuf, 5,
(queryPacket.getPosition() - 5));
profileMsgBuf.append("Query\t\"");
profileMsgBuf.append(query);
profileMsgBuf.append("\"\texecution time:\t");
}
// Send query command and sql query string
Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket);
if (this.profileSql) {
long executionTime = System.currentTimeMillis() - queryStartTime;
profileMsgBuf.append(executionTime);
profileMsgBuf.append("\t");
}
resultPacket.setPosition(resultPacket.getPosition() - 1);
long columnCount = resultPacket.readFieldLength();
if (Driver.TRACE) {
Debug.msg(this, "Column count: " + columnCount);
}
if (columnCount == 0) {
if (this.profileSql) {
System.err.println(profileMsgBuf.toString());
}
return buildResultSetWithUpdates(resultPacket);
} else if (columnCount == Buffer.NULL_LENGTH) {
String charEncoding = null;
if (this.connection.useUnicode()) {
charEncoding = this.connection.getEncoding();
}
String fileName = null;
if (this.platformDbCharsetMatches) {
fileName = ((charEncoding != null)
? resultPacket.readString(charEncoding)
: resultPacket.readString());
} else {
fileName = resultPacket.readString();
}
return sendFileToServer(fileName);
} else {
long fetchStartTime = 0;
if (this.profileSql) {
fetchStartTime = System.currentTimeMillis();
}
com.mysql.jdbc.ResultSet results = getResultSet(columnCount,
maxRows, resultSetType, streamResults, catalog);
if (this.profileSql) {
long fetchElapsedTime = System.currentTimeMillis()
- fetchStartTime;
profileMsgBuf.append("result set fetch time:\t");
profileMsgBuf.append(fetchElapsedTime);
System.err.println(profileMsgBuf.toString());
}
return results;
}
}
/**
* Returns the host this IO is connected to
*
* @return DOCUMENT ME!
*/
String getHost() {
return this.host;
}
/**
* Does the version of the MySQL server we are connected to meet the given
* minimums?
*
* @param major DOCUMENT ME!
* @param minor DOCUMENT ME!
* @param subminor DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
boolean versionMeetsMinimum(int major, int minor, int subminor) {
if (getServerMajorVersion() >= major) {
if (getServerMajorVersion() == major) {
if (getServerMinorVersion() >= minor) {
if (getServerMinorVersion() == minor) {
return (getServerSubMinorVersion() >= subminor);
} else {
// newer than major.minor
return true;
}
} else {
// older than major.minor
return false;
}
} else {
// newer than major
return true;
}
} else {
return false;
}
}
private final int readFully(InputStream in, byte[] b, int off, int len)
throws IOException {
if (len < 0) {
throw new IndexOutOfBoundsException();
}
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count < 0) {
throw new EOFException();
}
n += count;
}
return n;
}
/**
* Read one packet from the MySQL server
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
* @throws java.sql.SQLException DOCUMENT ME!
*/
private final Buffer readPacket() throws SQLException {
try {
int lengthRead = readFully(mysqlInput, this.packetHeaderBuf, 0, 4);
if (lengthRead < 4) {
forceClose();
throw new IOException("Unexpected end of input stream");
}
int packetLength = ((int) (this.packetHeaderBuf[0] & 0xff))
+ (((int) (this.packetHeaderBuf[1] & 0xff)) << 8)
+ (((int) (this.packetHeaderBuf[2] & 0xff)) << 16);
byte multiPacketSeq = this.packetHeaderBuf[3];
// Read data
byte[] buffer = new byte[packetLength + 1];
readFully(this.mysqlInput, buffer, 0, packetLength);
buffer[packetLength] = 0;
Buffer packet = new Buffer(buffer);
return packet;
} catch (IOException ioEx) {
StringBuffer message = new StringBuffer(SQLError.get(
SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE));
message.append(": ");
message.append(ioEx.getClass().getName());
message.append(", underlying cause: ");
message.append(ioEx.getMessage());
if (!this.connection.useParanoidErrorMessages()) {
message.append(Util.stackTraceToString(ioEx));
}
throw new java.sql.SQLException(message.toString(),
SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, 0);
}
}
private com.mysql.jdbc.ResultSet buildResultSetWithRows(String catalog,
com.mysql.jdbc.Field[] fields, RowData rows, int resultSetConcurrency)
throws SQLException {
switch (resultSetConcurrency) {
case java.sql.ResultSet.CONCUR_READ_ONLY:
return new com.mysql.jdbc.ResultSet(catalog, fields, rows,
this.connection);
case java.sql.ResultSet.CONCUR_UPDATABLE:
return new com.mysql.jdbc.UpdatableResultSet(catalog, fields, rows,
this.connection);
default:
return new com.mysql.jdbc.ResultSet(catalog, fields, rows,
this.connection);
}
}
private com.mysql.jdbc.ResultSet buildResultSetWithUpdates(
Buffer resultPacket) throws SQLException {
long updateCount = -1;
long updateID = -1;
String info = null;
try {
if (this.useNewUpdateCounts) {
updateCount = resultPacket.newReadLength();
updateID = resultPacket.newReadLength();
} else {
updateCount = (long) resultPacket.readLength();
updateID = (long) resultPacket.readLength();
}
if (this.connection.isReadInfoMsgEnabled()) {
if (this.use41Extensions) {
int serverStatus = resultPacket.readInt();
int warningCount = resultPacket.readInt();
resultPacket.readByte(); // advance pointer
}
info = resultPacket.readString();
}
} catch (Exception ex) {
throw new java.sql.SQLException(SQLError.get(
SQLError.SQL_STATE_GENERAL_ERROR) + ": "
+ ex.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR, -1);
}
if (Driver.TRACE) {
Debug.msg(this, "Update Count = " + updateCount);
}
ResultSet updateRs = new ResultSet(updateCount, updateID);
if (info != null) {
updateRs.setServerInfo(info);
}
return updateRs;
}
/**
* Don't hold on to overly-large packets
*/
private void reclaimLargeReusablePacket() {
if ((this.reusablePacket != null)
&& (this.reusablePacket.getBufLength() > 1048576)) {
this.reusablePacket = new Buffer(this.connection.getNetBufferLength());
}
}
/**
* Re-use a packet to read from the MySQL server
*
* @param reuse DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
* @throws SQLException DOCUMENT ME!
*/
private final Buffer reuseAndReadPacket(Buffer reuse)
throws SQLException {
try {
reuse.setWasMultiPacket(false);
int lengthRead = readFully(mysqlInput, this.packetHeaderBuf, 0, 4);
if (lengthRead < 4) {
forceClose();
throw new IOException("Unexpected end of input stream");
}
int packetLength = ((int) (this.packetHeaderBuf[0] & 0xff))
+ (((int) (this.packetHeaderBuf[1] & 0xff)) << 8)
+ (((int) (this.packetHeaderBuf[2] & 0xff)) << 16);
byte multiPacketSeq = this.packetHeaderBuf[3];
//byte multiPacketSeq = (byte) this.mysqlInput.read();
// Set the Buffer to it's original state
reuse.setPosition(0);
reuse.setSendLength(0);
// Do we need to re-alloc the byte buffer?
//
// Note: We actually check the length of the buffer,
// rather than getBufLength(), because getBufLength() is not
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -