| File: System\Data\Common\DbConnection.cs | Web Access |
| Project: src\runtime\src\libraries\System.Data.Common\src\System.Data.Common.csproj (System.Data.Common) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; namespace System.Data.Common { public abstract class DbConnection : Component, IDbConnection, IAsyncDisposable { #pragma warning disable 649 // ignore unassigned field warning internal bool _suppressStateChangeForReconnection; #pragma warning restore 649 protected DbConnection() : base() { } [DefaultValue("")] [SettingsBindableAttribute(true)] [RefreshProperties(RefreshProperties.All)] #pragma warning disable 618 // ignore obsolete warning about RecommendedAsConfigurable to use SettingsBindableAttribute [RecommendedAsConfigurable(true)] #pragma warning restore 618 [AllowNull] public abstract string ConnectionString { get; set; } public virtual int ConnectionTimeout => ADP.DefaultConnectionTimeout; public abstract string Database { get; } public abstract string DataSource { get; } /// <summary> /// The associated provider factory for derived class. /// </summary> protected virtual DbProviderFactory? DbProviderFactory => null; internal DbProviderFactory? ProviderFactory => DbProviderFactory; [Browsable(false)] public abstract string ServerVersion { get; } [Browsable(false)] public abstract ConnectionState State { get; } public virtual event StateChangeEventHandler? StateChange; protected abstract DbTransaction BeginDbTransaction(IsolationLevel isolationLevel); public DbTransaction BeginTransaction() => BeginDbTransaction(IsolationLevel.Unspecified); public DbTransaction BeginTransaction(IsolationLevel isolationLevel) { return BeginDbTransaction(isolationLevel); } IDbTransaction IDbConnection.BeginTransaction() => BeginDbTransaction(IsolationLevel.Unspecified); IDbTransaction IDbConnection.BeginTransaction(IsolationLevel isolationLevel) => BeginDbTransaction(isolationLevel); protected virtual ValueTask<DbTransaction> BeginDbTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return ValueTask.FromCanceled<DbTransaction>(cancellationToken); } try { return new ValueTask<DbTransaction>(BeginDbTransaction(isolationLevel)); } catch (Exception e) { return ValueTask.FromException<DbTransaction>(e); } } public ValueTask<DbTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default) => BeginDbTransactionAsync(IsolationLevel.Unspecified, cancellationToken); public ValueTask<DbTransaction> BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default) => BeginDbTransactionAsync(isolationLevel, cancellationToken); public abstract void Close(); public virtual Task CloseAsync() { try { Close(); return Task.CompletedTask; } catch (Exception e) { return Task.FromException(e); } } public virtual ValueTask DisposeAsync() { Dispose(); return default; } public abstract void ChangeDatabase(string databaseName); public virtual Task ChangeDatabaseAsync(string databaseName, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled(cancellationToken); } try { ChangeDatabase(databaseName); return Task.CompletedTask; } catch (Exception e) { return Task.FromException(e); } } public virtual bool CanCreateBatch => false; public DbBatch CreateBatch() => CreateDbBatch(); protected virtual DbBatch CreateDbBatch() => throw new NotSupportedException(); public DbCommand CreateCommand() => CreateDbCommand(); IDbCommand IDbConnection.CreateCommand() => CreateDbCommand(); protected abstract DbCommand CreateDbCommand(); public virtual void EnlistTransaction(System.Transactions.Transaction? transaction) { throw ADP.NotSupported(); } // these need to be here so that GetSchema is visible when programming to a dbConnection object. // they are overridden by the real implementations in DbConnectionBase /// <summary> /// Returns schema information for the data source of this <see cref="DbConnection" />. /// </summary> /// <returns>A <see cref="DataTable" /> that contains schema information.</returns> /// <remarks> /// If the connection is associated with a transaction, executing <see cref="GetSchema()" /> calls may cause /// some providers to throw an exception. /// </remarks> public virtual DataTable GetSchema() { throw ADP.NotSupported(); } /// <summary> /// Returns schema information for the data source of this <see cref="DbConnection" /> using the specified /// string for the schema name. /// </summary> /// <param name="collectionName">Specifies the name of the schema to return.</param> /// <returns>A <see cref="DataTable" /> that contains schema information.</returns> /// <exception cref="ArgumentException"> /// <paramref name="collectionName" /> is specified as <see langword="null" />. /// </exception> /// <remarks> /// If the connection is associated with a transaction, executing <see cref="GetSchema(string)" /> calls may cause /// some providers to throw an exception. /// </remarks> public virtual DataTable GetSchema(string collectionName) { throw ADP.NotSupported(); } /// <summary> /// Returns schema information for the data source of this <see cref="DbConnection" /> using the specified /// string for the schema name and the specified string array for the restriction values. /// </summary> /// <param name="collectionName">Specifies the name of the schema to return.</param> /// <param name="restrictionValues">Specifies a set of restriction values for the requested schema.</param> /// <returns>A <see cref="DataTable" /> that contains schema information.</returns> /// <exception cref="ArgumentException"> /// <paramref name="collectionName" /> is specified as <see langword="null" />. /// </exception> /// <remarks> /// <para> /// The <paramref name="restrictionValues" /> parameter can supply n depth of values, which are specified by the /// restrictions collection for a specific collection. In order to set values on a given restriction, and not /// set the values of other restrictions, you need to set the preceding restrictions to null and then put the /// appropriate value in for the restriction that you would like to specify a value for. /// </para> /// <para> /// An example of this is the "Tables" collection. If the "Tables" collection has three restrictions (database, /// owner, and table name) and you want to get back only the tables associated with the owner "Carl", you must /// pass in the following values at least: null, "Carl". If a restriction value is not passed in, the default /// values are used for that restriction. This is the same mapping as passing in null, which is different from /// passing in an empty string for the parameter value. In that case, the empty string ("") is considered to be /// the value for the specified parameter. /// </para> /// <para> /// If the connection is associated with a transaction, executing <see cref="GetSchema(string, string[])" /> /// calls may cause some providers to throw an exception. /// </para> /// </remarks> public virtual DataTable GetSchema(string collectionName, string?[] restrictionValues) { throw ADP.NotSupported(); } /// <summary> /// This is the asynchronous version of <see cref="GetSchema()" />. /// Providers should override with an appropriate implementation. /// The cancellation token can optionally be honored. /// The default implementation invokes the synchronous <see cref="GetSchema()" /> call and returns a completed /// task. /// The default implementation will return a cancelled task if passed an already cancelled cancellationToken. /// Exceptions thrown by <see cref="GetSchema()" /> will be communicated via the returned Task Exception /// property. /// </summary> /// <param name="cancellationToken">The cancellation instruction.</param> /// <returns>A task representing the asynchronous operation.</returns> public virtual Task<DataTable> GetSchemaAsync(CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled<DataTable>(cancellationToken); } try { return Task.FromResult(GetSchema()); } catch (Exception e) { return Task.FromException<DataTable>(e); } } /// <summary> /// This is the asynchronous version of <see cref="GetSchema(string)" />. /// Providers should override with an appropriate implementation. /// The cancellation token can optionally be honored. /// The default implementation invokes the synchronous <see cref="GetSchema(string)" /> call and returns a /// completed task. /// The default implementation will return a cancelled task if passed an already cancelled cancellationToken. /// Exceptions thrown by <see cref="GetSchema(string)" /> will be communicated via the returned Task Exception /// property. /// </summary> /// <param name="collectionName">Specifies the name of the schema to return.</param> /// <param name="cancellationToken">The cancellation instruction.</param> /// <returns>A task representing the asynchronous operation.</returns> public virtual Task<DataTable> GetSchemaAsync( string collectionName, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled<DataTable>(cancellationToken); } try { return Task.FromResult(GetSchema(collectionName)); } catch (Exception e) { return Task.FromException<DataTable>(e); } } /// <summary> /// This is the asynchronous version of <see cref="GetSchema(string, string[])" />. /// Providers should override with an appropriate implementation. /// The cancellation token can optionally be honored. /// The default implementation invokes the synchronous <see cref="GetSchema(string, string[])" /> call and /// returns a completed task. /// The default implementation will return a cancelled task if passed an already cancelled cancellationToken. /// Exceptions thrown by <see cref="GetSchema(string, string[])" /> will be communicated via the returned Task /// Exception property. /// </summary> /// <param name="collectionName">Specifies the name of the schema to return.</param> /// <param name="restrictionValues">Specifies a set of restriction values for the requested schema.</param> /// <param name="cancellationToken">The cancellation instruction.</param> /// <returns>A task representing the asynchronous operation.</returns> public virtual Task<DataTable> GetSchemaAsync(string collectionName, string?[] restrictionValues, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled<DataTable>(cancellationToken); } try { return Task.FromResult(GetSchema(collectionName, restrictionValues)); } catch (Exception e) { return Task.FromException<DataTable>(e); } } protected virtual void OnStateChange(StateChangeEventArgs stateChange) { if (_suppressStateChangeForReconnection) { return; } StateChange?.Invoke(this, stateChange); } public abstract void Open(); public Task OpenAsync() => OpenAsync(CancellationToken.None); public virtual Task OpenAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled(cancellationToken); } else { try { Open(); return Task.CompletedTask; } catch (Exception e) { return Task.FromException(e); } } } } }