Beispiel #1
0
        public override Task <StatementExecutionBatchResult> ExecuteStatementAsync(StatementBatchExecutionModel executionModel, CancellationToken cancellationToken)
        {
            var result =
                new StatementExecutionBatchResult
            {
                ExecutionModel   = executionModel,
                DatabaseOutput   = "Test database output",
                StatementResults = executionModel.Statements.Select(BuildStatementExecutionResult).ToArray()
            };

            return(Task.FromResult(result));
        }
Beispiel #2
0
		public OracleDebuggerSession(OracleConnectionAdapter connectionAdapter, OracleCommand debuggedCommand, StatementExecutionBatchResult executionResult)
		{
			_connectionAdapter = connectionAdapter;
			ExecutionResult = executionResult;
			DebuggedCommand = debuggedCommand;
			var debuggedConnection = DebuggedCommand.Connection;
			_debuggedSessionCommand = debuggedConnection.CreateCommand();
			_debuggedSessionCommand.BindByName = true;
			_debuggerConnection = (OracleConnection)debuggedConnection.Clone();
			_debuggerSessionCommand = _debuggerConnection.CreateCommand();
			_debuggerSessionCommand.BindByName = true;

			_sources.Add(PlSqlBlockTitle, debuggedCommand.CommandText.Trim());
		}
Beispiel #3
0
        public OracleDebuggerSession(OracleConnectionAdapter connectionAdapter, OracleCommand debuggedCommand, StatementExecutionBatchResult executionResult)
        {
            _connectionAdapter = connectionAdapter;
            ExecutionResult    = executionResult;
            DebuggedCommand    = debuggedCommand;
            var debuggedConnection = DebuggedCommand.Connection;

            _debuggedSessionCommand            = debuggedConnection.CreateCommand();
            _debuggedSessionCommand.BindByName = true;
            _debuggerConnection                = (OracleConnection)debuggedConnection.Clone();
            _debuggerSessionCommand            = _debuggerConnection.CreateCommand();
            _debuggerSessionCommand.BindByName = true;

            _sources.Add(PlSqlBlockTitle, debuggedCommand.CommandText.Trim());
        }
Beispiel #4
0
		internal async Task FinalizeBatchExecution(StatementExecutionBatchResult batchResult, CancellationToken cancellationToken)
		{
			_userTransactionInfo = null;

			var exception = await ResolveExecutionPlanIdentifiersAndTransactionStatus(cancellationToken);
			if (exception != null)
			{
				await SafeResolveTransactionStatus(cancellationToken);
			}

			batchResult.DatabaseOutput = await RetrieveDatabaseOutput(cancellationToken);
		}
Beispiel #5
0
		private async Task<StatementExecutionBatchResult> ExecuteUserStatementAsync(StatementBatchExecutionModel batchExecutionModel, bool isReferenceConstraintNavigation, CancellationToken cancellationToken)
		{
			if (batchExecutionModel.Statements == null || batchExecutionModel.Statements.Count == 0)
			{
				throw new ArgumentException("An execution batch must contain at least one statement. ", nameof(batchExecutionModel));
			}

			_isExecuting = true;
			_userCommandHasCompilationErrors = false;

			var batchResult = new StatementExecutionBatchResult { ExecutionModel = batchExecutionModel };
			var statementResults = new List<StatementExecutionResult>();
			StatementExecutionResult currentStatementResult = null;

			try
			{
				SetOracleGlobalization();

				await EnsureUserConnectionOpen(cancellationToken);

				await EnsureDatabaseOutput(cancellationToken);

				if (batchExecutionModel.GatherExecutionStatistics)
				{
					_executionStatisticsDataProvider = new SessionExecutionStatisticsDataProvider(_databaseModel.StatisticsKeys, _userSessionIdentifier.Value.SessionId);
					await _databaseModel.UpdateModelAsync(true, cancellationToken, _executionStatisticsDataProvider.SessionBeginExecutionStatisticsDataProvider);
				}

				_userConnection.ActionName = "User command";

				foreach (var executionModel in batchExecutionModel.Statements)
				{
					currentStatementResult = new StatementExecutionResult { StatementModel = executionModel };
					statementResults.Add(currentStatementResult);

					if (_userTransaction == null)
					{
						var isolationLevel = executionModel.Statement?.RootNode[NonTerminals.Statement, NonTerminals.SetTransactionStatement, NonTerminals.TransactionModeOrIsolationLevelOrRollbackSegment, NonTerminals.SerializableOrReadCommitted, Terminals.Serializable] != null
							? IsolationLevel.Serializable
							: IsolationLevel.ReadCommitted;

						_userTransaction = _userConnection.BeginTransaction(isolationLevel);
					}

					var userCommand = InitializeUserCommand();
					userCommand.CommandText = executionModel.StatementText.Replace("\r\n", "\n");

					foreach (var variable in executionModel.BindVariables)
					{
						var value = await GetBindVariableValue(variable, cancellationToken);
						userCommand.AddSimpleParameter(variable.Name, value, variable.DataType.Name);
					}

					var resultInfoColumnHeaders = new Dictionary<ResultInfo, IReadOnlyList<ColumnHeader>>();
					var statement = (OracleStatement)executionModel.Statement;
					var isPlSql = statement?.IsPlSql ?? false;
					if (isPlSql && batchExecutionModel.EnableDebug && executionModel.IsPartialStatement)
					{
						throw new InvalidOperationException("Debugging is not supported for PL/SQL fragment. ");
					}

					if (isPlSql)
					{
						currentStatementResult.ExecutedAt = DateTime.Now;

						if (batchExecutionModel.EnableDebug)
						{
							// TODO: Add COMPILE DEBUG
							_debuggerSession = new OracleDebuggerSession(this, (OracleCommand)userCommand.Clone(), batchResult);
							_debuggerSession.Detached += DebuggerSessionDetachedHandler;
						}
						else
						{
							currentStatementResult.AffectedRowCount = await userCommand.ExecuteNonQueryAsynchronous(cancellationToken);
							currentStatementResult.Duration = DateTime.Now - currentStatementResult.ExecutedAt;
							resultInfoColumnHeaders.AddRange(AcquireImplicitRefCursors(userCommand));
						}
					}
					else
					{
						currentStatementResult.ExecutedAt = DateTime.Now;
						var dataReader = await userCommand.ExecuteReaderAsynchronous(CommandBehavior.Default, cancellationToken);
						currentStatementResult.Duration = DateTime.Now - currentStatementResult.ExecutedAt;
						currentStatementResult.AffectedRowCount = dataReader.RecordsAffected;
						var resultInfo = isReferenceConstraintNavigation
							? new ResultInfo($"ReferenceConstrantResult{dataReader.GetHashCode()}", null, ResultIdentifierType.SystemGenerated)
							: new ResultInfo($"MainResult{dataReader.GetHashCode()}", $"Result set {_resultInfoColumnHeaders.Count + 1}", ResultIdentifierType.UserDefined);

						var columnHeaders = GetColumnHeadersFromReader(dataReader);
						if (columnHeaders.Count > 0)
						{
							_commandReaders.Add(resultInfo, new CommandReader { Reader = dataReader, Command = userCommand } );
							resultInfoColumnHeaders.Add(resultInfo, columnHeaders);
						}
					}

					resultInfoColumnHeaders.AddRange(UpdateBindVariables(currentStatementResult.StatementModel, userCommand));
					currentStatementResult.ResultInfoColumnHeaders = resultInfoColumnHeaders.AsReadOnly();
					_resultInfoColumnHeaders.AddRange(resultInfoColumnHeaders);

					currentStatementResult.CompilationErrors = _userCommandHasCompilationErrors
						? await RetrieveCompilationErrors(executionModel.ValidationModel.Statement, cancellationToken)
						: CompilationError.EmptyArray;

					currentStatementResult.SuccessfulExecutionMessage = statement == null
						? OracleStatement.DefaultMessageCommandExecutedSuccessfully
						: statement.BuildExecutionFeedbackMessage(currentStatementResult.AffectedRowCount, _userCommandHasCompilationErrors);
				}
			}
			catch (OracleException exception)
			{
				if (currentStatementResult == null)
				{
					statementResults.Add(
						new StatementExecutionResult
						{
							StatementModel = batchExecutionModel.Statements[0],
							Exception = exception
						});
				}
				else
				{
					currentStatementResult.Exception = exception;

					if (currentStatementResult.ExecutedAt != null && currentStatementResult.Duration == null)
					{
						currentStatementResult.Duration = DateTime.Now - currentStatementResult.ExecutedAt;
					}
				}

				var executionException = new StatementExecutionException(batchResult, exception);

				var isConnectionTerminated = TryHandleConnectionTerminatedError(exception);
				if (isConnectionTerminated)
				{
					throw executionException;
				}

				if (exception.Number == (int)OracleErrorCode.UserInvokedCancellation)
				{
					return batchResult;
				}

				if (currentStatementResult != null)
				{
					currentStatementResult.ErrorPosition = await GetSyntaxErrorIndex(currentStatementResult.StatementModel.StatementText, cancellationToken);
				}

				throw executionException;
			}
			finally
			{
				batchResult.StatementResults = statementResults.AsReadOnly();

				try
				{
					if (_userConnection.State == ConnectionState.Open && !batchExecutionModel.EnableDebug && !cancellationToken.IsCancellationRequested)
					{
						await FinalizeBatchExecution(batchResult, cancellationToken);
					}
				}
				finally
				{
					_isExecuting = false;
				}
			}

			return batchResult;
		}
