📄 mysqlio.java
字号:
Packet = readPacket();
String TableName = Packet.readLenString();
String ColName = Packet.readLenString();
int colLength = Packet.readnBytes();
int colType = Packet.readnBytes();
Packet.readByte(); // We know it's currently 2
short colFlag = (short) (Packet.readByte() & 0xff);
int colDecimals = (Packet.readByte() & 0xff);
if (versionMeetsMinimum(3, 23, 0)) {
colDecimals++;
}
Fields[i] =
new Field(TableName, ColName, colLength, colType, colFlag, colDecimals);
}
Packet = readPacket();
Vector Rows = new Vector();
// Now read the data
byte[][] Row = nextRow((int) columnCount);
int row_count = 0;
if (Row != null) {
Rows.addElement(Row);
row_count = 1;
}
while (Row != null && row_count < max_rows) {
Row = nextRow((int) columnCount);
if (Row != null) {
Rows.addElement(Row);
row_count++;
}
else {
if (Driver.trace) {
Debug.msg(this, "* NULL Row *");
}
}
}
if (Driver.trace) {
Debug.msg(this, "* Fetched " + Rows.size() + " rows from server *");
}
return buildResultSetWithRows(Fields, Rows, null);
}
/**
* Retrieve one row from the MySQL server.
*
* Note: this method is not thread-safe, but it is only called
* from methods that are guarded by synchronizing on this object.
*/
private final byte[][] nextRow(int columnCount) throws Exception {
// Get the next incoming packet, re-using the packet because
// all the data we need gets copied out of it.
Buffer Packet = reuseAndReadPacket(_reusablePacket);
// check for errors.
if (Packet.readByte() == (byte) 0xff) {
String ErrorMessage;
int errno = 2000;
if (_protocolVersion > 9) {
errno = Packet.readInt();
ErrorMessage = Packet.readString();
String XOpen = SQLError.mysqlToXOpen(errno);
clearReceive();
throw new java.sql.SQLException(
SQLError.get(SQLError.get(XOpen)) + ": " + ErrorMessage,
XOpen,
errno);
}
else {
ErrorMessage = Packet.readString();
clearReceive();
throw new java.sql.SQLException(
ErrorMessage,
SQLError.mysqlToXOpen(errno),
errno);
}
}
// Away we go....
Packet._pos--;
int[] dataStart = new int[columnCount];
byte[][] Row = new byte[columnCount][];
if (!Packet.isLastDataPacket()) {
for (int i = 0; i < columnCount; i++) {
int p = Packet._pos;
dataStart[i] = p;
Packet._pos = (int) Packet.readLength() + Packet._pos;
}
for (int i = 0; i < columnCount; i++) {
Packet._pos = dataStart[i];
Row[i] = Packet.readLenByteArray();
if (Driver.trace) {
if (Row[i] == null) {
Debug.msg(this, "Field value: NULL");
}
else {
Debug.msg(this, "Field value: " + Row[i].toString());
}
}
}
return Row;
}
return null;
}
/**
* Log-off of the MySQL server and close the socket.
*/
final void quit() throws IOException {
Buffer Packet = new Buffer(6);
_packetSequence = -1;
Packet.writeByte((byte) MysqlDefs.QUIT);
send(Packet);
forceClose();
}
protected final void forceClose() throws IOException {
_mysqlConnection.close();
}
/**
* Get the major version of the MySQL server we are
* talking to.
*/
final int getServerMajorVersion() {
return _serverMajorVersion;
}
/**
* Get the minor version of the MySQL server we are
* talking to.
*/
final int getServerMinorVersion() {
return _serverMinorVersion;
}
/**
* Get the sub-minor version of the MySQL server we are
* talking to.
*/
final int getServerSubMinorVersion() {
return _serverSubMinorVersion;
}
/**
* Read one packet from the MySQL server
*/
private final Buffer readPacket() throws IOException {
byte b0, b1, b2;
b0 = (byte) _mysqlInput.read();
b1 = (byte) _mysqlInput.read();
b2 = (byte) _mysqlInput.read();
// If a read failure is detected, close the socket and throw an IOException
if ((int) b0 == -1 && (int) b1 == -1 && (int) b2 == -1) {
forceClose();
throw new IOException("Unexpected end of input stream");
}
int packetLength = (int) (ub(b0) + (256 * ub(b1)) + (256 * 256 * ub(b2)));
byte packetSeq = (byte) _mysqlInput.read();
// Read data
byte[] buffer = new byte[packetLength + 1];
readFully(_mysqlInput, buffer, 0, packetLength);
buffer[packetLength] = 0;
return new Buffer(buffer);
}
/**
* Re-use a packet to read from the MySQL server
*/
private final Buffer reuseAndReadPacket(Buffer Reuse) throws IOException {
byte b0, b1, b2;
b0 = (byte) _mysqlInput.read();
b1 = (byte) _mysqlInput.read();
b2 = (byte) _mysqlInput.read();
// If a read failure is detected, close the socket and throw an IOException
if ((int) b0 == -1 && (int) b1 == -1 && (int) b2 == -1) {
forceClose();
throw new IOException("Unexpected end of input stream");
}
int packetLength = (int) (ub(b0) + (256 * ub(b1)) + (256 * 256 * ub(b2)));
byte packetSeq = (byte) _mysqlInput.read();
// Set the Buffer to it's original state
Reuse._pos = 0;
Reuse._sendLength = 0;
// Do we need to re-alloc the byte buffer?
//
// Note: We actually check the length of the buffer,
// rather than buf_length, because buf_length is not
// necesarily the actual length of the byte array
// used as the buffer
if (Reuse._buf.length <= packetLength) {
Reuse._buf = new byte[packetLength + 1];
}
// Set the new length
Reuse._bufLength = packetLength;
// Read the data from the server
readFully(_mysqlInput, Reuse._buf, 0, packetLength);
Reuse._buf[packetLength] = 0; // Null-termination
return Reuse;
}
/**
* Send a packet to the MySQL server
*/
private final void send(Buffer Packet) throws IOException {
int l = Packet._pos;
_packetSequence++;
Packet._pos = 0;
Packet.writeLongInt(l - HEADER_LENGTH);
Packet.writeByte(_packetSequence);
_mysqlOutput.write(Packet._buf, 0, l);
_mysqlOutput.flush();
int total_header_length = HEADER_LENGTH;
}
/**
* Clear waiting data in the InputStream
*/
private final void clearReceive() throws IOException {
int len = _mysqlInput.available();
if (len > 0) {
// _Mysql_Input.skipBytes(len);
}
}
/**
* Clear all data in the InputStream that is being
* sent by the MySQL server.
*/
private final void clearAllReceive() throws java.sql.SQLException {
try {
int len = _mysqlInput.available();
if (len > 0) {
Buffer Packet = readPacket();
if (Packet._buf[0] == (byte) 0xff) {
clearReceive();
return;
}
while (!Packet.isLastDataPacket()) {
// larger than the socket buffer.
Packet = readPacket();
if (Packet._buf[0] == (byte) 0xff)
break;
}
}
clearReceive();
}
catch (IOException E) {
throw new SQLException(
"Communication link failure: " + E.getClass().getName(),
"08S01");
}
}
protected abstract ResultSet buildResultSetWithRows(
Field[] Fields,
Vector Rows,
Connection Conn);
protected abstract ResultSet buildResultSetWithUpdates(
long updateCount,
long updateID,
Connection Conn);
static int getMaxBuf() {
return MAXBUF;
}
private final static int ub(byte b) {
return b < 0 ? (int) (256 + b) : b;
}
/**
* Retrieves matched rows count from EXTRA_INFO in MySQL protocol
* (for servers 3.22.5 or newer)
*
* Most JDBC clients expect this value, rather than the actual number
* of rows updated.
*
* This code assumes that this value is the first number in the
* EXTRA_INFO string.
*/
private final static long getMatchedRows(String Info) {
int info_length = Info.length();
StringBuffer MatchedRowCount = new StringBuffer();
boolean seen_first_digit = false;
for (int i = 0; i < info_length; i++) {
char c = Info.charAt(i);
if (Character.isDigit(c)) {
if (!seen_first_digit) {
seen_first_digit = true;
}
else {
break;
}
MatchedRowCount.append(c);
}
}
if (MatchedRowCount.length() > 0) {
try {
return Long.parseLong(MatchedRowCount.toString());
}
catch (NumberFormatException NFE) { /* Do Nothing */
}
}
return -1;
}
/**
* Does the version of the MySQL server we are connected to
* meet the given minimums?
*/
boolean versionMeetsMinimum(int major, int minor, int subminor) {
if (getServerMajorVersion() >= major) {
if (getServerMajorVersion() == major) {
if (getServerMinorVersion() >= minor) {
if (getServerMinorVersion() == minor) {
if (getServerSubMinorVersion() >= subminor) {
return true;
}
else {
return false;
}
}
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 void 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;
}
}
/**
* Sets the _profileSql.
* @param _profileSql The _profileSql to set
*/
public void setProfileSql(boolean flag)
{
this._profileSql = flag;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -