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

com.microsoft.sqlserver.jdbc.SQLServerDriver 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.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.ietf.jgss.GSSCredential;


/**
 * Implements the java.sql.Driver for SQLServerConnect.
 *
 */
final class SQLServerDriverPropertyInfo {
    private final String name;

    final String getName() {
        return name;
    }

    private final String description;
    private final String defaultValue;
    private final boolean required;
    private final String[] choices;

    SQLServerDriverPropertyInfo(String name, String defaultValue, boolean required, String[] choices) {
        this.name = name;
        this.description = SQLServerResource.getResource("R_" + name + "PropertyDescription");
        this.defaultValue = defaultValue;
        this.required = required;
        this.choices = choices;
    }

    DriverPropertyInfo build(Properties connProperties) {
        String propValue = name.equals(SQLServerDriverStringProperty.PASSWORD.toString()) ? "" : connProperties
                .getProperty(name);

        if (null == propValue)
            propValue = defaultValue;

        DriverPropertyInfo info = new DriverPropertyInfo(name, propValue);
        info.description = description;
        info.required = required;
        info.choices = choices;

        return info;
    }
}


enum SqlAuthentication {
    NotSpecified,
    SqlPassword,
    ActiveDirectoryPassword,
    ActiveDirectoryIntegrated,
    ActiveDirectoryMSI,
    ActiveDirectoryServicePrincipal,
    ActiveDirectoryInteractive;

    static SqlAuthentication valueOfString(String value) throws SQLServerException {
        SqlAuthentication method = null;

        if (value.toLowerCase(Locale.US).equalsIgnoreCase(SqlAuthentication.NotSpecified.toString())) {
            method = SqlAuthentication.NotSpecified;
        } else if (value.toLowerCase(Locale.US).equalsIgnoreCase(SqlAuthentication.SqlPassword.toString())) {
            method = SqlAuthentication.SqlPassword;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(SqlAuthentication.ActiveDirectoryPassword.toString())) {
            method = SqlAuthentication.ActiveDirectoryPassword;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(SqlAuthentication.ActiveDirectoryIntegrated.toString())) {
            method = SqlAuthentication.ActiveDirectoryIntegrated;
        } else if (value.toLowerCase(Locale.US).equalsIgnoreCase(SqlAuthentication.ActiveDirectoryMSI.toString())) {
            method = SqlAuthentication.ActiveDirectoryMSI;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(SqlAuthentication.ActiveDirectoryServicePrincipal.toString())) {
            method = SqlAuthentication.ActiveDirectoryServicePrincipal;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(SqlAuthentication.ActiveDirectoryInteractive.toString())) {
            method = SqlAuthentication.ActiveDirectoryInteractive;
        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_InvalidConnectionSetting"));
            Object[] msgArgs = {"authentication", value};
            throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
        }
        return method;
    }
}


enum ColumnEncryptionSetting {
    Enabled,
    Disabled;

    static ColumnEncryptionSetting valueOfString(String value) throws SQLServerException {
        ColumnEncryptionSetting method = null;

        if (value.toLowerCase(Locale.US).equalsIgnoreCase(ColumnEncryptionSetting.Enabled.toString())) {
            method = ColumnEncryptionSetting.Enabled;
        } else if (value.toLowerCase(Locale.US).equalsIgnoreCase(ColumnEncryptionSetting.Disabled.toString())) {
            method = ColumnEncryptionSetting.Disabled;
        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_InvalidConnectionSetting"));
            Object[] msgArgs = {"columnEncryptionSetting", value};
            throw new SQLServerException(form.format(msgArgs), null);
        }
        return method;
    }
}


enum AttestationProtocol {
    HGS("HGS"),
    AAS("AAS");

    private final String protocol;

    AttestationProtocol(String protocol) {
        this.protocol = protocol;
    }

    static boolean isValidAttestationProtocol(String protocol) {
        for (AttestationProtocol p : AttestationProtocol.values()) {
            if (protocol.equalsIgnoreCase(p.toString())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return protocol;
    }
}


enum EnclaveType {
    VBS("VBS"),
    SGX("SGX");

    private final String type;

    EnclaveType(String type) {
        this.type = type;
    }

    public int getValue() {
        return ordinal() + 1;
    }

    static boolean isValidEnclaveType(String type) {
        for (EnclaveType t : EnclaveType.values()) {
            if (type.equalsIgnoreCase(t.toString())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return type;
    }
}


enum SSLProtocol {
    TLS("TLS"),
    TLS_V10("TLSv1"),
    TLS_V11("TLSv1.1"),
    TLS_V12("TLSv1.2"),;

    private final String name;

    private SSLProtocol(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }

    static SSLProtocol valueOfString(String value) throws SQLServerException {
        SSLProtocol protocol = null;

        if (value.toLowerCase(Locale.ENGLISH).equalsIgnoreCase(SSLProtocol.TLS.toString())) {
            protocol = SSLProtocol.TLS;
        } else if (value.toLowerCase(Locale.ENGLISH).equalsIgnoreCase(SSLProtocol.TLS_V10.toString())) {
            protocol = SSLProtocol.TLS_V10;
        } else if (value.toLowerCase(Locale.ENGLISH).equalsIgnoreCase(SSLProtocol.TLS_V11.toString())) {
            protocol = SSLProtocol.TLS_V11;
        } else if (value.toLowerCase(Locale.ENGLISH).equalsIgnoreCase(SSLProtocol.TLS_V12.toString())) {
            protocol = SSLProtocol.TLS_V12;
        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidSSLProtocol"));
            Object[] msgArgs = {value};
            throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
        }
        return protocol;
    }
}


enum KeyStoreAuthentication {
    JavaKeyStorePassword,
    KeyVaultClientSecret,
    KeyVaultManagedIdentity;

    static KeyStoreAuthentication valueOfString(String value) throws SQLServerException {
        KeyStoreAuthentication method = null;

        if (value.toLowerCase(Locale.US).equalsIgnoreCase(KeyStoreAuthentication.JavaKeyStorePassword.toString())) {
            method = KeyStoreAuthentication.JavaKeyStorePassword;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(KeyStoreAuthentication.KeyVaultClientSecret.toString())) {
            method = KeyStoreAuthentication.KeyVaultClientSecret;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(KeyStoreAuthentication.KeyVaultManagedIdentity.toString())) {
            method = KeyStoreAuthentication.KeyVaultManagedIdentity;

        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_InvalidConnectionSetting"));
            Object[] msgArgs = {"keyStoreAuthentication", value};
            throw new SQLServerException(form.format(msgArgs), null);
        }
        return method;
    }
}


enum AuthenticationScheme {
    nativeAuthentication,
    ntlm,
    javaKerberos;

    static AuthenticationScheme valueOfString(String value) throws SQLServerException {
        AuthenticationScheme scheme;
        if (value.toLowerCase(Locale.US).equalsIgnoreCase(AuthenticationScheme.javaKerberos.toString())) {
            scheme = AuthenticationScheme.javaKerberos;
        } else if (value.toLowerCase(Locale.US)
                .equalsIgnoreCase(AuthenticationScheme.nativeAuthentication.toString())) {
            scheme = AuthenticationScheme.nativeAuthentication;
        } else if (value.toLowerCase(Locale.US).equalsIgnoreCase(AuthenticationScheme.ntlm.toString())) {
            scheme = AuthenticationScheme.ntlm;
        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidAuthenticationScheme"));
            Object[] msgArgs = {value};
            throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
        }
        return scheme;
    }
}


enum ApplicationIntent {
    READ_WRITE("readwrite"),
    READ_ONLY("readonly");

    // the value of the enum
    private final String value;

    /**
     * Constructs a ApplicationIntent that sets the string value of the enum.
     */
    private ApplicationIntent(String value) {
        this.value = value;
    }

    /**
     * Returns the string value of enum.
     */
    @Override
    public String toString() {
        return value;
    }

    static ApplicationIntent valueOfString(String value) throws SQLServerException {
        ApplicationIntent applicationIntent = ApplicationIntent.READ_WRITE;
        assert value != null;
        // handling turkish i issues
        value = value.toUpperCase(Locale.US).toLowerCase(Locale.US);
        if (value.equalsIgnoreCase(ApplicationIntent.READ_ONLY.toString())) {
            applicationIntent = ApplicationIntent.READ_ONLY;
        } else if (value.equalsIgnoreCase(ApplicationIntent.READ_WRITE.toString())) {
            applicationIntent = ApplicationIntent.READ_WRITE;
        } else {
            MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidapplicationIntent"));
            Object[] msgArgs = {value};
            throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
        }

        return applicationIntent;
    }
}


enum SQLServerDriverObjectProperty {
    GSS_CREDENTIAL("gsscredential", null);

    private final String name;
    private final String defaultValue;

    private SQLServerDriverObjectProperty(String name, String defaultValue) {
        this.name = name;
        this.defaultValue = defaultValue;
    }

    /**
     * Returns string due to structure of DRIVER_PROPERTIES_PROPERTY_ONLY.
     * 
     * @return
     */
    public String getDefaultValue() {
        return defaultValue;
    }

    @Override
    public String toString() {
        return name;
    }
}


enum SQLServerDriverStringProperty {
    APPLICATION_INTENT("applicationIntent", ApplicationIntent.READ_WRITE.toString()),
    APPLICATION_NAME("applicationName", SQLServerDriver.DEFAULT_APP_NAME),
    DATABASE_NAME("databaseName", ""),
    FAILOVER_PARTNER("failoverPartner", ""),
    HOSTNAME_IN_CERTIFICATE("hostNameInCertificate", ""),
    INSTANCE_NAME("instanceName", ""),
    JAAS_CONFIG_NAME("jaasConfigurationName", "SQLJDBCDriver"),
    PASSWORD("password", ""),
    RESPONSE_BUFFERING("responseBuffering", "adaptive"),
    SELECT_METHOD("selectMethod", "direct"),
    DOMAIN("domain", ""),
    SERVER_NAME("serverName", ""),
    SERVER_SPN("serverSpn", ""),
    SOCKET_FACTORY_CLASS("socketFactoryClass", ""),
    SOCKET_FACTORY_CONSTRUCTOR_ARG("socketFactoryConstructorArg", ""),
    TRUST_STORE_TYPE("trustStoreType", "JKS"),
    TRUST_STORE("trustStore", ""),
    TRUST_STORE_PASSWORD("trustStorePassword", ""),
    TRUST_MANAGER_CLASS("trustManagerClass", ""),
    TRUST_MANAGER_CONSTRUCTOR_ARG("trustManagerConstructorArg", ""),
    USER("user", ""),
    WORKSTATION_ID("workstationID", Util.WSIDNotAvailable),
    AUTHENTICATION_SCHEME("authenticationScheme", AuthenticationScheme.nativeAuthentication.toString()),
    AUTHENTICATION("authentication", SqlAuthentication.NotSpecified.toString()),
    ACCESS_TOKEN("accessToken", ""),
    COLUMN_ENCRYPTION("columnEncryptionSetting", ColumnEncryptionSetting.Disabled.toString()),
    ENCLAVE_ATTESTATION_URL("enclaveAttestationUrl", ""),
    ENCLAVE_ATTESTATION_PROTOCOL("enclaveAttestationProtocol", ""),
    KEY_STORE_AUTHENTICATION("keyStoreAuthentication", ""),
    KEY_STORE_SECRET("keyStoreSecret", ""),
    KEY_STORE_LOCATION("keyStoreLocation", ""),
    SSL_PROTOCOL("sslProtocol", SSLProtocol.TLS.toString()),
    MSI_CLIENT_ID("msiClientId", ""),
    KEY_VAULT_PROVIDER_CLIENT_ID("keyVaultProviderClientId", ""),
    KEY_VAULT_PROVIDER_CLIENT_KEY("keyVaultProviderClientKey", ""),
    KEY_STORE_PRINCIPAL_ID("keyStorePrincipalId", ""),
    CLIENT_CERTIFICATE("clientCertificate", ""),
    CLIENT_KEY("clientKey", ""),
    CLIENT_KEY_PASSWORD("clientKeyPassword", ""),
    AAD_SECURE_PRINCIPAL_ID("AADSecurePrincipalId", ""),
    AAD_SECURE_PRINCIPAL_SECRET("AADSecurePrincipalSecret", ""),
    MAX_RESULT_BUFFER("maxResultBuffer", "-1");

    private final String name;
    private final String defaultValue;

    private SQLServerDriverStringProperty(String name, String defaultValue) {
        this.name = name;
        this.defaultValue = defaultValue;
    }

    String getDefaultValue() {
        return defaultValue;
    }

    @Override
    public String toString() {
        return name;
    }
}


enum SQLServerDriverIntProperty {
    PACKET_SIZE("packetSize", TDS.DEFAULT_PACKET_SIZE),
    LOCK_TIMEOUT("lockTimeout", -1),
    LOGIN_TIMEOUT("loginTimeout", 15, 0, 65535),
    QUERY_TIMEOUT("queryTimeout", -1),
    PORT_NUMBER("portNumber", 1433),
    SOCKET_TIMEOUT("socketTimeout", 0),
    SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD("serverPreparedStatementDiscardThreshold", SQLServerConnection.DEFAULT_SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD),
    STATEMENT_POOLING_CACHE_SIZE("statementPoolingCacheSize", SQLServerConnection.DEFAULT_STATEMENT_POOLING_CACHE_SIZE),
    CANCEL_QUERY_TIMEOUT("cancelQueryTimeout", -1),
    CONNECT_RETRY_COUNT("connectRetryCount", 1, 0, 255),
    CONNECT_RETRY_INTERVAL("connectRetryInterval", 10, 1, 60);

    private final String name;
    private final int defaultValue;
    private int minValue = -1; // not assigned
    private int maxValue = -1; // not assigned

    private SQLServerDriverIntProperty(String name, int defaultValue) {
        this.name = name;
        this.defaultValue = defaultValue;
    }

    private SQLServerDriverIntProperty(String name, int defaultValue, int minValue, int maxValue) {
        this.name = name;
        this.defaultValue = defaultValue;
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    int getDefaultValue() {
        return defaultValue;
    }

    boolean isValidValue(int value) {
        return (minValue == -1 && maxValue == -1) || (value >= minValue && value <= maxValue);
    }

    @Override
    public String toString() {
        return name;
    }
}


enum SQLServerDriverBooleanProperty {
    DISABLE_STATEMENT_POOLING("disableStatementPooling", true),
    ENCRYPT("encrypt", false),
    INTEGRATED_SECURITY("integratedSecurity", false),
    LAST_UPDATE_COUNT("lastUpdateCount", true),
    MULTI_SUBNET_FAILOVER("multiSubnetFailover", false),
    SERVER_NAME_AS_ACE("serverNameAsACE", false),
    SEND_STRING_PARAMETERS_AS_UNICODE("sendStringParametersAsUnicode", true),
    SEND_TIME_AS_DATETIME("sendTimeAsDatetime", true),
    TRANSPARENT_NETWORK_IP_RESOLUTION("TransparentNetworkIPResolution", true),
    TRUST_SERVER_CERTIFICATE("trustServerCertificate", false),
    XOPEN_STATES("xopenStates", false),
    FIPS("fips", false),
    ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT("enablePrepareOnFirstPreparedStatementCall", SQLServerConnection.DEFAULT_ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT_CALL),
    USE_BULK_COPY_FOR_BATCH_INSERT("useBulkCopyForBatchInsert", false),
    USE_FMT_ONLY("useFmtOnly", false),
    SEND_TEMPORAL_DATATYPES_AS_STRING_FOR_BULK_COPY("sendTemporalDataTypesAsStringForBulkCopy", true),
    DELAY_LOADING_LOBS("delayLoadingLobs", true);

    private final String name;
    private final boolean defaultValue;

    private SQLServerDriverBooleanProperty(String name, boolean defaultValue) {
        this.name = name;
        this.defaultValue = defaultValue;
    }

    boolean getDefaultValue() {
        return defaultValue;
    }

    @Override
    public String toString() {
        return name;
    }
}


/**
 * Provides methods to connect to a SQL Server database and to obtain information about the JDBC driver.
 */
public final class SQLServerDriver implements java.sql.Driver {
    static final String PRODUCT_NAME = "Microsoft JDBC Driver " + SQLJdbcVersion.major + "." + SQLJdbcVersion.minor
            + " for SQL Server";
    static final String AUTH_DLL_NAME = "mssql-jdbc_auth-" + SQLJdbcVersion.major + "." + SQLJdbcVersion.minor + "."
            + SQLJdbcVersion.patch + "." + Util.getJVMArchOnWindows() + SQLJdbcVersion.releaseExt;
    static final String DEFAULT_APP_NAME = "Microsoft JDBC Driver for SQL Server";

    private static final String[] TRUE_FALSE = {"true", "false"};
    private static final SQLServerDriverPropertyInfo[] DRIVER_PROPERTIES = {
            // default required available choices
            // property name value property (if appropriate)
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.APPLICATION_INTENT.toString(),
                    SQLServerDriverStringProperty.APPLICATION_INTENT.getDefaultValue(), false,
                    new String[] {ApplicationIntent.READ_ONLY.toString(), ApplicationIntent.READ_WRITE.toString()}),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.APPLICATION_NAME.toString(),
                    SQLServerDriverStringProperty.APPLICATION_NAME.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.COLUMN_ENCRYPTION.toString(),
                    SQLServerDriverStringProperty.COLUMN_ENCRYPTION.getDefaultValue(), false,
                    new String[] {ColumnEncryptionSetting.Disabled.toString(),
                            ColumnEncryptionSetting.Enabled.toString()}),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.toString(),
                    SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.toString(),
                    SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.DATABASE_NAME.toString(),
                    SQLServerDriverStringProperty.DATABASE_NAME.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.getDefaultValue()), false,
                    new String[] {"true"}),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.ENCRYPT.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.ENCRYPT.getDefaultValue()), false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.FAILOVER_PARTNER.toString(),
                    SQLServerDriverStringProperty.FAILOVER_PARTNER.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(),
                    SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.INSTANCE_NAME.toString(),
                    SQLServerDriverStringProperty.INSTANCE_NAME.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(),
                    SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.getDefaultValue(), false,
                    new String[] {KeyStoreAuthentication.JavaKeyStorePassword.toString()}),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_STORE_SECRET.toString(),
                    SQLServerDriverStringProperty.KEY_STORE_SECRET.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_STORE_LOCATION.toString(),
                    SQLServerDriverStringProperty.KEY_STORE_LOCATION.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.LOCK_TIMEOUT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.LOCK_TIMEOUT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.LOGIN_TIMEOUT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.PACKET_SIZE.toString(),
                    Integer.toString(SQLServerDriverIntProperty.PACKET_SIZE.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.PASSWORD.toString(),
                    SQLServerDriverStringProperty.PASSWORD.getDefaultValue(), true, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.PORT_NUMBER.toString(),
                    Integer.toString(SQLServerDriverIntProperty.PORT_NUMBER.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.QUERY_TIMEOUT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.QUERY_TIMEOUT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString(),
                    SQLServerDriverStringProperty.RESPONSE_BUFFERING.getDefaultValue(), false,
                    new String[] {"adaptive", "full"}),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SELECT_METHOD.toString(),
                    SQLServerDriverStringProperty.SELECT_METHOD.getDefaultValue(), false,
                    new String[] {"direct", "cursor"}),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.toString(),
                    Boolean.toString(
                            SQLServerDriverBooleanProperty.SEND_STRING_PARAMETERS_AS_UNICODE.getDefaultValue()),
                    false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.DOMAIN.toString(),
                    SQLServerDriverStringProperty.DOMAIN.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SERVER_NAME.toString(),
                    SQLServerDriverStringProperty.SERVER_NAME.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SERVER_SPN.toString(),
                    SQLServerDriverStringProperty.SERVER_SPN.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SOCKET_FACTORY_CLASS.toString(),
                    SQLServerDriverStringProperty.SOCKET_FACTORY_CLASS.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SOCKET_FACTORY_CONSTRUCTOR_ARG.toString(),
                    SQLServerDriverStringProperty.SOCKET_FACTORY_CONSTRUCTOR_ARG.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString(),
                    Boolean.toString(
                            SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.getDefaultValue()),
                    false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_STORE_TYPE.toString(),
                    SQLServerDriverStringProperty.TRUST_STORE_TYPE.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_STORE.toString(),
                    SQLServerDriverStringProperty.TRUST_STORE.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(),
                    SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.toString(),
                    SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.toString(),
                    SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.USER.toString(),
                    SQLServerDriverStringProperty.USER.getDefaultValue(), true, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.WORKSTATION_ID.toString(),
                    SQLServerDriverStringProperty.WORKSTATION_ID.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.XOPEN_STATES.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.XOPEN_STATES.getDefaultValue()), false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.AUTHENTICATION_SCHEME.toString(),
                    SQLServerDriverStringProperty.AUTHENTICATION_SCHEME.getDefaultValue(), false,
                    new String[] {AuthenticationScheme.javaKerberos.toString(),
                            AuthenticationScheme.nativeAuthentication.toString(),
                            AuthenticationScheme.ntlm.toString()}),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.AUTHENTICATION.toString(),
                    SQLServerDriverStringProperty.AUTHENTICATION.getDefaultValue(), false,
                    new String[] {SqlAuthentication.NotSpecified.toString(), SqlAuthentication.SqlPassword.toString(),
                            SqlAuthentication.ActiveDirectoryPassword.toString(),
                            SqlAuthentication.ActiveDirectoryIntegrated.toString(),
                            SqlAuthentication.ActiveDirectoryMSI.toString(),
                            SqlAuthentication.ActiveDirectoryServicePrincipal.toString(),
                            SqlAuthentication.ActiveDirectoryInteractive.toString()}),

            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.SOCKET_TIMEOUT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.SOCKET_TIMEOUT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.FIPS.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.FIPS.getDefaultValue()), false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(
                    SQLServerDriverBooleanProperty.ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT
                            .getDefaultValue()),
                    false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(
                    SQLServerDriverIntProperty.SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD.toString(),
                    Integer.toString(
                            SQLServerDriverIntProperty.SERVER_PREPARED_STATEMENT_DISCARD_THRESHOLD.getDefaultValue()),
                    false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.toString(),
                    Integer.toString(SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.getDefaultValue()), false,
                    null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.JAAS_CONFIG_NAME.toString(),
                    SQLServerDriverStringProperty.JAAS_CONFIG_NAME.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.SSL_PROTOCOL.toString(),
                    SQLServerDriverStringProperty.SSL_PROTOCOL.getDefaultValue(), false,
                    new String[] {SSLProtocol.TLS.toString(), SSLProtocol.TLS_V10.toString(),
                            SSLProtocol.TLS_V11.toString(), SSLProtocol.TLS_V12.toString()}),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.CANCEL_QUERY_TIMEOUT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.CANCEL_QUERY_TIMEOUT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.USE_BULK_COPY_FOR_BATCH_INSERT.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.USE_BULK_COPY_FOR_BATCH_INSERT.getDefaultValue()),
                    false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.MSI_CLIENT_ID.toString(),
                    SQLServerDriverStringProperty.MSI_CLIENT_ID.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.toString(),
                    SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.toString(),
                    SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue()), false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_STORE_PRINCIPAL_ID.toString(),
                    SQLServerDriverStringProperty.KEY_STORE_PRINCIPAL_ID.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.CLIENT_CERTIFICATE.toString(),
                    SQLServerDriverStringProperty.CLIENT_CERTIFICATE.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.CLIENT_KEY.toString(),
                    SQLServerDriverStringProperty.CLIENT_KEY.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.CLIENT_KEY_PASSWORD.toString(),
                    SQLServerDriverStringProperty.CLIENT_KEY_PASSWORD.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.DELAY_LOADING_LOBS.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.DELAY_LOADING_LOBS.getDefaultValue()), false,
                    TRUE_FALSE),
            new SQLServerDriverPropertyInfo(
                    SQLServerDriverBooleanProperty.SEND_TEMPORAL_DATATYPES_AS_STRING_FOR_BULK_COPY.toString(),
                    Boolean.toString(SQLServerDriverBooleanProperty.SEND_TEMPORAL_DATATYPES_AS_STRING_FOR_BULK_COPY
                            .getDefaultValue()),
                    false, TRUE_FALSE),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.AAD_SECURE_PRINCIPAL_ID.toString(),
                    SQLServerDriverStringProperty.AAD_SECURE_PRINCIPAL_ID.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.AAD_SECURE_PRINCIPAL_SECRET.toString(),
                    SQLServerDriverStringProperty.AAD_SECURE_PRINCIPAL_SECRET.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.MAX_RESULT_BUFFER.toString(),
                    SQLServerDriverStringProperty.MAX_RESULT_BUFFER.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.CONNECT_RETRY_COUNT.toString(),
                    Integer.toString(SQLServerDriverIntProperty.CONNECT_RETRY_COUNT.getDefaultValue()), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverIntProperty.CONNECT_RETRY_INTERVAL.toString(),
                    Integer.toString(SQLServerDriverIntProperty.CONNECT_RETRY_INTERVAL.getDefaultValue()), false,
                    null),};

    /**
     * Properties that can only be set by using Properties. Cannot set in connection string
     */
    private static final SQLServerDriverPropertyInfo[] DRIVER_PROPERTIES_PROPERTY_ONLY = {
            // default required available choices
            // property name value property (if appropriate)
            new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ACCESS_TOKEN.toString(),
                    SQLServerDriverStringProperty.ACCESS_TOKEN.getDefaultValue(), false, null),
            new SQLServerDriverPropertyInfo(SQLServerDriverObjectProperty.GSS_CREDENTIAL.toString(),
                    SQLServerDriverObjectProperty.GSS_CREDENTIAL.getDefaultValue(), false, null),};

    private static final String driverPropertiesSynonyms[][] = {
            {"database", SQLServerDriverStringProperty.DATABASE_NAME.toString()},
            {"userName", SQLServerDriverStringProperty.USER.toString()},
            {"server", SQLServerDriverStringProperty.SERVER_NAME.toString()},
            {"domainName", SQLServerDriverStringProperty.DOMAIN.toString()},
            {"port", SQLServerDriverIntProperty.PORT_NUMBER.toString()}};
    static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for
                                                                      // logging).
    final private int instanceID; // Unique id for this instance.
    final private String traceID;

    // Returns unique id for each instance.
    private static int nextInstanceID() {
        return baseID.incrementAndGet();
    }

    @Override
    final public String toString() {
        return traceID;
    }

    static final private java.util.logging.Logger loggerExternal = java.util.logging.Logger
            .getLogger("com.microsoft.sqlserver.jdbc.Driver");
    static final private java.util.logging.Logger parentLogger = java.util.logging.Logger
            .getLogger("com.microsoft.sqlserver.jdbc");
    final private String loggingClassName;

    String getClassNameLogging() {
        return loggingClassName;
    }

    private final static java.util.logging.Logger drLogger = java.util.logging.Logger
            .getLogger("com.microsoft.sqlserver.jdbc.internals.SQLServerDriver");
    private static java.sql.Driver mssqlDriver = null;
    // Register with the DriverManager
    static {
        try {
            register();
        } catch (SQLException e) {
            if (drLogger.isLoggable(Level.FINER) && Util.isActivityTraceOn()) {
                drLogger.finer("Error registering driver: " + e);
            }
        }
    }

    /*
     * Registers the driver with DriverManager. No-op if driver is already registered.
     */
    public static void register() throws SQLException {
        if (!isRegistered()) {
            mssqlDriver = new SQLServerDriver();
            DriverManager.registerDriver(mssqlDriver);
        }
    }

    /*
     * De-registers the driver with the DriverManager. No-op if the driver is not registered.
     */
    public static void deregister() throws SQLException {
        if (isRegistered()) {
            DriverManager.deregisterDriver(mssqlDriver);
            mssqlDriver = null;
        }
    }

    /*
     * Checks whether the driver has been registered with the driver manager.
     */
    public static boolean isRegistered() {
        return mssqlDriver != null;
    }

    public SQLServerDriver() {
        instanceID = nextInstanceID();
        traceID = "SQLServerDriver:" + instanceID;
        loggingClassName = "com.microsoft.sqlserver.jdbc." + "SQLServerDriver:" + instanceID;
    }

    /**
     * Provides Helper function used to fix the case sensitivity, synonyms and remove unknown tokens from the
     * properties.
     */
    static Properties fixupProperties(Properties props) throws SQLServerException {
        // assert props !=null
        Properties fixedup = new Properties();
        Enumeration e = props.keys();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String newname = getNormalizedPropertyName(name, drLogger);

            if (null == newname) {
                newname = getPropertyOnlyName(name, drLogger);
            }

            if (null != newname) {
                String val = props.getProperty(name);
                if (null != val) {
                    // replace with the driver approved name
                    fixedup.setProperty(newname, val);
                } else if ("gsscredential".equalsIgnoreCase(newname) && (props.get(name) instanceof GSSCredential)) {
                    fixedup.put(newname, props.get(name));
                } else {
                    MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidpropertyValue"));
                    Object[] msgArgs = {name};
                    throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
                }
            }

        }
        return fixedup;
    }

    /**
     * Provides Helper function used to merge together the property set extracted from the url and the user supplied
     * property set passed in by the caller. This function is used by both SQLServerDriver.connect and
     * SQLServerDataSource.getConnectionInternal to centralize this property merging code.
     */
    static Properties mergeURLAndSuppliedProperties(Properties urlProps,
            Properties suppliedProperties) throws SQLServerException {
        if (null == suppliedProperties)
            return urlProps;
        if (suppliedProperties.isEmpty())
            return urlProps;
        Properties suppliedPropertiesFixed = fixupProperties(suppliedProperties);
        // Merge URL properties and supplied properties.
        for (SQLServerDriverPropertyInfo DRIVER_PROPERTY : DRIVER_PROPERTIES) {
            String sProp = DRIVER_PROPERTY.getName();
            String sPropVal = suppliedPropertiesFixed.getProperty(sProp); // supplied properties have precedence
            if (null != sPropVal) {
                // overwrite the property in urlprops if already exists. supp prop has more precedence
                urlProps.put(sProp, sPropVal);
            }
        }

        // Merge URL properties with property-only properties
        for (SQLServerDriverPropertyInfo aDRIVER_PROPERTIES_PROPERTY_ONLY : DRIVER_PROPERTIES_PROPERTY_ONLY) {
            String sProp = aDRIVER_PROPERTIES_PROPERTY_ONLY.getName();
            Object oPropVal = suppliedPropertiesFixed.get(sProp); // supplied properties have precedence
            if (null != oPropVal) {
                // overwrite the property in urlprops if already exists. supp prop has more precedence
                urlProps.put(sProp, oPropVal);
            }
        }

        return urlProps;
    }

    /**
     * Returns the normalized the property names.
     * 
     * @param name
     *        name to normalize
     * @param logger
     * @return the normalized property name
     */
    static String getNormalizedPropertyName(String name, Logger logger) {
        if (null == name)
            return name;

        for (String[] driverPropertiesSynonym : driverPropertiesSynonyms) {
            if (driverPropertiesSynonym[0].equalsIgnoreCase(name)) {
                return driverPropertiesSynonym[1];
            }
        }
        for (SQLServerDriverPropertyInfo DRIVER_PROPERTY : DRIVER_PROPERTIES) {
            if (DRIVER_PROPERTY.getName().equalsIgnoreCase(name)) {
                return DRIVER_PROPERTY.getName();
            }
        }

        if (logger.isLoggable(Level.FINER))
            logger.finer("Unknown property" + name);
        return null;
    }

    /**
     * Returns the property-only names that do not work with connection string.
     * 
     * @param name
     *        to normalize
     * @param logger
     * @return the normalized property name
     */
    static String getPropertyOnlyName(String name, Logger logger) {
        if (null == name)
            return name;

        for (SQLServerDriverPropertyInfo aDRIVER_PROPERTIES_PROPERTY_ONLY : DRIVER_PROPERTIES_PROPERTY_ONLY) {
            if (aDRIVER_PROPERTIES_PROPERTY_ONLY.getName().equalsIgnoreCase(name)) {
                return aDRIVER_PROPERTIES_PROPERTY_ONLY.getName();
            }
        }

        if (logger.isLoggable(Level.FINER))
            logger.finer("Unknown property" + name);
        return null;
    }

    @Override
    public java.sql.Connection connect(String Url, Properties suppliedProperties) throws SQLServerException {
        loggerExternal.entering(getClassNameLogging(), "connect", "Arguments not traced.");
        SQLServerConnection result = null;

        // Merge connectProperties (from URL) and supplied properties from user.
        Properties connectProperties = parseAndMergeProperties(Url, suppliedProperties);
        if (connectProperties != null) {
            if (Util.use43Wrapper()) {
                result = new SQLServerConnection43(toString());
            } else {
                result = new SQLServerConnection(toString());
            }
            result.connect(connectProperties, null);
        }
        loggerExternal.exiting(getClassNameLogging(), "connect", result);
        return result;
    }

    private Properties parseAndMergeProperties(String Url, Properties suppliedProperties) throws SQLServerException {
        if (Url == null) {
            throw new SQLServerException(null, SQLServerException.getErrString("R_nullConnection"), null, 0, false);
        }

        // Pull the URL properties into the connection properties
        Properties connectProperties = Util.parseUrl(Url, drLogger);
        if (null == connectProperties)
            return null; // If we are the wrong driver dont throw an exception

        String loginTimeoutProp = connectProperties.getProperty(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString());
        int dmLoginTimeout = DriverManager.getLoginTimeout();

        // Use Driver Manager's login timeout if it exceeds 0 and loginTimeout connection property is not provided.
        if (dmLoginTimeout > 0 && null == loginTimeoutProp) {
            connectProperties.setProperty(SQLServerDriverIntProperty.LOGIN_TIMEOUT.toString(),
                    String.valueOf(dmLoginTimeout));
        }

        // Merge connectProperties (from URL) and supplied properties from user.
        connectProperties = mergeURLAndSuppliedProperties(connectProperties, suppliedProperties);

        return connectProperties;
    }

    @Override
    public boolean acceptsURL(String url) throws SQLServerException {
        loggerExternal.entering(getClassNameLogging(), "acceptsURL", "Arguments not traced.");

        if (null == url) {
            throw new SQLServerException(null, SQLServerException.getErrString("R_nullConnection"), null, 0, false);
        }

        boolean result = false;
        try {
            result = (Util.parseUrl(url, drLogger) != null);
        } catch (SQLServerException e) {
            // ignore the exception from the parse URL failure, if we cant parse the URL we do not accept em
            result = false;
        }
        loggerExternal.exiting(getClassNameLogging(), "acceptsURL", result);
        return result;
    }

    @Override
    public DriverPropertyInfo[] getPropertyInfo(String Url, Properties Info) throws SQLServerException {
        loggerExternal.entering(getClassNameLogging(), "getPropertyInfo", "Arguments not traced.");

        Properties connProperties = parseAndMergeProperties(Url, Info);
        // This means we are not the right driver throw an exception.
        if (null == connProperties)
            throw new SQLServerException(null, SQLServerException.getErrString("R_invalidConnection"), null, 0, false);
        DriverPropertyInfo[] properties = getPropertyInfoFromProperties(connProperties);
        loggerExternal.exiting(getClassNameLogging(), "getPropertyInfo");

        return properties;
    }

    static final DriverPropertyInfo[] getPropertyInfoFromProperties(Properties props) {
        DriverPropertyInfo[] properties = new DriverPropertyInfo[DRIVER_PROPERTIES.length];

        for (int i = 0; i < DRIVER_PROPERTIES.length; i++)
            properties[i] = DRIVER_PROPERTIES[i].build(props);
        return properties;
    }

    @Override
    public int getMajorVersion() {
        loggerExternal.entering(getClassNameLogging(), "getMajorVersion");
        loggerExternal.exiting(getClassNameLogging(), "getMajorVersion", SQLJdbcVersion.major);
        return SQLJdbcVersion.major;
    }

    @Override
    public int getMinorVersion() {
        loggerExternal.entering(getClassNameLogging(), "getMinorVersion");
        loggerExternal.exiting(getClassNameLogging(), "getMinorVersion", SQLJdbcVersion.minor);
        return SQLJdbcVersion.minor;
    }

    @Override
    public Logger getParentLogger() {
        return parentLogger;
    }

    @Override
    public boolean jdbcCompliant() {
        loggerExternal.entering(getClassNameLogging(), "jdbcCompliant");
        loggerExternal.exiting(getClassNameLogging(), "jdbcCompliant", Boolean.TRUE);
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy