Example #1
0
        /// <summary>
        /// Handles request to execute a selection of a document in the workspace service
        /// </summary>
        internal async Task HandleExecuteRequest(ExecuteRequestParamsBase executeParams,
                                                 RequestContext <ExecuteRequestResult> requestContext)
        {
            try
            {
                // Setup actions to perform upon successful start and on failure to start
                Func <Query, Task <bool> > queryCreateSuccessAction = async q =>
                {
                    await requestContext.SendResult(new ExecuteRequestResult());

                    Logger.Write(TraceEventType.Stop, $"Response for Query: '{executeParams.OwnerUri} sent. Query Complete!");
                    return(true);
                };
                Func <string, Task> queryCreateFailureAction = message =>
                {
                    Logger.Write(TraceEventType.Warning, $"Failed to create Query: '{executeParams.OwnerUri}. Message: '{message}' Complete!");
                    return(requestContext.SendError(message));
                };

                // Use the internal handler to launch the query
                WorkTask = Task.Run(async() =>
                {
                    await InterServiceExecuteQuery(executeParams, null, requestContext, queryCreateSuccessAction, queryCreateFailureAction, null, null);
                });
            }
            catch (Exception ex)
            {
                await requestContext.SendError(ex.ToString());
            }
        }
Example #2
0
        // Internal for testing purposes
        internal string GetSqlText(ExecuteRequestParamsBase request)
        {
            // If it is a document selection, we'll retrieve the text from the document
            ExecuteDocumentSelectionParams docRequest = request as ExecuteDocumentSelectionParams;

            if (docRequest != null)
            {
                return(GetSqlTextFromSelectionData(docRequest.OwnerUri, docRequest.QuerySelection));
            }

            // If it is a document statement, we'll retrieve the text from the document
            ExecuteDocumentStatementParams stmtRequest = request as ExecuteDocumentStatementParams;

            if (stmtRequest != null)
            {
                return(GetSqlStatementAtPosition(stmtRequest.OwnerUri, stmtRequest.Line, stmtRequest.Column));
            }

            // If it is an ExecuteStringParams, return the text as is
            ExecuteStringParams stringRequest = request as ExecuteStringParams;

            if (stringRequest != null)
            {
                return(stringRequest.Query);
            }

            // Note, this shouldn't be possible due to inheritance rules
            throw new InvalidCastException("Invalid request type");
        }
        /// <summary>
        /// Handles request to execute a selection of a document in the workspace service
        /// </summary>
        internal Task HandleExecuteRequest(ExecuteRequestParamsBase executeParams,
                                           RequestContext <ExecuteRequestResult> requestContext)
        {
            // Setup actions to perform upon successful start and on failure to start
            Func <Task>         queryCreationAction = () => requestContext.SendResult(new ExecuteRequestResult());
            Func <string, Task> queryFailAction     = requestContext.SendError;

            // Use the internal handler to launch the query
            return(InterServiceExecuteQuery(executeParams, requestContext, queryCreationAction, queryFailAction));
        }
Example #4
0
        /// <summary>
        /// Handles request to execute a selection of a document in the workspace service
        /// </summary>
        internal Task HandleExecuteRequest(ExecuteRequestParamsBase executeParams,
                                           RequestContext <ExecuteRequestResult> requestContext)
        {
            // Setup actions to perform upon successful start and on failure to start
            Func <Query, Task <bool> > queryCreateSuccessAction = async q => {
                await requestContext.SendResult(new ExecuteRequestResult());

                return(true);
            };
            Func <string, Task> queryCreateFailureAction = message => requestContext.SendError(message);

            // Use the internal handler to launch the query
            return(InterServiceExecuteQuery(executeParams, null, requestContext, queryCreateSuccessAction, queryCreateFailureAction, null, null));
        }
        /// <summary>
        /// Query execution meant to be called from another service. Utilizes callbacks to allow
        /// custom actions to be taken upon creation of query and failure to create query.
        /// </summary>
        /// <param name="executeParams">Params for creating the new query</param>
        /// <param name="eventSender">Object that can send events for query execution progress</param>
        /// <param name="queryCreatedAction">
        /// Action to perform when query has been successfully created, right before execution of
        /// the query
        /// </param>
        /// <param name="failureAction">Action to perform if query was not successfully created</param>
        public async Task InterServiceExecuteQuery(ExecuteRequestParamsBase executeParams, IEventSender eventSender,
                                                   Func <Task> queryCreatedAction, Func <string, Task> failureAction)
        {
            Validate.IsNotNull(nameof(executeParams), executeParams);
            Validate.IsNotNull(nameof(eventSender), eventSender);
            Validate.IsNotNull(nameof(queryCreatedAction), queryCreatedAction);
            Validate.IsNotNull(nameof(failureAction), failureAction);

            // Get a new active query
            Query newQuery = await CreateAndActivateNewQuery(executeParams, queryCreatedAction, failureAction);

            // Execute the query asynchronously
            ExecuteAndCompleteQuery(executeParams.OwnerUri, eventSender, newQuery);
        }
        private async Task <Query> CreateAndActivateNewQuery(ExecuteRequestParamsBase executeParams, Func <Task> successAction, Func <string, Task> failureAction)
        {
            try
            {
                // Attempt to get the connection for the editor
                ConnectionInfo connectionInfo;
                if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
                {
                    await failureAction(SR.QueryServiceQueryInvalidOwnerUri);

                    return(null);
                }

                // Attempt to clean out any old query on the owner URI
                Query oldQuery;
                if (ActiveQueries.TryGetValue(executeParams.OwnerUri, out oldQuery) && oldQuery.HasExecuted)
                {
                    oldQuery.Dispose();
                    ActiveQueries.TryRemove(executeParams.OwnerUri, out oldQuery);
                }

                // Retrieve the current settings for executing the query with
                QueryExecutionSettings querySettings = Settings.QueryExecutionSettings;

                // Apply execution parameter settings
                querySettings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;

                // If we can't add the query now, it's assumed the query is in progress
                Query newQuery = new Query(GetSqlText(executeParams), connectionInfo, querySettings, BufferFileFactory);
                if (!ActiveQueries.TryAdd(executeParams.OwnerUri, newQuery))
                {
                    await failureAction(SR.QueryServiceQueryInProgress);

                    newQuery.Dispose();
                    return(null);
                }

                // Successfully created query
                await successAction();

                return(newQuery);
            }
            catch (Exception e)
            {
                await failureAction(e.Message);

                return(null);
            }
        }
Example #7
0
        private Query CreateQuery(ExecuteRequestParamsBase executeParams, ConnectionInfo connInfo)
        {
            // Attempt to get the connection for the editor
            ConnectionInfo connectionInfo;

            if (connInfo != null)
            {
                connectionInfo = connInfo;
            }
            else if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
            {
                throw new ArgumentOutOfRangeException(nameof(executeParams.OwnerUri), SR.QueryServiceQueryInvalidOwnerUri);
            }

            // Attempt to clean out any old query on the owner URI
            Query oldQuery;

            // DevNote:
            //    if any oldQuery exists on the executeParams.OwnerUri but it has not yet executed,
            //    then shouldn't we cancel and clean out that query since we are about to create a new query object on the current OwnerUri.
            //
            if (ActiveQueries.TryGetValue(executeParams.OwnerUri, out oldQuery) && (oldQuery.HasExecuted || oldQuery.HasCancelled))
            {
                oldQuery.Dispose();
                ActiveQueries.TryRemove(executeParams.OwnerUri, out oldQuery);
            }

            // Retrieve the current settings for executing the query with
            QueryExecutionSettings settings = Settings.QueryExecutionSettings;

            // Apply execution parameter settings
            settings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;

            // If we can't add the query now, it's assumed the query is in progress
            Query newQuery = new Query(GetSqlText(executeParams), connectionInfo, settings, BufferFileFactory, executeParams.GetFullColumnSchema);

            if (!ActiveQueries.TryAdd(executeParams.OwnerUri, newQuery))
            {
                newQuery.Dispose();
                throw new InvalidOperationException(SR.QueryServiceQueryInProgress);
            }

            Logger.Write(TraceEventType.Information, $"Query object for URI:'{executeParams.OwnerUri}' created");
            return(newQuery);
        }
        // Internal for testing purposes
        internal string GetSqlText(ExecuteRequestParamsBase request)
        {
            // If it is a document selection, we'll retrieve the text from the document
            ExecuteDocumentSelectionParams docRequest = request as ExecuteDocumentSelectionParams;

            if (docRequest != null)
            {
                // Get the document from the parameters
                ScriptFile queryFile = WorkspaceService.Workspace.GetFile(docRequest.OwnerUri);

                // If a selection was not provided, use the entire document
                if (docRequest.QuerySelection == null)
                {
                    return(queryFile.Contents);
                }

                // A selection was provided, so get the lines in the selected range
                string[] queryTextArray = queryFile.GetLinesInRange(
                    new BufferRange(
                        new BufferPosition(
                            docRequest.QuerySelection.StartLine + 1,
                            docRequest.QuerySelection.StartColumn + 1
                            ),
                        new BufferPosition(
                            docRequest.QuerySelection.EndLine + 1,
                            docRequest.QuerySelection.EndColumn + 1
                            )
                        )
                    );
                return(string.Join(Environment.NewLine, queryTextArray));
            }

            // If it is an ExecuteStringParams, return the text as is
            ExecuteStringParams stringRequest = request as ExecuteStringParams;

            if (stringRequest != null)
            {
                return(stringRequest.Query);
            }

            // Note, this shouldn't be possible due to inheritance rules
            throw new InvalidCastException("Invalid request type");
        }
Example #9
0
        private Query CreateQuery(ExecuteRequestParamsBase executeParams, ConnectionInfo connInfo)
        {
            // Attempt to get the connection for the editor
            ConnectionInfo connectionInfo;

            if (connInfo != null)
            {
                connectionInfo = connInfo;
            }
            else if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
            {
                throw new ArgumentOutOfRangeException(nameof(executeParams.OwnerUri), SR.QueryServiceQueryInvalidOwnerUri);
            }

            // Attempt to clean out any old query on the owner URI
            Query oldQuery;

            if (ActiveQueries.TryGetValue(executeParams.OwnerUri, out oldQuery) && oldQuery.HasExecuted)
            {
                oldQuery.Dispose();
                ActiveQueries.TryRemove(executeParams.OwnerUri, out oldQuery);
            }

            // Retrieve the current settings for executing the query with
            QueryExecutionSettings settings = Settings.QueryExecutionSettings;

            // Apply execution parameter settings
            settings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;

            // If we can't add the query now, it's assumed the query is in progress
            Query newQuery = new Query(GetSqlText(executeParams), connectionInfo, settings, BufferFileFactory, executeParams.GetFullColumnSchema);

            if (!ActiveQueries.TryAdd(executeParams.OwnerUri, newQuery))
            {
                newQuery.Dispose();
                throw new InvalidOperationException(SR.QueryServiceQueryInProgress);
            }

            return(newQuery);
        }
Example #10
0
        /// <summary>
        /// Query execution meant to be called from another service. Utilizes callbacks to allow
        /// custom actions to be taken upon creation of query and failure to create query.
        /// </summary>
        /// <param name="executeParams">Parameters for execution</param>
        /// <param name="connInfo">Connection Info to use; will try and get the connection from owneruri if not provided</param>
        /// <param name="queryEventSender">Event sender that will send progressive events during execution of the query</param>
        /// <param name="queryCreateSuccessFunc">
        /// Callback for when query has been created successfully. If result is <c>true</c>, query
        /// will be executed asynchronously. If result is <c>false</c>, query will be disposed. May
        /// be <c>null</c>
        /// </param>
        /// <param name="queryCreateFailFunc">
        /// Callback for when query failed to be created successfully. Error message is provided.
        /// May be <c>null</c>.
        /// </param>
        /// <param name="querySuccessFunc">
        /// Callback to call when query has completed execution successfully. May be <c>null</c>.
        /// </param>
        /// <param name="queryFailureFunc">
        /// Callback to call when query has completed execution with errors. May be <c>null</c>.
        /// </param>
        public async Task InterServiceExecuteQuery(ExecuteRequestParamsBase executeParams,
                                                   ConnectionInfo connInfo,
                                                   IEventSender queryEventSender,
                                                   Func <Query, Task <bool> > queryCreateSuccessFunc,
                                                   Func <string, Task> queryCreateFailFunc,
                                                   Query.QueryAsyncEventHandler querySuccessFunc,
                                                   Query.QueryAsyncErrorEventHandler queryFailureFunc,
                                                   bool applyExecutionSettings = false)
        {
            Validate.IsNotNull(nameof(executeParams), executeParams);
            Validate.IsNotNull(nameof(queryEventSender), queryEventSender);

            Query newQuery;

            try
            {
                // Get a new active query
                newQuery = CreateQuery(executeParams, connInfo, applyExecutionSettings);
                if (queryCreateSuccessFunc != null && !await queryCreateSuccessFunc(newQuery))
                {
                    // The callback doesn't want us to continue, for some reason
                    // It's ok if we leave the query behind in the active query list, the next call
                    // to execute will replace it.
                    newQuery.Dispose();
                    return;
                }
            }
            catch (Exception e)
            {
                // Call the failure callback if it was provided
                if (queryCreateFailFunc != null)
                {
                    await queryCreateFailFunc(e.Message);
                }
                return;
            }

            // Execute the query asynchronously
            ExecuteAndCompleteQuery(executeParams.OwnerUri, newQuery, queryEventSender, querySuccessFunc, queryFailureFunc);
        }
Example #11
0
        private Query CreateQuery(
            ExecuteRequestParamsBase executeParams,
            ConnectionInfo connInfo,
            bool applyExecutionSettings)
        {
            // Attempt to get the connection for the editor
            ConnectionInfo connectionInfo;

            if (connInfo != null)
            {
                connectionInfo = connInfo;
            }
            else if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connectionInfo))
            {
                throw new ArgumentOutOfRangeException(nameof(executeParams.OwnerUri), SR.QueryServiceQueryInvalidOwnerUri);
            }

            // Attempt to clean out any old query on the owner URI
            Query oldQuery;

            // DevNote:
            //    if any oldQuery exists on the executeParams.OwnerUri but it has not yet executed,
            //    then shouldn't we cancel and clean out that query since we are about to create a new query object on the current OwnerUri.
            //
            if (ActiveQueries.TryGetValue(executeParams.OwnerUri, out oldQuery) && (oldQuery.HasExecuted || oldQuery.HasCancelled || oldQuery.HasErrored))
            {
                oldQuery.Dispose();
                ActiveQueries.TryRemove(executeParams.OwnerUri, out oldQuery);
            }

            // check if there are active query execution settings for the editor, otherwise, use the global settings
            QueryExecutionSettings settings;

            if (this.ActiveQueryExecutionSettings.TryGetValue(executeParams.OwnerUri, out settings))
            {
                // special-case handling for query plan options to maintain compat with query execution API parameters
                // the logic is that if either the query execute API parameters or the active query setttings
                // request a plan then enable the query option
                ExecutionPlanOptions executionPlanOptions = executeParams.ExecutionPlanOptions;
                if (settings.IncludeActualExecutionPlanXml)
                {
                    executionPlanOptions.IncludeActualExecutionPlanXml = settings.IncludeActualExecutionPlanXml;
                }
                if (settings.IncludeEstimatedExecutionPlanXml)
                {
                    executionPlanOptions.IncludeEstimatedExecutionPlanXml = settings.IncludeEstimatedExecutionPlanXml;
                }
                settings.ExecutionPlanOptions = executionPlanOptions;
            }
            else
            {
                settings = Settings.QueryExecutionSettings;
                settings.ExecutionPlanOptions = executeParams.ExecutionPlanOptions;
            }

            // If we can't add the query now, it's assumed the query is in progress
            Query newQuery = new Query(
                GetSqlText(executeParams),
                connectionInfo,
                settings,
                BufferFileFactory,
                executeParams.GetFullColumnSchema,
                applyExecutionSettings);

            if (!ActiveQueries.TryAdd(executeParams.OwnerUri, newQuery))
            {
                newQuery.Dispose();
                throw new InvalidOperationException(SR.QueryServiceQueryInProgress);
            }

            Logger.Write(TraceEventType.Information, $"Query object for URI:'{executeParams.OwnerUri}' created");
            return(newQuery);
        }