override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions(DbConnectionOptions connectionOptions)
        {
            SqlConnectionString opt = (SqlConnectionString)connectionOptions;

            DbConnectionPoolGroupOptions poolingOptions = null;

            if (opt.Pooling)
            {    // never pool context connections.
                int connectionTimeout = opt.ConnectTimeout;

                if ((0 < connectionTimeout) && (connectionTimeout < Int32.MaxValue / 1000))
                {
                    connectionTimeout *= 1000;
                }
                else if (connectionTimeout >= Int32.MaxValue / 1000)
                {
                    connectionTimeout = Int32.MaxValue;
                }

                poolingOptions = new DbConnectionPoolGroupOptions(
                    opt.IntegratedSecurity,
                    opt.MinPoolSize,
                    opt.MaxPoolSize,
                    connectionTimeout,
                    opt.LoadBalanceTimeout
                    );
            }
            return(poolingOptions);
        }
        protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous)
        {
            Debug.Assert(!ADP.IsEmpty(connectionString), "empty connectionString");
            SqlConnectionString result = new SqlConnectionString(connectionString);

            return(result);
        }
        // This c-tor is used to create SSE and user instance connection strings when user instance is set to true
        // BUG (VSTFDevDiv) 479687: Using TransactionScope with Linq2SQL against user instances fails with "connection has been broken" message
        internal SqlConnectionString(SqlConnectionString connectionOptions, string dataSource, bool userInstance) : base(connectionOptions)
        {
            _integratedSecurity = connectionOptions._integratedSecurity;
            _encrypt            = connectionOptions._encrypt;

            _mars = connectionOptions._mars;
            _persistSecurityInfo = connectionOptions._persistSecurityInfo;
            _pooling             = connectionOptions._pooling;
            _replication         = connectionOptions._replication;
            _userInstance        = userInstance;
            _connectTimeout      = connectionOptions._connectTimeout;
            _loadBalanceTimeout  = connectionOptions._loadBalanceTimeout;
            _maxPoolSize         = connectionOptions._maxPoolSize;
            _minPoolSize         = connectionOptions._minPoolSize;
            _multiSubnetFailover = connectionOptions._multiSubnetFailover;
            _packetSize          = connectionOptions._packetSize;
            _applicationName     = connectionOptions._applicationName;
            _attachDBFileName    = connectionOptions._attachDBFileName;
            _currentLanguage     = connectionOptions._currentLanguage;
            _dataSource          = dataSource;
            _localDBInstance     = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource);
            _failoverPartner     = connectionOptions._failoverPartner;
            _initialCatalog      = connectionOptions._initialCatalog;
            _password            = connectionOptions._password;
            _userID               = connectionOptions._userID;
            _workstationId        = connectionOptions._workstationId;
            _typeSystemVersion    = connectionOptions._typeSystemVersion;
            _applicationIntent    = connectionOptions._applicationIntent;
            _connectRetryCount    = connectionOptions._connectRetryCount;
            _connectRetryInterval = connectionOptions._connectRetryInterval;

            ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source);
        }
        // This method will be called once connection string is set or changed.
        private void CacheConnectionStringProperties()
        {
            SqlConnectionString connString = ConnectionOptions as SqlConnectionString;

            if (connString != null)
            {
                _connectRetryCount = connString.ConnectRetryCount;
            }
        }
        internal SqlConnectionPoolGroupProviderInfo(SqlConnectionString connectionOptions)
        {
            // This is for the case where the user specified the failover partner
            // in the connection string and we have not yet connected to get the
            // env change.
            _failoverPartner = connectionOptions.FailoverPartner;

            if (ADP.IsEmpty(_failoverPartner))
            {
                _failoverPartner = null;
            }
        }
        internal static SqlConnectionString FindSqlConnectionOptions(SqlConnectionPoolKey key)
        {
            SqlConnectionString connectionOptions = (SqlConnectionString)SingletonInstance.FindConnectionOptions(key);

            if (null == connectionOptions)
            {
                connectionOptions = new SqlConnectionString(key.ConnectionString);
            }
            if (connectionOptions.IsEmpty)
            {
                throw ADP.NoConnectionString();
            }
            return(connectionOptions);
        }
        private bool TryOpen(TaskCompletionSource <DbConnectionInternal> retry)
        {
            SqlConnectionString connectionOptions = (SqlConnectionString)ConnectionOptions;

            _applyTransientFaultHandling = (retry == null && connectionOptions != null && connectionOptions.ConnectRetryCount > 0);

            if (ForceNewConnection)
            {
                if (!InnerConnection.TryReplaceConnection(this, ConnectionFactory, retry, UserConnectionOptions))
                {
                    return(false);
                }
            }
            else
            {
                if (!InnerConnection.TryOpenConnection(this, ConnectionFactory, retry, UserConnectionOptions))
                {
                    return(false);
                }
            }
            // does not require GC.KeepAlive(this) because of OnStateChange

            var tdsInnerConnection = (InnerConnection as SqlInternalConnectionTds);

            Debug.Assert(tdsInnerConnection.Parser != null, "Where's the parser?");

            if (!tdsInnerConnection.ConnectionOptions.Pooling)
            {
                // For non-pooled connections, we need to make sure that the finalizer does actually run to avoid leaking SNI handles
                GC.ReRegisterForFinalize(this);
            }

            if (StatisticsEnabled)
            {
                ADP.TimerCurrent(out _statistics._openTimestamp);
                tdsInnerConnection.Parser.Statistics = _statistics;
            }
            else
            {
                tdsInnerConnection.Parser.Statistics = null;
                _statistics = null; // in case of previous Open/Close/reset_CollectStats sequence
            }

            return(true);
        }
        override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
        {
            SqlConnectionString   opt    = (SqlConnectionString)options;
            SqlConnectionPoolKey  key    = (SqlConnectionPoolKey)poolKey;
            SqlInternalConnection result = null;
            SessionData           recoverySessionData = null;

            SqlConnection sqlOwningConnection         = owningConnection as SqlConnection;
            bool          applyTransientFaultHandling = sqlOwningConnection != null ? sqlOwningConnection._applyTransientFaultHandling : false;

            SqlConnectionString userOpt = null;

            if (userOptions != null)
            {
                userOpt = (SqlConnectionString)userOptions;
            }
            else if (owningConnection != null)
            {
                userOpt = (SqlConnectionString)(((SqlConnection)owningConnection).UserConnectionOptions);
            }

            if (owningConnection != null)
            {
                recoverySessionData = ((SqlConnection)owningConnection)._recoverySessionData;
            }

            bool redirectedUserInstance       = false;
            DbConnectionPoolIdentity identity = null;

            // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security.
            // Used by notifications.
            if (opt.IntegratedSecurity)
            {
                if (pool != null)
                {
                    identity = pool.Identity;
                }
                else
                {
                    identity = DbConnectionPoolIdentity.GetCurrent();
                }
            }

            // FOLLOWING IF BLOCK IS ENTIRELY FOR SSE USER INSTANCES
            // If "user instance=true" is in the connection string, we're using SSE user instances
            if (opt.UserInstance)
            {
                // opt.DataSource is used to create the SSE connection
                redirectedUserInstance = true;
                string instanceName;

                if ((null == pool) ||
                    (null != pool && pool.Count <= 0))
                { // Non-pooled or pooled and no connections in the pool.
                    SqlInternalConnectionTds sseConnection = null;
                    try
                    {
                        // We throw an exception in case of a failure
                        // NOTE: Cloning connection option opt to set 'UserInstance=True' and 'Enlist=False'
                        //       This first connection is established to SqlExpress to get the instance name
                        //       of the UserInstance.
                        SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */);
                        sseConnection = new SqlInternalConnectionTds(identity, sseopt, null, false, applyTransientFaultHandling: applyTransientFaultHandling);
                        // NOTE: Retrieve <UserInstanceName> here. This user instance name will be used below to connect to the Sql Express User Instance.
                        instanceName = sseConnection.InstanceName;

                        if (!instanceName.StartsWith("\\\\.\\", StringComparison.Ordinal))
                        {
                            throw SQL.NonLocalSSEInstance();
                        }

                        if (null != pool)
                        { // Pooled connection - cache result
                            SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo;
                            // No lock since we are already in creation mutex
                            providerInfo.InstanceName = instanceName;
                        }
                    }
                    finally
                    {
                        if (null != sseConnection)
                        {
                            sseConnection.Dispose();
                        }
                    }
                }
                else
                { // Cached info from pool.
                    SqlConnectionPoolProviderInfo providerInfo = (SqlConnectionPoolProviderInfo)pool.ProviderInfo;
                    // No lock since we are already in creation mutex
                    instanceName = providerInfo.InstanceName;
                }

                // NOTE: Here connection option opt is cloned to set 'instanceName=<UserInstanceName>' that was
                //       retrieved from the previous SSE connection. For this UserInstance connection 'Enlist=True'.
                // options immutable - stored in global hash - don't modify
                opt = new SqlConnectionString(opt, instanceName, false /* user instance=false */);
                poolGroupProviderInfo = null; // null so we do not pass to constructor below...
            }
            result = new SqlInternalConnectionTds(identity, opt, poolGroupProviderInfo, redirectedUserInstance, userOpt, recoverySessionData, applyTransientFaultHandling: applyTransientFaultHandling);
            return(result);
        }
        internal void FailoverCheck(SqlInternalConnection connection, bool actualUseFailoverPartner, SqlConnectionString userConnectionOptions, string actualFailoverPartner)
        {
            if (UseFailoverPartner != actualUseFailoverPartner)
            {
                base.PoolGroup.Clear();
                _useFailoverPartner = actualUseFailoverPartner;
            }
            // Only construct a new permission set when we're connecting to the
            // primary data source, not the failover partner.
            if (!_useFailoverPartner && _failoverPartner != actualFailoverPartner)
            {
                // NOTE: we optimisitically generate the permission set to keep
                //       lock short, but we only do this when we get a new
                //       failover partner.

                lock (this)
                {
                    if (_failoverPartner != actualFailoverPartner)
                    {
                        _failoverPartner = actualFailoverPartner;
                    }
                }
            }
        }
Exemple #10
0
 internal SqlInternalConnection(SqlConnectionString connectionOptions) : base()
 {
     Debug.Assert(null != connectionOptions, "null connectionOptions?");
     _connectionOptions = connectionOptions;
 }