All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.sqlserver.jdbc.SQLServerDataSource Maven / Gradle / Ivy

There is a newer version: 12.8.1.jre11
Show newest version
/*
 * 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 setFIPSProvider(String fipsProvider) { setStringProperty(connectionProps, SQLServerDriverStringProperty.FIPS_PROVIDER.toString(), fipsProvider); } public String getFIPSProvider() { return getStringProperty(connectionProps, SQLServerDriverStringProperty.FIPS_PROVIDER.toString(), null); } // 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 conection. 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 conection. 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); } /** * 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, new Integer(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 = 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; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy