private async Task ExecuteImpl(bool autoCommit, AsyncWrappingCommonArgs async) { if ((_statements?.Count ?? 0) == 0) { throw new InvalidOperationException("There are no commands for execution."); } _shouldClose = false; foreach (var statement in Statements) { if (!(statement.StatementType == SqlStatementType.Connect || statement.StatementType == SqlStatementType.CreateDatabase || statement.StatementType == SqlStatementType.Disconnect || statement.StatementType == SqlStatementType.DropDatabase || statement.StatementType == SqlStatementType.SetAutoDDL || statement.StatementType == SqlStatementType.SetDatabase || statement.StatementType == SqlStatementType.SetNames || statement.StatementType == SqlStatementType.SetSQLDialect)) { await ProvideCommand(async).ConfigureAwait(false); _sqlCommand.CommandText = statement.Text; if (_sqlTransaction == null && !(statement.StatementType == SqlStatementType.Commit || statement.StatementType == SqlStatementType.Rollback)) { _sqlTransaction = await _sqlConnection.BeginTransactionImpl(FbTransaction.DefaultIsolationLevel, null, async).ConfigureAwait(false); } _sqlCommand.Transaction = _sqlTransaction; } try { switch (statement.StatementType) { case SqlStatementType.AlterCharacterSet: case SqlStatementType.AlterDatabase: case SqlStatementType.AlterDomain: case SqlStatementType.AlterException: case SqlStatementType.AlterFunction: case SqlStatementType.AlterIndex: case SqlStatementType.AlterPackage: case SqlStatementType.AlterProcedure: case SqlStatementType.AlterRole: case SqlStatementType.AlterSequence: case SqlStatementType.AlterTable: case SqlStatementType.AlterTrigger: case SqlStatementType.AlterView: case SqlStatementType.CommentOn: case SqlStatementType.CreateCollation: case SqlStatementType.CreateDomain: case SqlStatementType.CreateException: case SqlStatementType.CreateFunction: case SqlStatementType.CreateGenerator: case SqlStatementType.CreateIndex: case SqlStatementType.CreatePackage: case SqlStatementType.CreatePackageBody: case SqlStatementType.CreateProcedure: case SqlStatementType.CreateRole: case SqlStatementType.CreateSequence: case SqlStatementType.CreateShadow: case SqlStatementType.CreateTable: case SqlStatementType.CreateTrigger: case SqlStatementType.CreateView: case SqlStatementType.DeclareCursor: case SqlStatementType.DeclareExternalFunction: case SqlStatementType.DeclareFilter: case SqlStatementType.DeclareStatement: case SqlStatementType.DeclareTable: case SqlStatementType.Delete: case SqlStatementType.DropCollation: case SqlStatementType.DropDomain: case SqlStatementType.DropException: case SqlStatementType.DropExternalFunction: case SqlStatementType.DropFunction: case SqlStatementType.DropFilter: case SqlStatementType.DropGenerator: case SqlStatementType.DropIndex: case SqlStatementType.DropPackage: case SqlStatementType.DropPackageBody: case SqlStatementType.DropProcedure: case SqlStatementType.DropSequence: case SqlStatementType.DropRole: case SqlStatementType.DropShadow: case SqlStatementType.DropTable: case SqlStatementType.DropTrigger: case SqlStatementType.DropView: case SqlStatementType.EventInit: case SqlStatementType.EventWait: case SqlStatementType.Execute: case SqlStatementType.ExecuteImmediate: case SqlStatementType.ExecuteProcedure: case SqlStatementType.Grant: case SqlStatementType.Insert: case SqlStatementType.InsertCursor: case SqlStatementType.Merge: case SqlStatementType.Open: case SqlStatementType.Prepare: case SqlStatementType.Revoke: case SqlStatementType.RecreateFunction: case SqlStatementType.RecreatePackage: case SqlStatementType.RecreatePackageBody: case SqlStatementType.RecreateProcedure: case SqlStatementType.RecreateTable: case SqlStatementType.RecreateTrigger: case SqlStatementType.RecreateView: case SqlStatementType.SetGenerator: case SqlStatementType.Update: case SqlStatementType.Whenever: OnCommandExecuting(_sqlCommand, statement.StatementType); var rowsAffected = await ExecuteCommand(autoCommit, async).ConfigureAwait(false); _requiresNewConnection = false; OnCommandExecuted(null, statement.Text, statement.StatementType, rowsAffected); break; case SqlStatementType.ExecuteBlock: case SqlStatementType.Select: (await ProvideCommand(async).ConfigureAwait(false)).CommandText = statement.Text; OnCommandExecuting(_sqlCommand, statement.StatementType); var dataReader = await _sqlCommand.ExecuteReaderImpl(CommandBehavior.Default, async).ConfigureAwait(false); try { _requiresNewConnection = false; OnCommandExecuted(dataReader, statement.Text, statement.StatementType, -1); } finally { #if NET48 || NETSTANDARD2_0 dataReader.Dispose(); #else await async.AsyncSyncCallNoCancellation(dataReader.DisposeAsync, dataReader.Dispose).ConfigureAwait(false); #endif } break; case SqlStatementType.Commit: OnCommandExecuting(null, statement.StatementType); await CommitTransaction(async).ConfigureAwait(false); OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.Rollback: OnCommandExecuting(null, statement.StatementType); await RollbackTransaction(async).ConfigureAwait(false); OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.CreateDatabase: OnCommandExecuting(null, statement.StatementType); await CreateDatabase(statement.CleanText, async).ConfigureAwait(false); _requiresNewConnection = false; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.DropDatabase: OnCommandExecuting(null, statement.StatementType); await async.AsyncSyncCall(FbConnection.DropDatabaseAsync, FbConnection.DropDatabase, _connectionString.ToString()).ConfigureAwait(false); _requiresNewConnection = true; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.Connect: OnCommandExecuting(null, statement.StatementType); await ConnectToDatabase(statement.CleanText, async).ConfigureAwait(false); _requiresNewConnection = false; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.Disconnect: OnCommandExecuting(null, statement.StatementType); await _sqlConnection.CloseImpl(async).ConfigureAwait(false); FbConnection.ClearPool(_sqlConnection); _requiresNewConnection = false; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.SetAutoDDL: OnCommandExecuting(null, statement.StatementType); SetAutoDdl(statement.CleanText, ref autoCommit); _requiresNewConnection = false; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.SetNames: OnCommandExecuting(null, statement.StatementType); SetNames(statement.CleanText); _requiresNewConnection = true; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.SetSQLDialect: OnCommandExecuting(null, statement.StatementType); SetSqlDialect(statement.CleanText); _requiresNewConnection = true; OnCommandExecuted(null, statement.Text, statement.StatementType, -1); break; case SqlStatementType.Fetch: case SqlStatementType.Describe: break; case SqlStatementType.SetDatabase: case SqlStatementType.SetStatistics: case SqlStatementType.SetTransaction: case SqlStatementType.ShowSQLDialect: throw new NotImplementedException(); } } catch (Exception ex) { await DisposeCommand(async).ConfigureAwait(false); await RollbackTransaction(async).ConfigureAwait(false); await CloseConnection(async).ConfigureAwait(false); throw new FbException(string.Format("An exception was thrown when executing command: {1}.{0}Batch execution aborted.{0}The returned message was: {2}.", Environment.NewLine, statement.Text, ex.Message), ex); } } await DisposeCommand(async).ConfigureAwait(false); await CommitTransaction(async).ConfigureAwait(false); await CloseConnection(async).ConfigureAwait(false); }