📄 tdscore.java
字号:
* Retrieve the status of the response stream. * * @return <code>boolean</code> true if the response has been entirely consumed */ boolean isEndOfResponse() { return endOfResponse; } /** * Empty the server response queue. * * @throws SQLException if an error occurs */ void clearResponseQueue() throws SQLException { checkOpen(); while (!endOfResponse) { nextToken(); } } /** * Consume packets from the server response queue up to (and including) the * first response terminator. * * @throws SQLException if an I/O or protocol error occurs; server errors * are queued up and not thrown */ void consumeOneResponse() throws SQLException { checkOpen(); while (!endOfResponse) { nextToken(); // If it's a response terminator, return if (currentToken.isEndToken() && (currentToken.status & DONE_END_OF_RESPONSE) != 0) { return; } } } /** * Retrieve the next data row from the result set. * * @return <code>false</code> if at the end of results, <code>true</code> * otherwise * @throws SQLException if an I/O or protocol error occurs; server errors * are queued up and not thrown */ boolean getNextRow() throws SQLException { if (endOfResponse || endOfResults) { return false; } checkOpen(); nextToken(); // Will either be first or next data row or end. while (!currentToken.isRowData() && !currentToken.isEndToken()) { nextToken(); // Could be messages } return currentToken.isRowData(); } /** * Retrieve the status of result set. * <p> * This does a quick read ahead and is needed to support the isLast() * method in the ResultSet. * * @return <code>boolean</code> - <code>true</code> if there is more data * in the result set. */ boolean isDataInResultSet() throws SQLException { byte x; checkOpen(); try { x = (endOfResponse) ? TDS_DONE_TOKEN : (byte) in.peek(); while (x != TDS_ROW_TOKEN && x != TDS_DONE_TOKEN && x != TDS_DONEINPROC_TOKEN && x != TDS_DONEPROC_TOKEN) { nextToken(); x = (byte) in.peek(); } messages.checkErrors(); } catch (IOException e) { connection.setClosed(); throw Support.linkException( new SQLException( Messages.get( "error.generic.ioerror", e.getMessage()), "08S01"), e); } return x == TDS_ROW_TOKEN; } /** * Retrieve the return status for the current stored procedure. * * @return The return status as an <code>Integer</code>. */ Integer getReturnStatus() { return this.returnStatus; } /** * Inform the server that this connection is closing. * <p> * Used by Sybase a no-op for Microsoft. */ synchronized void closeConnection() { try { if (tdsVersion == Driver.TDS50) { socket.setTimeout(1000); out.setPacketType(SYBQUERY_PKT); out.write((byte)TDS_CLOSE_TOKEN); out.write((byte)0); out.flush(); endOfResponse = false; clearResponseQueue(); } } catch (Exception e) { // Ignore any exceptions as this connection // is closing anyway. } } /** * Close the <code>TdsCore</code> connection object and associated streams. */ void close() throws SQLException { if (!isClosed) { try { clearResponseQueue(); out.close(); in.close(); } finally { isClosed = true; } } } /** * Send (only) one cancel packet to the server. */ void cancel() { Semaphore mutex = null; try { mutex = connection.getMutex(); synchronized (cancelMonitor) { if (!cancelPending && !endOfResponse) { cancelPending = socket.cancel(out.getStreamId()); } // If a cancel request was sent, reset the end of response flag if (cancelPending) { endOfResponse = false; } } } finally { if (mutex != null) { mutex.release(); } } } /** * Submit a simple SQL statement to the server and process all output. * * @param sql the statement to execute * @throws SQLException if an error is returned by the server */ void submitSQL(String sql) throws SQLException { checkOpen(); messages.clearWarnings(); if (sql.length() == 0) { throw new IllegalArgumentException("submitSQL() called with empty SQL String"); } executeSQL(sql, null, null, false, 0, -1, -1, true); clearResponseQueue(); messages.checkErrors(); } /** * Notifies the <code>TdsCore</code> that a batch is starting. This is so * that it knows to use <code>sp_executesql</code> for parameterized * queries (because there's no way to prepare a statement in the middle of * a batch). * <p> * Sets the {@link #inBatch} flag. */ void startBatch() { inBatch = true; } /** * Send an SQL statement with optional parameters to the server. * * @param sql SQL statement to execute * @param procName stored procedure to execute or <code>null</code> * @param parameters parameters for call or null * @param noMetaData suppress meta data for cursor calls * @param timeOut optional query timeout or 0 * @param maxRows the maximum number of data rows to return (-1 to * leave unaltered) * @param maxFieldSize the maximum number of bytes in a column to return * (-1 to leave unaltered) * @param sendNow whether to send the request now or not * @throws SQLException if an error occurs */ synchronized void executeSQL(String sql, String procName, ParamInfo[] parameters, boolean noMetaData, int timeOut, int maxRows, int maxFieldSize, boolean sendNow) throws SQLException { boolean sendFailed = true; // Used to ensure mutex is released. try { // // Obtain a lock on the connection giving exclusive access // to the network connection for this thread // if (connectionLock == null) { connectionLock = connection.getMutex(); } checkOpen(); clearResponseQueue(); messages.exceptions = null; // // Set the connection row count and text size if required. // Once set these will not be changed within a // batch so execution of the set rows query will // only occur once a the start of a batch. // No other thread can send until this one has finished. // setRowCountAndTextSize(maxRows, maxFieldSize); messages.clearWarnings(); this.returnStatus = null; // // Normalize the parameters argument to simplify later checks // if (parameters != null && parameters.length == 0) { parameters = null; } this.parameters = parameters; // // Normalise the procName argument as well // if (procName != null && procName.length() == 0) { procName = null; } if (parameters != null && parameters[0].isRetVal) { returnParam = parameters[0]; nextParam = 0; } else { returnParam = null; nextParam = -1; } if (parameters != null) { if (procName == null && sql.startsWith("EXECUTE ")) { // // If this is a callable statement that could not be fully parsed // into an RPC call convert to straight SQL now. // An example of non RPC capable SQL is {?=call sp_example('literal', ?)} // for (int i = 0; i < parameters.length; i++){ // Output parameters not allowed. if (!parameters[i].isRetVal && parameters[i].isOutput){ throw new SQLException(Messages.get("error.prepare.nooutparam", Integer.toString(i + 1)), "07000"); } } sql = Support.substituteParameters(sql, parameters, getTdsVersion()); parameters = null; } else { // // Check all parameters are either output or have values set // for (int i = 0; i < parameters.length; i++){ if (!parameters[i].isSet && !parameters[i].isOutput){ throw new SQLException(Messages.get("error.prepare.paramnotset", Integer.toString(i + 1)), "07000"); } parameters[i].clearOutValue(); // FIXME Should only set TDS type if not already set // but we might need to take a lot of care not to // exceed size limitations (e.g. write 11 chars in a // VARCHAR(10) ) TdsData.getNativeType(connection, parameters[i]); } } } try { switch (tdsVersion) { case Driver.TDS42: executeSQL42(sql, procName, parameters, noMetaData, sendNow); break; case Driver.TDS50: executeSQL50(sql, procName, parameters); break; case Driver.TDS70: case Driver.TDS80: case Driver.TDS81: executeSQL70(sql, procName, parameters, noMetaData, sendNow); break; default: throw new IllegalStateException("Unknown TDS version " + tdsVersion); } if (sendNow) { out.flush(); connectionLock.release(); connectionLock = null; sendFailed = false; endOfResponse = false; endOfResults = true; wait(timeOut); } else { sendFailed = false; } } catch (IOException ioe) { connection.setClosed(); throw Support.linkException( new SQLException( Messages.get( "error.generic.ioerror", ioe.getMessage()), "08S01"), ioe); } } finally { if ((sendNow || sendFailed) && connectionLock != null) { connectionLock.release(); connectionLock = null; } // Clear the in batch flag if (sendNow) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -