internal void PermissionDemand() { Debug.Assert(DbConnectionClosedConnecting.SingletonInstance == _innerConnection, "not connecting"); Microsoft.Data.ProviderBase.DbConnectionPoolGroup poolGroup = PoolGroup; DbConnectionOptions connectionOptions = ((null != poolGroup) ? poolGroup.ConnectionOptions : null); if ((null == connectionOptions) || connectionOptions.IsEmpty) { throw ADP.NoConnectionString(); } DbConnectionOptions userConnectionOptions = UserConnectionOptions; Debug.Assert(null != userConnectionOptions, "null UserConnectionOptions"); userConnectionOptions.DemandPermission(); }
private void ConnectionString_Set(DbConnectionPoolKey key) { DbConnectionOptions connectionOptions = null; Microsoft.Data.ProviderBase.DbConnectionPoolGroup poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); DbConnectionInternal connectionInternal = InnerConnection; bool flag = connectionInternal.AllowSetConnectionString; if (flag) { //try { // NOTE: There's a race condition with multiple threads changing // ConnectionString and any thread throws an exception // Closed->Busy: prevent Open during set_ConnectionString flag = SetInnerConnectionFrom(DbConnectionClosedBusy.SingletonInstance, connectionInternal); if (flag) { _userConnectionOptions = connectionOptions; _poolGroup = poolGroup; _innerConnection = DbConnectionClosedNeverOpened.SingletonInstance; } //} //catch { // // recover from exceptions to avoid sticking in busy state // SetInnerConnectionFrom(connectionInternal, DbConnectionClosedBusy.SingletonInstance); // throw; //} } if (!flag) { throw ADP.OpenConnectionPropertySet(ADP.ConnectionString, connectionInternal.State); } if (SqlClientEventSource.Log.IsTraceEnabled()) { SqlClientEventSource.Log.TraceEvent("<prov.DbConnectionHelper.ConnectionString_Set|API> {0}, '{1}'", ObjectID, connectionOptions.UsersConnectionStringForTrace()); } }
private Task <DbConnectionInternal> CreateReplaceConnectionContinuation(Task <DbConnectionInternal> task, DbConnection owningConnection, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionPoolGroup poolGroup, CancellationTokenSource cancellationTokenSource) { return(task.ContinueWith( (_) => { Transaction originalTransaction = ADP.GetCurrentTransaction(); try { ADP.SetCurrentTransaction(retry.Task.AsyncState as Transaction); var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions); if ((oldConnection != null) && (oldConnection.State == ConnectionState.Open)) { oldConnection.PrepareForReplaceConnection(); oldConnection.Dispose(); } return newConnection; } finally { ADP.SetCurrentTransaction(originalTransaction); } }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default )); }
abstract internal void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup);
internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions) { if (ADP.IsEmpty(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); } 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), then 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 CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) { Debug.Assert(null != owningConnection, "null owningConnection?"); Debug.Assert(null != poolGroup, "null poolGroup?"); DbConnectionOptions connectionOptions = poolGroup.ConnectionOptions; DbConnectionPoolGroupProviderInfo poolGroupProviderInfo = poolGroup.ProviderInfo; DbConnectionPoolKey poolKey = poolGroup.PoolKey; DbConnectionInternal newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions); if (null != newConnection) { PerformanceCounters.HardConnectsPerSecond.Increment(); newConnection.MakeNonPooledObject(owningConnection, PerformanceCounters); } SqlClientEventSource.Log.TryTraceEvent("<prov.DbConnectionFactory.CreateNonPooledConnection|RES|CPOOL> {0}, Non-pooled database connection created.", ObjectID); return(newConnection); }
override protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) { throw ADP.ClosedConnectionError(); }