📄 connectionjdbc2.java
字号:
*/ boolean isCharsetSpecified() { return charsetSpecified; } /** * Called by the protcol to change the current database context. * * @param newDb The new database selected on the server. * @param oldDb The old database as known by the server. * @throws SQLException */ protected void setDatabase(final String newDb, final String oldDb) throws SQLException { if (currentDatabase != null && !oldDb.equalsIgnoreCase(currentDatabase)) { throw new SQLException(Messages.get("error.connection.dbmismatch", oldDb, databaseName), "HY096"); } currentDatabase = newDb; if (Logger.isActive()) { Logger.println("Changed database from " + oldDb + " to " + newDb); } } /** * Update the connection instance with information about the server. * * @param databaseProductName The server name eg SQL Server. * @param databaseMajorVersion The major version eg 11 * @param databaseMinorVersion The minor version eg 92 * @param buildNumber The server build number. */ protected void setDBServerInfo(String databaseProductName, int databaseMajorVersion, int databaseMinorVersion, int buildNumber) { this.databaseProductName = databaseProductName; this.databaseMajorVersion = databaseMajorVersion; this.databaseMinorVersion = databaseMinorVersion; if (tdsVersion >= Driver.TDS70) { StringBuffer buf = new StringBuffer(10); if (databaseMajorVersion < 10) { buf.append('0'); } buf.append(databaseMajorVersion).append('.'); if (databaseMinorVersion < 10) { buf.append('0'); } buf.append(databaseMinorVersion).append('.'); buf.append(buildNumber); while (buf.length() < 10) { buf.insert(6, '0'); } this.databaseProductVersion = buf.toString(); } else { databaseProductVersion = databaseMajorVersion + "." + databaseMinorVersion; } } /** * Removes a statement object from the list maintained by the connection * and cleans up the statement cache if necessary. * <p> * Synchronized because it accesses the statement list, the statement cache * and the <code>baseTds</code>. * * @param statement the statement to remove */ synchronized void removeStatement(JtdsStatement statement) throws SQLException { // Remove the JtdsStatement from the statement list for (int i = 0; i < statements.size(); i++) { WeakReference wr = (WeakReference) statements.get(i); if (wr != null) { Statement stmt = (Statement) wr.get(); if (stmt != null && stmt == statement) { statements.set(i, null); } } } if (statement instanceof JtdsPreparedStatement) { // Release the prepared statement handles or procedures Collection handles = ((JtdsPreparedStatement) statement).handles; if (handles != null) { for (Iterator iterator = handles.iterator(); iterator.hasNext(); ) { ProcEntry handle = (ProcEntry)iterator.next(); handle.release(); } } // Clean up the prepared statement cache handles = statementCache.getObsoleteHandles(handles); if (handles != null) { if (serverType == Driver.SQLSERVER) { // SQL Server unprepare StringBuffer cleanupSql = new StringBuffer(handles.size() * 32); for (Iterator iterator = handles.iterator(); iterator.hasNext(); ) { ProcEntry pe = (ProcEntry) iterator.next(); // Could get put back if in a transaction that is // rolled back pe.appendDropSQL(cleanupSql); } if (cleanupSql.length() > 0) { baseTds.executeSQL(cleanupSql.toString(), null, null, true, 0, -1, -1, true); baseTds.clearResponseQueue(); } } else { // Sybase unprepare for (Iterator iterator = handles.iterator(); iterator.hasNext(); ) { ProcEntry pe = (ProcEntry)iterator.next(); if (pe.toString() != null) { // Remove the Sybase light weight proc baseTds.sybaseUnPrepare(pe.toString()); } } } } } } /** * Adds a statement object to the list maintained by the connection. * <p/> * WeakReferences are used so that statements can still be closed and * garbage collected even if not explicitly closed by the connection. * * @param statement statement to add */ void addStatement(JtdsStatement statement) { synchronized (statements) { for (int i = 0; i < statements.size(); i++) { WeakReference wr = (WeakReference) statements.get(i); if (wr == null) { statements.set(i, new WeakReference(statement)); return; } } statements.add(new WeakReference(statement)); } } /** * Checks that the connection is still open. * * @throws SQLException if the connection is closed */ void checkOpen() throws SQLException { if (closed) { throw new SQLException( Messages.get("error.generic.closed", "Connection"), "HY010"); } } /** * Checks that this connection is in local transaction mode. * * @param method the method name being tested * @throws SQLException if in XA distributed transaction mode */ void checkLocal(String method) throws SQLException { if (xaTransaction) { throw new SQLException( Messages.get("error.connection.badxaop", method), "HY010"); } } /** * Reports that user tried to call a method which has not been implemented. * * @param method the method name to report in the error message * @throws SQLException always, with the not implemented message */ static void notImplemented(String method) throws SQLException { throw new SQLException( Messages.get("error.generic.notimp", method), "HYC00"); } /** * Retrieves the DBMS major version. * * @return the version as an <code>int</code> */ public int getDatabaseMajorVersion() { return this.databaseMajorVersion; } /** * Retrieves the DBMS minor version. * * @return the version as an <code>int</code> */ public int getDatabaseMinorVersion() { return this.databaseMinorVersion; } /** * Retrieves the DBMS product name. * * @return the name as a <code>String</code> */ String getDatabaseProductName() { return this.databaseProductName; } /** * Retrieves the DBMS product version. * * @return the version as a <code>String</code> */ String getDatabaseProductVersion() { return this.databaseProductVersion; } /** * Retrieves the original connection URL. * * @return the connection url as a <code>String</code> */ String getURL() { return this.url; } /** * Retrieves the host and port for this connection. * <p> * Used to identify same resource manager in XA transactions. * * @return the hostname and port as a <code>String</code> */ public String getRmHost() { return serverName + ':' + portNumber; } /** * Forces the closed status on the statement if an I/O error has occurred. */ void setClosed() { closed = true; // Make sure we release the socket and all data buffered at the socket // level try { socket.close(); } catch (IOException e) { // Ignore; shouldn't happen anyway } } /** * Invokes the <code>xp_jtdsxa</code> extended stored procedure on the * server. * <p/> * Synchronized because it accesses the <code>baseTds</code>. * * @param args the arguments eg cmd, rmid, flags etc. * @param data option byte data eg open string xid etc. * @return optional byte data eg OLE cookie * @throws SQLException if an error condition occurs */ synchronized byte[][] sendXaPacket(int args[], byte[] data) throws SQLException { ParamInfo params[] = new ParamInfo[6]; params[0] = new ParamInfo(Types.INTEGER, null, ParamInfo.RETVAL); params[1] = new ParamInfo(Types.INTEGER, new Integer(args[1]), ParamInfo.INPUT); params[2] = new ParamInfo(Types.INTEGER, new Integer(args[2]), ParamInfo.INPUT); params[3] = new ParamInfo(Types.INTEGER, new Integer(args[3]), ParamInfo.INPUT); params[4] = new ParamInfo(Types.INTEGER, new Integer(args[4]), ParamInfo.INPUT); params[5] = new ParamInfo(Types.VARBINARY, data, ParamInfo.OUTPUT); // // Execute our extended stored procedure (let's hope it is installed!). // baseTds.executeSQL(null, "master..xp_jtdsxa", params, false, 0, -1, -1, true); // // Now process results // ArrayList xids = new ArrayList(); while (!baseTds.isEndOfResponse()) { if (baseTds.getMoreResults()) { // This had better be the results from a xa_recover command while (baseTds.getNextRow()) { Object row[] = baseTds.getRowData(); if (row.length == 1 && row[0] instanceof byte[]) { xids.add(row[0]); } } } } messages.checkErrors(); if (params[0].getOutValue() instanceof Integer) { // Should be return code from XA command args[0] = ((Integer)params[0].getOutValue()).intValue(); } else { args[0] = -7; // XAException.XAER_RMFAIL } if (xids.size() > 0) { // List of XIDs from xa_recover byte list[][] = new byte[xids.size()][]; for (int i = 0; i < xids.size(); i++) { list[i] = (byte[])xids.get(i); } return list; } else if (params[5].getOutValue() instanceof byte[]) { // xa_open the xa connection ID // xa_start OLE Transaction cookie byte cookie[][] = new byte[1][]; cookie[0] = (byte[])params[5].getOutValue(); return cookie; } else { // All other cases return null; } } /** * Enlists the current connection in a distributed transaction. * * @param oleTranID the OLE transaction cookie or null to delist * @throws SQLException if an error condition occurs */ synchronized void enlistConnection(byte[] oleTranID) throws SQLException { if (oleTranID != null) { // TODO: Stored procs are no good but maybe prepare will be OK. this.prepareSql = TdsCore.EXECUTE_SQL; baseTds.enlistConnection(1, oleTranID); xaTransaction = true; } else { baseTds.enlistConnection(1, null); xaTransaction = false; } } /** * Sets the XA transaction ID when running in emulation mode. * * @param xid the XA Transaction ID */ void setXid(Object xid) { this.xid = xid; xaTransaction = xid != null; } /** * Gets the XA transaction ID when running in emulation mode. * * @return the transaction ID as an <code>Object</code> */ Object getXid() { return xid; } /** * Sets the XA state variable. * * @param value the XA state value */ void setXaState(int value) { this.xaState = value; } /** * Retrieves the XA state variable.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -