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 = (SqlConnection)owningConnection; bool applyTransientFaultHandling = sqlOwningConnection != null ? sqlOwningConnection._applyTransientFaultHandling : false; SqlConnectionString userOpt = null; if (userOptions != null) { userOpt = (SqlConnectionString)userOptions; } else if (sqlOwningConnection != null) { userOpt = (SqlConnectionString)(sqlOwningConnection.UserConnectionOptions); } if (sqlOwningConnection != null) { recoverySessionData = sqlOwningConnection._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, userInstance: true, setEnlistValue: false); 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, userInstance: false, setEnlistValue: null); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, poolGroupProviderInfo, redirectedUserInstance, userOpt, recoverySessionData, applyTransientFaultHandling: applyTransientFaultHandling); return(result); }
protected DbConnectionPoolKey(DbConnectionPoolKey key) { _connectionString = key.ConnectionString; }
protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool?pool, DbConnection?owningObject) { DbConnectionInternal result = new OleDbConnectionInternal((OleDbConnectionString)options, (OleDbConnection?)owningObject); return(result); }
override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) { return(CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection, userOptions: null)); }
internal DbConnectionInternal?CreatePooledConnection(DbConnectionPool pool, DbConnection?owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions?userOptions) { Debug.Assert(null != pool, "null pool?"); DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo !; DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) { PerformanceCounters.HardConnectsPerSecond.Increment(); newConnection.MakePooledConnection(pool); } return(newConnection); }
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 (sqlOwningConnection != null) { userOpt = (SqlConnectionString)(sqlOwningConnection.UserConnectionOptions); } if (sqlOwningConnection != null) { recoverySessionData = sqlOwningConnection._recoverySessionData; } if (opt.ContextConnection) { result = GetContextConnection(opt, poolGroupProviderInfo); } else { bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. // Used by notifications. if (opt.IntegratedSecurity || opt.UsesCertificate || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { 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 { // What about a failure - throw? YES! // BUG (VSTFDevDiv) 479687: Using TransactionScope with Linq2SQL against user instances fails with "connection has been broken" message // 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 */, false /* set Enlist = false */); sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", 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 */, null /* do not modify the Enlist value */); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData, key.ServerCertificateValidationCallback, key.ClientCertificateRetrievalCallback, pool, key.AccessToken, key.OriginalNetworkAddressInfo, applyTransientFaultHandling: applyTransientFaultHandling); } return(result); }
protected virtual DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool?pool, DbConnection?owningConnection, DbConnectionOptions?userOptions) { return(CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningConnection)); }
internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) { Debug.Assert(null != pool, "null pool?"); DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo; DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) { newConnection.MakePooledConnection(pool); } return(newConnection); }
internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) { Debug.Assert(null != pool, "null pool?"); DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo; DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) { PerformanceCounters.HardConnectsPerSecond.Increment(); newConnection.MakePooledConnection(pool); } Bid.Trace("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> %d#, Pooled database connection created.\n", ObjectID); return(newConnection); }
internal DbConnectionPoolGroup?GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions?poolOptions, ref DbConnectionOptions?userConnectionOptions) { if (ADP.IsEmpty(key.ConnectionString)) { return(null); } DbConnectionPoolGroup?connectionPoolGroup; Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions))) { // If we can't find an entry for the connection string in // our collection of pool entries, then we need to create a // new pool entry and add it to our collection. DbConnectionOptions connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions); if (null == connectionOptions) { throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing); } string expandedConnectionString = key.ConnectionString; if (null == userConnectionOptions) { // we only allow one expansion on the connection string userConnectionOptions = connectionOptions; expandedConnectionString = connectionOptions.Expand(); // if the expanded string is same instance (default implementation), the use the already created options if ((object)expandedConnectionString != (object)key.ConnectionString) { // CONSIDER: caching the original string to reduce future parsing DbConnectionPoolKey newKey = (DbConnectionPoolKey)((ICloneable)key).Clone(); newKey.ConnectionString = expandedConnectionString; return(GetConnectionPoolGroup(newKey, null, ref userConnectionOptions)); } } // We don't support connection pooling on Win9x; it lacks too many of the APIs we require. if ((null == poolOptions) && ADP.IsWindowsNT) { if (null != connectionPoolGroup) { // reusing existing pool option in case user originally used SetConnectionPoolOptions poolOptions = connectionPoolGroup.PoolGroupOptions; } else { // Note: may return null for non-pooled connections poolOptions = CreateConnectionPoolGroupOptions(connectionOptions); } } lock (this) { connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup)) { DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions !); newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions); // build new dictionary with space for new connection string Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> newConnectionPoolGroups = new Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup>(1 + connectionPoolGroups.Count); foreach (KeyValuePair <DbConnectionPoolKey, DbConnectionPoolGroup> entry in connectionPoolGroups) { newConnectionPoolGroups.Add(entry.Key, entry.Value); } // lock prevents race condition with PruneConnectionPoolGroups newConnectionPoolGroups.Add(key, newConnectionPoolGroup); PerformanceCounters.NumberOfActiveConnectionPoolGroups.Increment(); connectionPoolGroup = newConnectionPoolGroup; _connectionPoolGroups = newConnectionPoolGroups; } else { Debug.Assert(!connectionPoolGroup.IsDisabled, "Disabled pool entry discovered"); } } Debug.Assert(null != connectionPoolGroup, "how did we not create a pool entry?"); Debug.Assert(null != userConnectionOptions, "how did we not have user connection options?"); } else if (null == userConnectionOptions) { userConnectionOptions = connectionPoolGroup.ConnectionOptions; } return(connectionPoolGroup); }
internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) { Debug.Assert(null != pool, "null pool?"); DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = pool.PoolGroup.ProviderInfo; DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions); if (null != newConnection) { newConnection.MakePooledConnection(pool); } SqlClientEventSource.Log.TryTraceEvent("<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> {0}, Pooled database connection created.", ObjectID); return(newConnection); }
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; 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; } if (opt.ContextConnection) { result = GetContextConnection(opt, poolGroupProviderInfo); } else { bool redirectedUserInstance = false; DbConnectionPoolIdentity identity = null; // Pass DbConnectionPoolIdentity to SqlInternalConnectionTds if using integrated security. // Used by notifications. if (opt.IntegratedSecurity || opt.Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { 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 { // What about a failure - throw? YES! // SqlConnectionString sseopt = new SqlConnectionString(opt, opt.DataSource, true /* user instance=true */, false /* set Enlist = false */); sseConnection = new SqlInternalConnectionTds(identity, sseopt, key.Credential, null, "", null, false); // 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 */, null /* do not modify the Enlist value */); poolGroupProviderInfo = null; // null so we do not pass to constructor below... } result = new SqlInternalConnectionTds(identity, opt, key.Credential, poolGroupProviderInfo, "", null, redirectedUserInstance, userOpt, recoverySessionData, pool, key.AccessToken); } return(result); }
internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions) { if (string.IsNullOrEmpty(key.ConnectionString)) { return((DbConnectionPoolGroup)null); } DbConnectionPoolGroup connectionPoolGroup; Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions))) { // If we can't find an entry for the connection string in // our collection of pool entries, then we need to create a // new pool entry and add it to our collection. DbConnectionOptions connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions); if (null == connectionOptions) { throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing); } if (null == userConnectionOptions) { // we only allow one expansion on the connection string userConnectionOptions = connectionOptions; } // We don't support connection pooling on Win9x if (null == poolOptions) { if (null != connectionPoolGroup) { // reusing existing pool option in case user originally used SetConnectionPoolOptions poolOptions = connectionPoolGroup.PoolGroupOptions; } else { // Note: may return null for non-pooled connections poolOptions = CreateConnectionPoolGroupOptions(connectionOptions); } } lock (this) { connectionPoolGroups = _connectionPoolGroups; if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup)) { DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions); newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions); // build new dictionary with space for new connection string Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> newConnectionPoolGroups = new Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup>(1 + connectionPoolGroups.Count); foreach (KeyValuePair <DbConnectionPoolKey, DbConnectionPoolGroup> entry in connectionPoolGroups) { newConnectionPoolGroups.Add(entry.Key, entry.Value); } // lock prevents race condition with PruneConnectionPoolGroups newConnectionPoolGroups.Add(key, newConnectionPoolGroup); connectionPoolGroup = newConnectionPoolGroup; _connectionPoolGroups = newConnectionPoolGroups; } else { Debug.Assert(!connectionPoolGroup.IsDisabled, "Disabled pool entry discovered"); } } Debug.Assert(null != connectionPoolGroup, "how did we not create a pool entry?"); Debug.Assert(null != userConnectionOptions, "how did we not have user connection options?"); } else if (null == userConnectionOptions) { userConnectionOptions = connectionPoolGroup.ConnectionOptions; } return(connectionPoolGroup); }
private void ConnectionString_Set(string value) { DbConnectionPoolKey key = new DbConnectionPoolKey(value); ConnectionString_Set(key); }
protected abstract DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool?pool, DbConnection?owningConnection);
protected override DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) { DbConnectionInternal result = new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString); return(result); }