Beispiel #6
0
		private async Task ExecuteDatabaseCommandAsyncInternal(StatementBatchExecutionModel executionModel)
		{
			if (executionModel.Statements.Count == 0)
			{
				return;
			}

			var beforeExecutionText = DocumentPage.Editor.Text;

			Initialize();

			FileResultViewer.Initialize();

			ConnectionAdapter.EnableDatabaseOutput = EnableDatabaseOutput;

			Task<StatementExecutionBatchResult> innerTask = null;
			var actionResult = await SafeTimedActionAsync(() => innerTask = ConnectionAdapter.ExecuteStatementAsync(executionModel, _statementExecutionCancellationTokenSource.Token));

			HasActiveTransaction = ConnectionAdapter.HasActiveTransaction;
			TransactionIdentifier = ConnectionAdapter.TransanctionIdentifier;

			if (!actionResult.IsSuccessful)
			{
				var executionException = actionResult.Exception as StatementExecutionException;
				if (executionException != null)
				{
					UpdateExecutionLog(executionException.BatchResult.StatementResults);
					WriteDatabaseOutput(executionException.BatchResult.DatabaseOutput);

					var lastStatementResult = executionException.BatchResult.StatementResults.Last();
					var errorPosition = lastStatementResult.ErrorPosition;
					if (errorPosition.HasValue && String.Equals(beforeExecutionText, DocumentPage.Editor.Text))
					{
						DocumentPage.Editor.CaretOffset = lastStatementResult.StatementModel.Statement.RootNode.SourcePosition.IndexStart + errorPosition.Value;
					}
				}

				Messages.ShowError(actionResult.Exception.Message);
				return;
			}

			_executionResult = innerTask.Result;

			if (ConnectionAdapter.DebuggerSession != null)
			{
				DebuggerViewer.Initialize(this, ConnectionAdapter.DebuggerSession);
				ConnectionAdapter.DebuggerSession.Attached += delegate { Dispatcher.Invoke(DebuggerSessionSynchronizedHandler); };
				ConnectionAdapter.DebuggerSession.Detached += DebuggerSessionDetachedHandler;
				var exception = await App.SafeActionAsync(() => ConnectionAdapter.DebuggerSession.Start(_statementExecutionCancellationTokenSource.Token));
				if (exception != null)
				{
					Messages.ShowError(exception.Message);
				}

				return;
			}

			UpdateExecutionLog(_executionResult.StatementResults);

			UpdateHistoryEntries();

			if (_executionResult.StatementResults.Last().ExecutedSuccessfully == false)
			{
				NotifyExecutionCanceled();
				return;
			}

			UpdateTimerMessage(actionResult.Elapsed, false);

			await DisplayExecutionResult();
		}