📄 connectionjdbc2.java
字号:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase// Copyright (C) 2004 The jTDS Project//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library 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// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//package net.sourceforge.jtds.jdbc;import java.lang.ref.WeakReference;import java.sql.CallableStatement;import java.sql.DatabaseMetaData;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.SQLWarning;import java.sql.Savepoint;import java.sql.Statement;import java.sql.Types;import java.sql.ResultSet;import java.net.UnknownHostException;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Properties;import net.sourceforge.jtds.jdbc.cache.*;import net.sourceforge.jtds.util.*;/** * jTDS implementation of the java.sql.Connection interface. * <p> * Implementation notes: * <ol> * <li>Environment setting code carried over from old jTDS otherwise * generally a new implementation of Connection. * <li>Connection properties and SQLException text messages are loaded from * a properties file. * <li>Character set choices are also loaded from a resource file and the original * Encoder class has gone. * <li>Prepared SQL statements are converted to procedures in the prepareSQL method. * <li>Use of Stored procedures is optional and controlled via connection property. * <li>This Connection object maintains a table of weak references to associated * statements. This allows the connection object to control the statements (for * example to close them) but without preventing them being garbage collected in * a pooled environment. * </ol> * * @author Mike Hutchinson * @author Alin Sinpalean * @version $Id: ConnectionJDBC2.java,v 1.90 2005/06/16 09:32:27 alin_sinpalean Exp $ */public class ConnectionJDBC2 implements java.sql.Connection { /** * SQL query to determine the server charset on Sybase. */ private static final String SYBASE_SERVER_CHARSET_QUERY = "select name from master.dbo.syscharsets where id =" + " (select value from master.dbo.sysconfigures where config=131)"; /** * SQL query to determine the server charset on MS SQL Server 6.5. */ private static final String SQL_SERVER_65_CHARSET_QUERY = "select name from master.dbo.syscharsets where id =" + " (select csid from master.dbo.syscharsets, master.dbo.sysconfigures" + " where config=1123 and id = value)"; /** Sybase initial connection string. */ private String SYBASE_INITIAL_SQL = "SET TRANSACTION ISOLATION LEVEL 1\r\n" + "SET CHAINED OFF\r\n" + "SET QUOTED_IDENTIFIER ON\r\n"+ "SET TEXTSIZE 2147483647"; /** * SQL Server initial connection string. Also contains a <code>SELECT * @@MAX_PRECISION</code> query to retrieve the maximum precision for * DECIMAL/NUMERIC data. */ private String SQL_SERVER_INITIAL_SQL = "SELECT @@MAX_PRECISION\r\n" + "SET TRANSACTION ISOLATION LEVEL READ COMMITTED\r\n" + "SET IMPLICIT_TRANSACTIONS OFF\r\n" + "SET QUOTED_IDENTIFIER ON\r\n"+ "SET TEXTSIZE 2147483647"; /* * Conection attributes */ /** The orginal connection URL. */ private final String url; /** The server host name. */ private String serverName; /** The server port number. */ private int portNumber; /** The make of SQL Server (sybase/microsoft). */ private int serverType; /** The SQL Server instance. */ private String instanceName; /** The requested database name. */ private String databaseName; /** The current database name. */ private String currentDatabase; /** The Windows Domain name. */ private String domainName; /** The database user ID. */ private String user; /** The user password. */ private String password; /** The server character set. */ private String serverCharset; /** The application name. */ private String appName; /** The program name. */ private String progName; /** Workstation ID. */ private String wsid; /** The server message language. */ private String language; /** The client MAC Address. */ private String macAddress; /** The server protocol version. */ private int tdsVersion; /** The network TCP/IP socket. */ private final SharedSocket socket; /** The cored TDS protocol object. */ private final TdsCore baseTds; /** The initial network packet size. */ private int netPacketSize = TdsCore.MIN_PKT_SIZE; /** User requested packet size. */ private int packetSize; /** SQL Server 2000 collation. */ private byte collation[]; /** True if user specifies an explicit charset. */ private boolean charsetSpecified; /** The database product name eg SQL SERVER. */ private String databaseProductName; /** The product version eg 11.92. */ private String databaseProductVersion; /** The major version number eg 11. */ private int databaseMajorVersion; /** The minor version number eg 92. */ private int databaseMinorVersion; /** True if this connection is closed. */ private boolean closed; /** True if this connection is read only. */ private boolean readOnly; /** List of statements associated with this connection. */ private final ArrayList statements = new ArrayList(); /** Default transaction isolation level. */ private int transactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED; /** Default auto commit state. */ private boolean autoCommit = true; /** Diagnostc messages for this connection. */ private final SQLDiagnostic messages; /** Connection's current rowcount limit. */ private int rowCount; /** Connection's current maximum field size limit. */ private int textSize; /** Maximum decimal precision. */ private int maxPrecision = 38; // Sybase default /** Stored procedure unique ID number. */ private int spSequenceNo = 1; /** Cursor unique ID number. */ private int cursorSequenceNo = 1; /** Procedures in this transaction. */ private final ArrayList procInTran = new ArrayList(); /** Java charset for encoding. */ private CharsetInfo charsetInfo; /** Method for preparing SQL used in Prepared Statements. */ private int prepareSql; /** The amount of LOB data to buffer in memory. */ private long lobBuffer; /** The maximum number of statements to keep open. */ private int maxStatements; /** Statement cache.*/ private StatementCache statementCache; /** Send parameters as unicode. */ private boolean useUnicode = true; /** Use named pipe IPC instead of TCP/IP sockets. */ private boolean namedPipe; /** Only return the last update count. */ private boolean lastUpdateCount; /** TCP_NODELAY */ private boolean tcpNoDelay = true; /** Login timeout value in seconds or 0. */ private int loginTimeout; /** Sybase capability mask.*/ private int sybaseInfo; /** True if running distributed transaction. */ private boolean xaTransaction; /** Current emulated XA State eg start/end/prepare etc. */ private int xaState; /** Current XA Transaction ID. */ private Object xid; /** True if driver should emulate distributed transactions. */ private boolean xaEmulation = true; /** Mutual exclusion lock to control access to connection. */ private final Semaphore mutex = new Semaphore(1); /** SSL setting. */ private String ssl; /** The maximum size of a batch. */ private int batchSize; /** Use metadata cache for prepared statements. */ private boolean useMetadataCache; /** Use fast forward cursors for forward only result sets. */ private boolean useCursors; /** The global buffer memory limit for all connections (in kilobytes). */ private int bufferMaxMemory; /** The minimum number of packets per statement to buffer to memory. */ private int bufferMinPackets; /** Map large types (IMAGE and TEXT/NTEXT) to LOBs by default. */ private boolean useLOBs; /** A cached <code>TdsCore</code> instance to reuse on new statements. */ private TdsCore cachedTds; /** * Default constructor. * <p/> * Used for testing. */ private ConnectionJDBC2() { url = null; socket = null; baseTds = null; messages = null; } /** * Create a new database connection. * * @param url The connection URL starting jdbc:jtds:. * @param info The additional connection properties. * @throws SQLException */ ConnectionJDBC2(String url, Properties info) throws SQLException { this.url = url; // // Extract properties into instance variables // unpackProperties(info); this.messages = new SQLDiagnostic(serverType); // // Get the instance port, if it is specified. // Named pipes use instance names differently. // if (instanceName.length() > 0 && !namedPipe) { final MSSqlServerInfo msInfo = new MSSqlServerInfo(serverName); portNumber = msInfo.getPortForInstance(instanceName); if (portNumber == -1) { throw new SQLException( Messages.get("error.msinfo.badinst", serverName, instanceName), "08003"); } } SharedSocket.setMemoryBudget(bufferMaxMemory * 1024); SharedSocket.setMinMemPkts(bufferMinPackets); try { Object timer = null; if (loginTimeout > 0) { // Start a login timer timer = TimerThread.getInstance().setTimer(loginTimeout * 1000, new TimerThread.TimerListener() { public void timerExpired() { if (socket != null) { socket.forceClose(); } } }); } if (namedPipe) { // TODO Use namedPipe parameter to select implementation type if(System.getProperty("os.name").toLowerCase().startsWith("windows")) { // If the OS is Windows, use a local named pipe socket = new SharedLocalNamedPipe(serverName, tdsVersion, serverType, instanceName); } else { // Otherwise use a named pipe over TCP/IP socket = SharedNamedPipe.instance(serverName, tdsVersion, serverType, packetSize, instanceName, domainName, user, password); } } else { // Use plain TCP/IP socket socket = new SharedSocket(serverName, portNumber, tdsVersion, serverType, tcpNoDelay, loginTimeout); } if (timer != null && TimerThread.getInstance().hasExpired(timer)) { // If the timer has expired during the connection phase, close // the socket and throw an exception socket.forceClose(); throw new IOException("Login timed out"); } if ( charsetSpecified ) { loadCharset(serverCharset); } else { // Need a default charset to process login packets for TDS 4.2/5.0 // Will discover the actual serverCharset later loadCharset("iso_1"); serverCharset = ""; // But don't send charset name to server! } // // Create TDS protocol object // baseTds = new TdsCore(this, messages); // // Negotiate SSL connection if required // if (tdsVersion >= Driver.TDS80 && !namedPipe) { baseTds.negotiateSSL(instanceName, ssl); } // // Now try and login // baseTds.login(serverName, databaseName, user, password, domainName, serverCharset, appName, progName, wsid, language, macAddress, packetSize); if (timer != null) { // Cancel loginTimer TimerThread.getInstance().cancelTimer(timer); } // Update the tdsVersion with the value in baseTds. baseTds sets // the TDS version for the socket and there are no other objects // with cached TDS versions at this point. tdsVersion = baseTds.getTdsVersion(); if (tdsVersion < Driver.TDS70 && databaseName.length() > 0) { // Need to select the default database setCatalog(databaseName); } } catch (UnknownHostException e) { throw Support.linkException( new SQLException(Messages.get("error.connection.badhost", e.getMessage()), "08S03"), e); } catch (IOException e) { if (loginTimeout > 0 && e.getMessage().indexOf("timed out") >= 0) { throw new SQLException( Messages.get("error.connection.timeout"), "HYT01"); } throw Support.linkException( new SQLException(Messages.get("error.connection.ioerror", e.getMessage()), "08S01"), e); } catch (SQLException e) { if (loginTimeout > 0 && e.getMessage().indexOf("socket closed") >= 0) { throw new SQLException( Messages.get("error.connection.timeout"), "HYT01"); } throw e;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -