com.microsoft.sqlserver.jdbc.SQLServerDataSource Maven / Gradle / Ivy
Show all versions of mssql-jdbc Show documentation
/*
* Microsoft JDBC Driver for SQL Server
*
* Copyright(c) Microsoft Corporation All rights reserved.
*
* This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/
package com.microsoft.sqlserver.jdbc;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.sql.DataSource;
import org.ietf.jgss.GSSCredential;
/**
* This datasource lists properties specific for the SQLServerConnection class.
*/
public class SQLServerDataSource implements ISQLServerDataSource, DataSource, java.io.Serializable, javax.naming.Referenceable {
// dsLogger is logger used for all SQLServerDataSource instances.
static final java.util.logging.Logger dsLogger = java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.SQLServerDataSource");
static final java.util.logging.Logger loggerExternal = java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc.DataSource");
static final private java.util.logging.Logger parentLogger = java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc");
final private String loggingClassName;
private boolean trustStorePasswordStripped = false;
private static final long serialVersionUID = 654861379544314296L;
private Properties connectionProps; // Properties passed to SQLServerConnection class.
private String dataSourceURL; // URL for datasource.
private String dataSourceDescription; // Description for datasource.
static private final AtomicInteger baseDataSourceID = new AtomicInteger(0); // Unique id generator for each DataSource instance (used for
// logging).
final private String traceID;
/**
* Initializes a new instance of the SQLServerDataSource class.
*/
public SQLServerDataSource() {
connectionProps = new Properties();
int dataSourceID = nextDataSourceID();
String nameL = getClass().getName();
traceID = nameL.substring(1 + nameL.lastIndexOf('.')) + ":" + dataSourceID;
loggingClassName = "com.microsoft.sqlserver.jdbc." + nameL.substring(1 + nameL.lastIndexOf('.')) + ":" + dataSourceID;
}
String getClassNameLogging() {
return loggingClassName;
}
public String toString() {
return traceID;
}
// DataSource interface public methods
public Connection getConnection() throws SQLServerException {
loggerExternal.entering(getClassNameLogging(), "getConnection");
Connection con = getConnectionInternal(null, null, null);
loggerExternal.exiting(getClassNameLogging(), "getConnection", con);
return con;
}
public Connection getConnection(String username,
String password) throws SQLServerException {
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.entering(getClassNameLogging(), "getConnection", new Object[] {username, "Password not traced"});
Connection con = getConnectionInternal(username, password, null);
loggerExternal.exiting(getClassNameLogging(), "getConnection", con);
return con;
}
// Sets the maximum time in seconds that this data source will wait while
// attempting to connect to a database. Note default value is 0.
public void setLoginTimeout(int loginTimeout) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(), loginTimeout);
}
public int getLoginTimeout() {
int defaultTimeOut = SQLServerDriverIntProperty.LOGIN_TIMEOUT.getDefaultValue();
final int logintimeout = getIntProperty(connectionProps, SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(), defaultTimeOut);
// even if the user explicitly sets the timeout to zero, convert to 15
return (logintimeout == 0) ? defaultTimeOut : logintimeout;
}
// Sets the log writer for this DataSource.
// Currently we just hold onto this logWriter and pass it back to callers, nothing else.
private transient PrintWriter logWriter;
public void setLogWriter(PrintWriter out) {
loggerExternal.entering(getClassNameLogging(), "setLogWriter", out);
logWriter = out;
loggerExternal.exiting(getClassNameLogging(), "setLogWriter");
}
// Retrieves the log writer for this DataSource.
public PrintWriter getLogWriter() {
loggerExternal.entering(getClassNameLogging(), "getLogWriter");
loggerExternal.exiting(getClassNameLogging(), "getLogWriter", logWriter);
return logWriter;
}
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return parentLogger;
}
// Core Connection property setters/getters.
// applicationName is used to identify the specific application in various SQL Server
// profiling and logging tools.
public void setApplicationName(String applicationName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_NAME.toString(), applicationName);
}
public String getApplicationName() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_NAME.toString(),
SQLServerDriverStringProperty.APPLICATION_NAME.getDefaultValue());
}
// databaseName is the name of the database to connect to. If databaseName is not set,
// getDatabaseName returns the default value of null.
public void setDatabaseName(String databaseName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.DATABASE_NAME.toString(), databaseName);
}
public String getDatabaseName() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.DATABASE_NAME.toString(), null);
}
// instanceName is the SQL Server instance name to connect to.
// If instanceName is not set, getInstanceName returns the default value of null.
public void setInstanceName(String instanceName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.INSTANCE_NAME.toString(), instanceName);
}
public String getInstanceName() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.INSTANCE_NAME.toString(), null);
}
public void setIntegratedSecurity(boolean enable) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.toString(), enable);
}
public void setAuthenticationScheme(String authenticationScheme) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION_SCHEME.toString(), authenticationScheme);
}
/**
* sets the authentication mode
*
* @param authentication
* the authentication mode
*/
public void setAuthentication(String authentication) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION.toString(), authentication);
}
/**
* Retrieves the authentication mode
*
* @return the authentication value
*/
public String getAuthentication() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.AUTHENTICATION.toString(),
SQLServerDriverStringProperty.AUTHENTICATION.getDefaultValue());
}
/**
* sets GSSCredential
*
* @param userCredential the credential
*/
public void setGSSCredentials(GSSCredential userCredential){
setObjectProperty(connectionProps,SQLServerDriverObjectProperty.GSS_CREDENTIAL.toString(), userCredential);
}
/**
* Retrieves the GSSCredential
*
* @return GSSCredential
*/
public GSSCredential getGSSCredentials(){
return (GSSCredential) getObjectProperty(connectionProps, SQLServerDriverObjectProperty.GSS_CREDENTIAL.toString(),
SQLServerDriverObjectProperty.GSS_CREDENTIAL.getDefaultValue());
}
/**
* Sets the access token.
*
* @param accessToken
* to be set in the string property.
*/
public void setAccessToken(String accessToken) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.ACCESS_TOKEN.toString(), accessToken);
}
/**
* Retrieves the access token.
*
* @return the access token.
*/
public String getAccessToken() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.ACCESS_TOKEN.toString(), null);
}
// If lastUpdateCount is set to true, the driver will return only the last update
// count from all the update counts returned by a batch. The default of false will
// return all update counts. If lastUpdateCount is not set, getLastUpdateCount
// returns the default value of false.
/**
* Enables/disables Always Encrypted functionality for the data source object. The default is Disabled.
*
* @param columnEncryptionSetting
* Enables/disables Always Encrypted functionality for the data source object. The default is Disabled.
*/
public void setColumnEncryptionSetting(String columnEncryptionSetting) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.COLUMN_ENCRYPTION.toString(), columnEncryptionSetting);
}
/**
* Retrieves the Always Encrypted functionality setting for the data source object.
*
* @return the Always Encrypted functionality setting for the data source object.
*/
public String getColumnEncryptionSetting() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.COLUMN_ENCRYPTION.toString(),
SQLServerDriverStringProperty.COLUMN_ENCRYPTION.getDefaultValue());
}
/**
* Sets the name that identifies a key store. Only value supported is the "JavaKeyStorePassword" for identifying the Java Key Store. The default
* is null.
*
* @param keyStoreAuthentication
* the name that identifies a key store.
*/
public void setKeyStoreAuthentication(String keyStoreAuthentication) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(), keyStoreAuthentication);
}
/**
* Gets the value of the keyStoreAuthentication setting for the data source object.
*
* @return the value of the keyStoreAuthentication setting for the data source object.
*/
public String getKeyStoreAuthentication() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(),
SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.getDefaultValue());
}
/**
* Sets the password for the Java keystore. Note that, for Java Key Store provider the password for the keystore and the key must be the same.
* Note that, keyStoreAuthentication must be set with "JavaKeyStorePassword".
*
* @param keyStoreSecret
* the password to use for the keystore as well as for the key
*/
public void setKeyStoreSecret(String keyStoreSecret) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_SECRET.toString(), keyStoreSecret);
}
/**
* Sets the location including the file name for the Java keystore. Note that, keyStoreAuthentication must be set with "JavaKeyStorePassword".
*
* @param keyStoreLocation
* the location including the file name for the Java keystore.
*/
public void setKeyStoreLocation(String keyStoreLocation) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_LOCATION.toString(), keyStoreLocation);
}
/**
* Retrieves the keyStoreLocation for the Java Key Store.
*
* @return the keyStoreLocation for the Java Key Store.
*/
public String getKeyStoreLocation() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_STORE_LOCATION.toString(),
SQLServerDriverStringProperty.KEY_STORE_LOCATION.getDefaultValue());
}
public void setLastUpdateCount(boolean lastUpdateCount) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString(), lastUpdateCount);
}
public boolean getLastUpdateCount() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString(),
SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.getDefaultValue());
}
// Encryption
public void setEncrypt(boolean encrypt) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENCRYPT.toString(), encrypt);
}
public boolean getEncrypt() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENCRYPT.toString(),
SQLServerDriverBooleanProperty.ENCRYPT.getDefaultValue());
}
/**
* Beginning in version 6.0 of the Microsoft JDBC Driver for SQL Server, a new connection property transparentNetworkIPResolution (TNIR) is added
* for transparent connection to Always On availability groups or to a server which has multiple IP addresses associated. When
* transparentNetworkIPResolution is true, the driver attempts to connect to the first IP address available. If the first attempt fails, the
* driver tries to connect to all IP addresses in parallel until the timeout expires, discarding any pending connection attempts when one of them
* succeeds.
*
* transparentNetworkIPResolution is ignored if multiSubnetFailover is true
*
* transparentNetworkIPResolution is ignored if database mirroring is used
*
* transparentNetworkIPResolution is ignored if there are more than 64 IP addresses
*
* @param tnir
* if set to true, the driver attempts to connect to the first IP address available. It is true by default.
*/
public void setTransparentNetworkIPResolution(boolean tnir) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString(), tnir);
}
/**
* Retrieves the TransparentNetworkIPResolution value.
*
* @return if enabled, returns true. Otherwise, false.
*/
public boolean getTransparentNetworkIPResolution() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString(),
SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.getDefaultValue());
}
public void setTrustServerCertificate(boolean e) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(), e);
}
public boolean getTrustServerCertificate() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(),
SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.getDefaultValue());
}
public void setTrustStoreType(String trustStoreType) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE_TYPE.toString(), trustStoreType);
}
public String getTrustStoreType() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE_TYPE.toString(),
SQLServerDriverStringProperty.TRUST_STORE_TYPE.getDefaultValue());
}
public void setTrustStore(String st) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE.toString(), st);
}
public String getTrustStore() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE.toString(), null);
}
public void setTrustStorePassword(String p) {
// if a non value property is set
if (p != null)
trustStorePasswordStripped = false;
setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(), p);
}
public void setHostNameInCertificate(String host) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(), host);
}
public String getHostNameInCertificate() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(), null);
}
// lockTimeout is the number of milliseconds to wait before the database reports
// a lock timeout. The default value of -1 means wait forever. If specified,
// this value will be the default for all statements on the connection. Note a
// value of 0 means no wait. If lockTimeout is not set, getLockTimeout returns
// the default of -1.
public void setLockTimeout(int lockTimeout) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.LOCK_TIMEOUT.toString(), lockTimeout);
}
public int getLockTimeout() {
return getIntProperty(connectionProps, SQLServerDriverIntProperty.LOCK_TIMEOUT.toString(),
SQLServerDriverIntProperty.LOCK_TIMEOUT.getDefaultValue());
}
// setPassword sets the password that will be used when connecting to SQL Server.
// Note getPassword is deliberately declared non-public for security reasons.
// If the password is not set, getPassword returns the default value of null.
public void setPassword(String password) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.PASSWORD.toString(), password);
}
String getPassword() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.PASSWORD.toString(), null);
}
// portNumber is the TCP-IP port number used when opening a socket connection
// to SQL Server. If portNumber is not set, getPortNumber returns the default
// of 1433. Note as mentioned above, setPortNumber does not do any range
// checking on the port value passed in, invalid port numbers like 99999 can
// be passed in without triggering any error.
public void setPortNumber(int portNumber) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.PORT_NUMBER.toString(), portNumber);
}
public int getPortNumber() {
return getIntProperty(connectionProps, SQLServerDriverIntProperty.PORT_NUMBER.toString(),
SQLServerDriverIntProperty.PORT_NUMBER.getDefaultValue());
}
// selectMethod is the default cursor type used for the result set. This
// property is useful when you are dealing with large result sets and don't
// want to store the whole result set in memory on the client side. By setting
// the property to "cursor" you will be able to create a server side cursor that
// can fetch smaller chunks of data at a time. If selectMethod is not set,
// getSelectMethod returns the default value of "direct".
public void setSelectMethod(String selectMethod) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.SELECT_METHOD.toString(), selectMethod);
}
public String getSelectMethod() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.SELECT_METHOD.toString(),
SQLServerDriverStringProperty.SELECT_METHOD.getDefaultValue());
}
public void setResponseBuffering(String respo) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString(), respo);
}
public String getResponseBuffering() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString(),
SQLServerDriverStringProperty.RESPONSE_BUFFERING.getDefaultValue());
}
public void setApplicationIntent(String applicationIntent) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_INTENT.toString(), applicationIntent);
}
public String getApplicationIntent() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.APPLICATION_INTENT.toString(),
SQLServerDriverStringProperty.APPLICATION_INTENT.getDefaultValue());
}
public void setSendTimeAsDatetime(boolean sendTimeAsDatetime) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(), sendTimeAsDatetime);
}
public boolean getSendTimeAsDatetime() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(),
SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue());
}
// If sendStringParametersAsUnicode is set to true (which is the default),
// string parameters are sent to the server in UNICODE format. If sendStringParametersAsUnicode
// is set to false, string parameters are sent to the server in the native TDS collation
// format of the database, not in UNICODE. If sendStringParametersAsUnicode is not set,
// getSendStringParametersAsUnicode returns the default of true.
public void setSendStringParametersAsUnicode(boolean sendStringParametersAsUnicode) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.toString(),
sendStringParametersAsUnicode);
}
public boolean getSendStringParametersAsUnicode() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.toString(),
SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.getDefaultValue());
}
/**
* Translates the serverName from Unicode to ASCII Compatible Encoding (ACE)
*
* @param serverNameAsACE
* if enabled the servername will be translated to ASCII Compatible Encoding (ACE)
*/
public void setServerNameAsACE(boolean serverNameAsACE) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString(), serverNameAsACE);
}
/**
* Retrieves if the serverName should be translated from Unicode to ASCII Compatible Encoding (ACE)
*
* @return if enabled, will return true. Otherwise, false.
*/
public boolean getServerNameAsACE() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString(),
SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.getDefaultValue());
}
// serverName is the host name of the target SQL Server. If serverName is not set,
// getServerName returns the default value of null is returned.
public void setServerName(String serverName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_NAME.toString(), serverName);
}
public String getServerName() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_NAME.toString(), null);
}
// Specify an Service Principal Name (SPN) of the target SQL Server.
// https://msdn.microsoft.com/en-us/library/cc280459.aspx
public void setServerSpn(String serverSpn) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_SPN.toString(), serverSpn);
}
public String getServerSpn() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.SERVER_SPN.toString(), null);
}
// serverName is the host name of the target SQL Server. If serverName is not set,
// getServerName returns the default value of null is returned.
public void setFailoverPartner(String serverName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.FAILOVER_PARTNER.toString(), serverName);
}
public String getFailoverPartner() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.FAILOVER_PARTNER.toString(), null);
}
public void setMultiSubnetFailover(boolean multiSubnetFailover) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString(), multiSubnetFailover);
}
public boolean getMultiSubnetFailover() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString(),
SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.getDefaultValue());
}
// setUser set's the user name that will be used when connecting to SQL Server.
// If user is not set, getUser returns the default value of null.
public void setUser(String user) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.USER.toString(), user);
}
public String getUser() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.USER.toString(), null);
}
// workstationID is the name of the client machine (or client workstation).
// workstationID is the host name of the client in other words. If workstationID
// is not set, the default value is constructed by calling InetAddress.getLocalHost().getHostName()
// or if getHostName() returns blank then getHostAddress().toString().
public void setWorkstationID(String workstationID) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.WORKSTATION_ID.toString(), workstationID);
}
public String getWorkstationID() {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "getWorkstationID");
String getWSID = connectionProps.getProperty(SQLServerDriverStringProperty.WORKSTATION_ID.toString());
// Per spec, return what the logon will send here if workstationID property is not set.
if (null == getWSID) {
getWSID = Util.lookupHostName();
}
loggerExternal.exiting(getClassNameLogging(), "getWorkstationID", getWSID);
return getWSID;
}
// If xopenStates is set to true, the driver will convert SQL states to XOPEN
// compliant states. The default is false which causes the driver to generate SQL 99
// state codes. If xopenStates is not set, getXopenStates returns the default value
// of false.
public void setXopenStates(boolean xopenStates) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.XOPEN_STATES.toString(), xopenStates);
}
public boolean getXopenStates() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.XOPEN_STATES.toString(),
SQLServerDriverBooleanProperty.XOPEN_STATES.getDefaultValue());
}
public void setFIPS(boolean fips) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.FIPS.toString(), fips);
}
public boolean getFIPS() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.FIPS.toString(),
SQLServerDriverBooleanProperty.FIPS.getDefaultValue());
}
public void setSSLProtocol(String sslProtocol) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.SSL_PROTOCOL.toString(), sslProtocol);
}
public String getSSLProtocol() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.SSL_PROTOCOL.toString(),
SQLServerDriverStringProperty.SSL_PROTOCOL.getDefaultValue());
}
public void setTrustManagerClass(String trustManagerClass) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.toString(), trustManagerClass);
}
public String getTrustManagerClass() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.toString(),
SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.getDefaultValue());
}
public void setTrustManagerConstructorArg(String trustManagerClass) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.toString(), trustManagerClass);
}
public String getTrustManagerConstructorArg() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.toString(),
SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.getDefaultValue());
}
// The URL property is exposed for backwards compatibility reasons. Also, several
// Java Application servers expect a setURL function on the DataSource and set it
// by default (JBoss and WebLogic).
// Note for security reasons we do not recommend that customers include the password
// in the url supplied to setURL. The reason for this is third-party Java Application
// Servers will very often display the value set to URL property in their DataSource
// configuration GUI. We recommend instead that clients use the setPassword method
// to set the password value. The Java Application Servers will not display a password
// that is set on the DataSource in the configuration GUI.
// Note if setURL is not called, getURL returns the default value of "jdbc:sqlserver://".
public void setURL(String url) {
loggerExternal.entering(getClassNameLogging(), "setURL", url);
// URL is not stored in a property set, it is maintained separately.
dataSourceURL = url;
loggerExternal.exiting(getClassNameLogging(), "setURL");
}
public String getURL() {
String url = dataSourceURL;
loggerExternal.entering(getClassNameLogging(), "getURL");
if (null == dataSourceURL)
url = "jdbc:sqlserver://";
loggerExternal.exiting(getClassNameLogging(), "getURL", url);
return url;
}
// DataSource specific property setters/getters.
// Per JDBC specification 16.1.1 "...the only property that all DataSource
// implementations are required to support is the description property".
public void setDescription(String description) {
loggerExternal.entering(getClassNameLogging(), "setDescription", description);
dataSourceDescription = description;
loggerExternal.exiting(getClassNameLogging(), "setDescription");
}
public String getDescription() {
loggerExternal.entering(getClassNameLogging(), "getDescription");
loggerExternal.exiting(getClassNameLogging(), "getDescription", dataSourceDescription);
return dataSourceDescription;
}
// packetSize is the size (in bytes) to use for the TCP/IP send and receive
// buffer. It is also the value used for the TDS packet size (SQL Server
// Network Packet Size). Validity of the value is checked at connect time.
// If no value is set for this property, its default value is 4KB.
public void setPacketSize(int packetSize) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.PACKET_SIZE.toString(), packetSize);
}
public int getPacketSize() {
return getIntProperty(connectionProps, SQLServerDriverIntProperty.PACKET_SIZE.toString(),
SQLServerDriverIntProperty.PACKET_SIZE.getDefaultValue());
}
/**
* Setting the query timeout
*
* @param queryTimeout
* The number of seconds to wait before a timeout has occurred on a query. The default value is 0, which means infinite timeout.
*/
public void setQueryTimeout(int queryTimeout) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.QUERY_TIMEOUT.toString(), queryTimeout);
}
/**
* Getting the query timeout
*
* @return The number of seconds to wait before a timeout has occurred on a query.
*/
public int getQueryTimeout() {
return getIntProperty(connectionProps, SQLServerDriverIntProperty.QUERY_TIMEOUT.toString(),
SQLServerDriverIntProperty.QUERY_TIMEOUT.getDefaultValue());
}
/**
* If this configuration is false the first execution of a prepared statement will call sp_executesql and not prepare
* a statement, once the second execution happens it will call sp_prepexec and actually setup a prepared statement handle. Following
* executions will call sp_execute. This relieves the need for sp_unprepare on prepared statement close if the statement is only
* executed once.
*
* @param enablePrepareOnFirstPreparedStatementCall
* Changes the setting per the description.
*/
public void setEnablePrepareOnFirstPreparedStatementCall(boolean enablePrepareOnFirstPreparedStatementCall) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT.toString(), enablePrepareOnFirstPreparedStatementCall);
}
/**
* If this configuration returns false the first execution of a prepared statement will call sp_executesql and not prepare a statement, once the
* second execution happens it will call sp_prepexec and actually setup a prepared statement handle. Following executions will call sp_execute.
* This relieves the need for sp_unprepare on prepared statement close if the statement is only executed once.
*
* @return Returns the current setting per the description.
*/
public boolean getEnablePrepareOnFirstPreparedStatementCall() {
boolean defaultValue = SQLServerDriverBooleanProperty.ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT.getDefaultValue();
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT.toString(),
defaultValue);
}
/**
* This setting controls how many outstanding prepared statement discard actions (sp_unprepare) can be outstanding per connection before a call to
* clean-up the outstanding handles on the server is executed. If the setting is {@literal <=} 1 unprepare actions will be executed immedietely on
* prepared statement close. If it is set to {@literal >} 1 these calls will be batched together to avoid overhead of calling sp_unprepare too
* often.
*
* @param serverPreparedStatementDiscardThreshold
* Changes the setting per the description.
*/
public void setServerPreparedStatementDiscardThreshold(int serverPreparedStatementDiscardThreshold) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD.toString(), serverPreparedStatementDiscardThreshold);
}
/**
* This setting controls how many outstanding prepared statement discard actions (sp_unprepare) can be outstanding per connection before a call to
* clean-up the outstanding handles on the server is executed. If the setting is {@literal <=} 1 unprepare actions will be executed immedietely on
* prepared statement close. If it is set to {@literal >} 1 these calls will be batched together to avoid overhead of calling sp_unprepare too
* often.
*
* @return Returns the current setting per the description.
*/
public int getServerPreparedStatementDiscardThreshold() {
int defaultSize = SQLServerDriverIntProperty.SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD.getDefaultValue();
return getIntProperty(connectionProps, SQLServerDriverIntProperty.SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD.toString(), defaultSize);
}
/**
* Specifies the size of the prepared statement cache for this connection. A value less than 1 means no cache.
*
* @param statementPoolingCacheSize
* Changes the setting per the description.
*/
public void setStatementPoolingCacheSize(int statementPoolingCacheSize) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.toString(), statementPoolingCacheSize);
}
/**
* Returns the size of the prepared statement cache for this connection. A value less than 1 means no cache.
*
* @return Returns the current setting per the description.
*/
public int getStatementPoolingCacheSize() {
int defaultSize = SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.getDefaultValue();
return getIntProperty(connectionProps, SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.toString(), defaultSize);
}
/**
* Sets the statement pooling to true or false
* @param disableStatementPooling
*/
public void setDisableStatementPooling(boolean disableStatementPooling) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.toString(), disableStatementPooling);
}
/**
* Returns true if statement pooling is disabled.
* @return
*/
public boolean getDisableStatementPooling() {
boolean defaultValue = SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.getDefaultValue();
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.toString(),
defaultValue);
}
/**
* Setting the socket timeout
*
* @param socketTimeout
* The number of milliseconds to wait before a timeout is occurred on a socket read or accept. The default value is 0, which means
* infinite timeout.
*/
public void setSocketTimeout(int socketTimeout) {
setIntProperty(connectionProps, SQLServerDriverIntProperty.SOCKET_TIMEOUT.toString(), socketTimeout);
}
/**
* Getting the socket timeout
*
* @return The number of milliseconds to wait before a timeout is occurred on a socket read or accept.
*/
public int getSocketTimeout() {
int defaultTimeOut = SQLServerDriverIntProperty.SOCKET_TIMEOUT.getDefaultValue();
return getIntProperty(connectionProps, SQLServerDriverIntProperty.SOCKET_TIMEOUT.toString(), defaultTimeOut);
}
/**
* Sets the login configuration file for Kerberos authentication. This
* overrides the default configuration SQLJDBCDriver
*
* @param configurationName the configuration name
*/
public void setJASSConfigurationName(String configurationName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.JAAS_CONFIG_NAME.toString(),
configurationName);
}
/**
* Retrieves the login configuration file for Kerberos authentication.
*
* @return login configuration file name
*/
public String getJASSConfigurationName() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.JAAS_CONFIG_NAME.toString(),
SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue());
}
// responseBuffering controls the driver's buffering of responses from SQL Server.
// Possible values are:
//
// "full" - Fully buffer the response at execution time.
// Advantages:
// 100% back compat with v1.1 driver
// Maximizes concurrency on the server
// Disadvantages:
// Consumes more client-side memory
// Client scalability limits with large responses
// More execute latency
//
// "adaptive" - Data Pipe adaptive buffering
// Advantages:
// Buffers only when necessary, only as much as necessary
// Enables handling very large responses, values
// Disadvantages
// Reduced concurrency on the server
// Internal functions for setting/getting property values.
// Set a string property value.
// Caller will always supply a non-null props and propKey.
// Caller may supply a null propValue, in this case no property value is set.
private void setStringProperty(Properties props,
String propKey,
String propValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER) && !propKey.contains("password") && !propKey.contains("Password")) {
loggerExternal.entering(getClassNameLogging(), "set" + propKey, propValue);
}
else
loggerExternal.entering(getClassNameLogging(), "set" + propKey);
if (null != propValue)
props.setProperty(propKey, propValue);
loggerExternal.exiting(getClassNameLogging(), "set" + propKey);
}
// Reads property value in String format.
// Caller will always supply a non-null props and propKey.
// Returns null if the specific property value is not set.
private String getStringProperty(Properties props,
String propKey,
String defaultValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "get" + propKey);
String propValue = props.getProperty(propKey);
if (null == propValue)
propValue = defaultValue;
if (loggerExternal.isLoggable(java.util.logging.Level.FINER) && !propKey.contains("password") && !propKey.contains("Password"))
loggerExternal.exiting(getClassNameLogging(), "get" + propKey, propValue);
return propValue;
}
// Set an integer property value.
// Caller will always supply a non-null props and propKey.
private void setIntProperty(Properties props,
String propKey,
int propValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "set" + propKey, propValue);
props.setProperty(propKey, Integer.valueOf(propValue).toString());
loggerExternal.exiting(getClassNameLogging(), "set" + propKey);
}
// Reads a property value in int format.
// Caller will always supply a non-null props and propKey.
// Returns defaultValue if the specific property value is not set.
private int getIntProperty(Properties props,
String propKey,
int defaultValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "get" + propKey);
String propValue = props.getProperty(propKey);
int value = defaultValue;
if (null != propValue) {
try {
value = Integer.parseInt(propValue);
}
catch (NumberFormatException nfe) {
// This exception cannot occur as all of our properties
// are set internally by int -> Integer.toString.
assert false : "Bad portNumber:-" + propValue;
}
}
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.exiting(getClassNameLogging(), "get" + propKey, value);
return value;
}
// Set a boolean property value.
// Caller will always supply a non-null props and propKey.
private void setBooleanProperty(Properties props,
String propKey,
boolean propValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "set" + propKey, propValue);
props.setProperty(propKey, (propValue) ? "true" : "false");
loggerExternal.exiting(getClassNameLogging(), "set" + propKey);
}
// Reads a property value in boolean format.
// Caller will always supply a non-null props and propKey.
// Returns defaultValue if the specific property value is not set.
private boolean getBooleanProperty(Properties props,
String propKey,
boolean defaultValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "get" + propKey);
String propValue = props.getProperty(propKey);
Boolean value;
if (null == propValue) {
value = defaultValue;
}
else {
// Since we set the value of the String property ourselves to
// "true" or "false", we can do this.
value = Boolean.valueOf(propValue);
}
loggerExternal.exiting(getClassNameLogging(), "get" + propKey, value);
return value;
}
private void setObjectProperty(Properties props,
String propKey,
Object propValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER)) {
loggerExternal.entering(getClassNameLogging(), "set" + propKey);
}
if (null != propValue) {
props.put(propKey, propValue);
}
loggerExternal.exiting(getClassNameLogging(), "set" + propKey);
}
private Object getObjectProperty(Properties props,
String propKey,
Object defaultValue) {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "get" + propKey);
Object propValue = props.get(propKey);
if (null == propValue)
propValue = defaultValue;
loggerExternal.exiting(getClassNameLogging(), "get" + propKey);
return propValue;
}
// Returns a SQLServerConnection given username, password, and pooledConnection.
// Note that the DataSource properties set to connectionProps are used when creating
// the connection.
// Both username and password can be null.
// If pooledConnection is not null, then connection returned is attached to the pooledConnection
// and participates in connection pooling.
SQLServerConnection getConnectionInternal(String username,
String password,
SQLServerPooledConnection pooledConnection) throws SQLServerException {
Properties userSuppliedProps;
Properties mergedProps;
// Trust store password stripped and this object got created via Objectfactory referencing.
if (trustStorePasswordStripped)
SQLServerException.makeFromDriverError(null, null, SQLServerException.getErrString("R_referencingFailedTSP"), null, true);
// If username or password is passed in, clone the property set so we
// don't alter original connectionProps.
if (null != username || null != password) {
userSuppliedProps = (Properties) this.connectionProps.clone();
// Remove user and password from connectionProps if set.
// We want the user supplied user+password to replace
// whatever is set in connectionProps.
userSuppliedProps.remove(SQLServerDriverStringProperty.USER.toString());
userSuppliedProps.remove(SQLServerDriverStringProperty.PASSWORD.toString());
if (null != username)
userSuppliedProps.put(SQLServerDriverStringProperty.USER.toString(), username);
if (null != password)
userSuppliedProps.put(SQLServerDriverStringProperty.PASSWORD.toString(), password);
}
else {
userSuppliedProps = connectionProps;
}
// Merge in URL properties into userSuppliedProps if URL is set.
if (null != dataSourceURL) {
Properties urlProps = Util.parseUrl(dataSourceURL, dsLogger);
// null returned properties means that the passed in URL is not supported.
if (null == urlProps)
SQLServerException.makeFromDriverError(null, null, SQLServerException.getErrString("R_errorConnectionString"), null, true);
// Manually merge URL props and user supplied props.
mergedProps = SQLServerDriver.mergeURLAndSuppliedProperties(urlProps, userSuppliedProps);
}
else {
mergedProps = userSuppliedProps;
}
// Create new connection and connect.
if (dsLogger.isLoggable(Level.FINER))
dsLogger.finer(toString() + " Begin create new connection.");
SQLServerConnection result = null;
if (Util.use43Wrapper()) {
result = new SQLServerConnection43(toString());
}
else {
result = new SQLServerConnection(toString());
}
result.connect(mergedProps, pooledConnection);
if (dsLogger.isLoggable(Level.FINER))
dsLogger.finer(toString() + " End create new connection " + result.toString());
return result;
}
// Implement javax.naming.Referenceable interface methods.
public Reference getReference() {
loggerExternal.entering(getClassNameLogging(), "getReference");
Reference ref = getReferenceInternal("com.microsoft.sqlserver.jdbc.SQLServerDataSource");
loggerExternal.exiting(getClassNameLogging(), "getReference", ref);
return ref;
}
Reference getReferenceInternal(String dataSourceClassString) {
if (dsLogger.isLoggable(Level.FINER))
dsLogger.finer(toString() + " creating reference for " + dataSourceClassString + ".");
Reference ref = new Reference(this.getClass().getName(), "com.microsoft.sqlserver.jdbc.SQLServerDataSourceObjectFactory", null);
if (null != dataSourceClassString)
ref.add(new StringRefAddr("class", dataSourceClassString));
if (trustStorePasswordStripped)
ref.add(new StringRefAddr("trustStorePasswordStripped", "true"));
// Add each property name+value pair found in connectionProps.
Enumeration> e = connectionProps.keys();
while (e.hasMoreElements()) {
String propertyName = (String) e.nextElement();
// If a trustStore password is set, it is omitted and a trustStorePasswordSet flag is set.
if (propertyName.equals(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString())) {
// The property set and the variable set at the same time is not possible
assert trustStorePasswordStripped == false;
ref.add(new StringRefAddr("trustStorePasswordStripped", "true"));
}
else {
// do not add passwords to the collection. we have normal password
if (!propertyName.contains(SQLServerDriverStringProperty.PASSWORD.toString()))
ref.add(new StringRefAddr(propertyName, connectionProps.getProperty(propertyName)));
}
}
// Add dataSourceURL and dataSourceDescription as these will not appear in connectionProps.
if (null != dataSourceURL)
ref.add(new StringRefAddr("dataSourceURL", dataSourceURL));
if (null != dataSourceDescription)
ref.add(new StringRefAddr("dataSourceDescription", dataSourceDescription));
return ref;
}
// Initialize this datasource from properties found inside the reference ref.
// Called by SQLServerDataSourceObjectFactory to initialize new DataSource instance.
void initializeFromReference(javax.naming.Reference ref) {
// Enumerate all the StringRefAddr objects in the Reference and assign properties appropriately.
Enumeration> e = ref.getAll();
while (e.hasMoreElements()) {
StringRefAddr addr = (StringRefAddr) e.nextElement();
String propertyName = addr.getType();
String propertyValue = (String) addr.getContent();
// Special case dataSourceURL and dataSourceDescription.
if ("dataSourceURL".equals(propertyName)) {
dataSourceURL = propertyValue;
}
else if ("dataSourceDescription".equals(propertyName)) {
dataSourceDescription = propertyValue;
}
else if ("trustStorePasswordStripped".equals(propertyName)) {
trustStorePasswordStripped = true;
}
// Just skip "class" StringRefAddr, it does not go into connectionProps
else if (!"class".equals(propertyName)) {
connectionProps.setProperty(propertyName, propertyValue);
}
}
}
public boolean isWrapperFor(Class> iface) throws SQLException {
loggerExternal.entering(getClassNameLogging(), "isWrapperFor", iface);
boolean f = iface.isInstance(this);
loggerExternal.exiting(getClassNameLogging(), "isWrapperFor", f);
return f;
}
public T unwrap(Class iface) throws SQLException {
loggerExternal.entering(getClassNameLogging(), "unwrap", iface);
T t;
try {
t = iface.cast(this);
}
catch (ClassCastException e) {
throw new SQLServerException(e.getMessage(), e);
}
loggerExternal.exiting(getClassNameLogging(), "unwrap", t);
return t;
}
// Returns unique id for each DataSource instance.
private static int nextDataSourceID() {
return baseDataSourceID.incrementAndGet();
}
private Object writeReplace() throws java.io.ObjectStreamException {
return new SerializationProxy(this);
}
private void readObject(java.io.ObjectInputStream stream) throws java.io.InvalidObjectException {
// For added security/robustness, the only way to rehydrate a serialized SQLServerDataSource
// is to use a SerializationProxy. Direct use of readObject() is not supported.
throw new java.io.InvalidObjectException("");
}
// This code is duplicated in pooled and XA datasource classes.
private static class SerializationProxy implements java.io.Serializable {
private final Reference ref;
private static final long serialVersionUID = 654661379542314226L;
SerializationProxy(SQLServerDataSource ds) {
// We do not need the class name so pass null, serialization mechanism
// stores the class info.
ref = ds.getReferenceInternal(null);
}
private Object readResolve() {
SQLServerDataSource ds = new SQLServerDataSource();
ds.initializeFromReference(ref);
return ds;
}
}
}