コード例 #1
0
        public async Task CancelQueryBeforeExecutionStartedTest()
        {
            // Setup query settings
            QueryExecutionSettings querySettings = new QueryExecutionSettings
            {
                ExecutionPlanOptions = new ExecutionPlanOptions
                {
                    IncludeActualExecutionPlanXml    = false,
                    IncludeEstimatedExecutionPlanXml = true
                }
            };

            // Create query with a failure callback function
            ConnectionInfo ci = Common.CreateTestConnectionInfo(null, false, false);

            ConnectionService.Instance.OwnerToConnectionMap[ci.OwnerUri] = ci;
            Query query = new Query(Constants.StandardQuery, ci, querySettings, MemoryFileSystem.GetFileStreamFactory());

            string errorMessage = null;

            Query.QueryAsyncErrorEventHandler failureCallback = async(q, e) =>
            {
                errorMessage = "Error Occured";
            };
            query.QueryFailed += failureCallback;

            query.Cancel();
            query.Execute();
            await query.ExecutionTask;

            // Validate that query has not been executed but cancelled and query failed called function was called
            Assert.Equal(true, query.HasCancelled);
            Assert.Equal(false, query.HasExecuted);
            Assert.Equal("Error Occured", errorMessage);
        }
コード例 #2
0
        private async Task <EditSession.EditSessionQueryExecutionState> SessionInitializeQueryRunner(string ownerUri,
                                                                                                     IEventSender eventSender, string query)
        {
            // Open a task completion source, effectively creating a synchronous block
            TaskCompletionSource <EditSession.EditSessionQueryExecutionState> taskCompletion =
                new TaskCompletionSource <EditSession.EditSessionQueryExecutionState>();

            // Setup callback for successful query creation
            // NOTE: We do not want to set the task completion source, since we will continue executing the query after
            Func <Query, Task <bool> > queryCreateSuccessCallback = q => Task.FromResult(true);

            // Setup callback for failed query creation
            Func <string, Task> queryCreateFailureCallback = m =>
            {
                taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(null, m));
                return(Task.FromResult(0));
            };

            // Setup callback for successful query execution
            Query.QueryAsyncEventHandler queryCompleteSuccessCallback = q =>
            {
                taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(q));
                return(Task.FromResult(0));
            };

            // Setup callback for failed query execution
            Query.QueryAsyncErrorEventHandler queryCompleteFailureCallback = (q, e) =>
            {
                taskCompletion.SetResult(new EditSession.EditSessionQueryExecutionState(null));
                return(Task.FromResult(0));
            };

            // Execute the query
            ExecuteStringParams executeParams = new ExecuteStringParams
            {
                Query = query,
                GetFullColumnSchema = true,
                OwnerUri            = ownerUri
            };
            await queryExecutionService.InterServiceExecuteQuery(executeParams, null, eventSender,
                                                                 queryCreateSuccessCallback, queryCreateFailureCallback,
                                                                 queryCompleteSuccessCallback, queryCompleteFailureCallback);

            // Wait for the completion source to complete, this will wait until the query has
            // completed and sent all its events.
            return(await taskCompletion.Task);
        }
コード例 #3
0
        private static async Task ExecuteAndCompleteQuery(QueryExecuteParams executeParams, RequestContext <QueryExecuteResult> requestContext, Query query)
        {
            // Skip processing if the query is null
            if (query == null)
            {
                return;
            }

            // Setup the query completion/failure callbacks
            Query.QueryAsyncEventHandler callback = async q =>
            {
                // Send back the results
                QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams
                {
                    OwnerUri       = executeParams.OwnerUri,
                    BatchSummaries = q.BatchSummaries
                };
                await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams);
            };

            Query.QueryAsyncErrorEventHandler errorCallback = async errorMessage =>
            {
                // Send back the error message
                QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams
                {
                    OwnerUri = executeParams.OwnerUri,
                    Message  = errorMessage
                };
                await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams);
            };

            query.QueryCompleted           += callback;
            query.QueryFailed              += callback;
            query.QueryConnectionException += errorCallback;

            // Launch this as an asynchronous task
            query.Execute();

            // Send back a result showing we were successful
            await requestContext.SendResult(new QueryExecuteResult
            {
                Messages = null
            });
        }
コード例 #4
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);
        }
コード例 #5
0
        private static void ExecuteAndCompleteQuery(string ownerUri, Query query,
                                                    IEventSender eventSender,
                                                    Query.QueryAsyncEventHandler querySuccessCallback,
                                                    Query.QueryAsyncErrorEventHandler queryFailureCallback)
        {
            // Setup the callback to send the complete event
            Query.QueryAsyncEventHandler completeCallback = async q =>
            {
                // Send back the results
                QueryCompleteParams eventParams = new QueryCompleteParams
                {
                    OwnerUri       = ownerUri,
                    BatchSummaries = q.BatchSummaries
                };

                await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
            };

            // Setup the callback to send the complete event
            Query.QueryAsyncErrorEventHandler failureCallback = async(q, e) =>
            {
                // Send back the results
                QueryCompleteParams eventParams = new QueryCompleteParams
                {
                    OwnerUri       = ownerUri,
                    BatchSummaries = q.BatchSummaries
                };

                await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
            };
            query.QueryCompleted += completeCallback;
            query.QueryFailed    += failureCallback;

            // Add the callbacks that were provided by the caller
            // If they're null, that's no problem
            query.QueryCompleted += querySuccessCallback;
            query.QueryFailed    += queryFailureCallback;

            // Setup the batch callbacks
            Batch.BatchAsyncEventHandler batchStartCallback = async b =>
            {
                BatchEventParams eventParams = new BatchEventParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = ownerUri
                };

                await eventSender.SendEvent(BatchStartEvent.Type, eventParams);
            };
            query.BatchStarted += batchStartCallback;

            Batch.BatchAsyncEventHandler batchCompleteCallback = async b =>
            {
                BatchEventParams eventParams = new BatchEventParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = ownerUri
                };

                await eventSender.SendEvent(BatchCompleteEvent.Type, eventParams);
            };
            query.BatchCompleted += batchCompleteCallback;

            Batch.BatchAsyncMessageHandler batchMessageCallback = async m =>
            {
                MessageParams eventParams = new MessageParams
                {
                    Message  = m,
                    OwnerUri = ownerUri
                };
                await eventSender.SendEvent(MessageEvent.Type, eventParams);
            };
            query.BatchMessageSent += batchMessageCallback;

            // Setup the ResultSet completion callback
            ResultSet.ResultSetAsyncEventHandler resultCallback = async r =>
            {
                ResultSetEventParams eventParams = new ResultSetEventParams
                {
                    ResultSetSummary = r.Summary,
                    OwnerUri         = ownerUri
                };
                await eventSender.SendEvent(ResultSetCompleteEvent.Type, eventParams);
            };
            query.ResultSetCompleted += resultCallback;

            // Launch this as an asynchronous task
            query.Execute();
        }
コード例 #6
0
        /// <summary>
        /// Handles a request to execute a string and return the result
        /// </summary>
        internal async Task HandleSimpleExecuteRequest(SimpleExecuteParams executeParams,
                                                       RequestContext <SimpleExecuteResult> requestContext)
        {
            try
            {
                string randomUri = Guid.NewGuid().ToString();
                ExecuteStringParams executeStringParams = new ExecuteStringParams
                {
                    Query = executeParams.QueryString,
                    // generate guid as the owner uri to make sure every query is unique
                    OwnerUri = randomUri
                };

                // get connection
                ConnectionInfo connInfo;
                if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connInfo))
                {
                    await requestContext.SendError(SR.QueryServiceQueryInvalidOwnerUri);

                    return;
                }

                ConnectParams connectParams = new ConnectParams
                {
                    OwnerUri   = randomUri,
                    Connection = connInfo.ConnectionDetails,
                    Type       = ConnectionType.Default
                };

                Task workTask = Task.Run(async() => {
                    await ConnectionService.Connect(connectParams);

                    ConnectionInfo newConn;
                    ConnectionService.TryFindConnection(randomUri, out newConn);

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

                    ResultOnlyContext <SimpleExecuteResult> newContext = new ResultOnlyContext <SimpleExecuteResult>(requestContext);

                    // handle sending event back when the query completes
                    Query.QueryAsyncEventHandler queryComplete = async query =>
                    {
                        try
                        {
                            // check to make sure any results were recieved
                            if (query.Batches.Length == 0 ||
                                query.Batches[0].ResultSets.Count == 0)
                            {
                                await requestContext.SendError(SR.QueryServiceResultSetHasNoResults);
                                return;
                            }

                            long rowCount = query.Batches[0].ResultSets[0].RowCount;
                            // check to make sure there is a safe amount of rows to load into memory
                            if (rowCount > Int32.MaxValue)
                            {
                                await requestContext.SendError(SR.QueryServiceResultSetTooLarge);
                                return;
                            }

                            SimpleExecuteResult result = new SimpleExecuteResult
                            {
                                RowCount   = rowCount,
                                ColumnInfo = query.Batches[0].ResultSets[0].Columns,
                                Rows       = new DbCellValue[0][]
                            };

                            if (rowCount > 0)
                            {
                                SubsetParams subsetRequestParams = new SubsetParams
                                {
                                    OwnerUri       = randomUri,
                                    BatchIndex     = 0,
                                    ResultSetIndex = 0,
                                    RowsStartIndex = 0,
                                    RowsCount      = Convert.ToInt32(rowCount)
                                };
                                // get the data to send back
                                ResultSetSubset subset = await InterServiceResultSubset(subsetRequestParams);
                                result.Rows            = subset.Rows;
                            }
                            await requestContext.SendResult(result);
                        }
                        finally
                        {
                            Query removedQuery;
                            Task removedTask;
                            // remove the active query since we are done with it
                            ActiveQueries.TryRemove(randomUri, out removedQuery);
                            ActiveSimpleExecuteRequests.TryRemove(randomUri, out removedTask);
                            ConnectionService.Disconnect(new DisconnectParams()
                            {
                                OwnerUri = randomUri,
                                Type     = null
                            });
                        }
                    };

                    // handle sending error back when query fails
                    Query.QueryAsyncErrorEventHandler queryFail = async(q, e) =>
                    {
                        await requestContext.SendError(e);
                    };

                    await InterServiceExecuteQuery(executeStringParams, newConn, newContext, null, queryCreateFailureAction, queryComplete, queryFail);
                });

                ActiveSimpleExecuteRequests.TryAdd(randomUri, workTask);
            }
            catch (Exception ex)
            {
                await requestContext.SendError(ex.ToString());
            }
        }
コード例 #7
0
        private static void ExecuteAndCompleteQuery(string ownerUri, Query query,
                                                    IEventSender eventSender,
                                                    Query.QueryAsyncEventHandler querySuccessCallback,
                                                    Query.QueryAsyncErrorEventHandler queryFailureCallback)
        {
            // Setup the callback to send the complete event
            Query.QueryAsyncEventHandler completeCallback = async q =>
            {
                // Send back the results
                QueryCompleteParams eventParams = new QueryCompleteParams
                {
                    OwnerUri       = ownerUri,
                    BatchSummaries = q.BatchSummaries
                };

                Logger.Write(TraceEventType.Information, $"Query:'{ownerUri}' completed");
                await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
            };

            // Setup the callback to send the failure event
            Query.QueryAsyncErrorEventHandler failureCallback = async(q, e) =>
            {
                // Send back the results
                QueryCompleteParams eventParams = new QueryCompleteParams
                {
                    OwnerUri       = ownerUri,
                    BatchSummaries = q.BatchSummaries
                };

                Logger.Write(TraceEventType.Error, $"Query:'{ownerUri}' failed");
                await eventSender.SendEvent(QueryCompleteEvent.Type, eventParams);
            };
            query.QueryCompleted += completeCallback;
            query.QueryFailed    += failureCallback;

            // Add the callbacks that were provided by the caller
            // If they're null, that's no problem
            query.QueryCompleted += querySuccessCallback;
            query.QueryFailed    += queryFailureCallback;

            // Setup the batch callbacks
            Batch.BatchAsyncEventHandler batchStartCallback = async b =>
            {
                BatchEventParams eventParams = new BatchEventParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Batch:'{b.Summary}' on Query:'{ownerUri}' started");
                await eventSender.SendEvent(BatchStartEvent.Type, eventParams);
            };
            query.BatchStarted += batchStartCallback;

            Batch.BatchAsyncEventHandler batchCompleteCallback = async b =>
            {
                BatchEventParams eventParams = new BatchEventParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Batch:'{b.Summary}' on Query:'{ownerUri}' completed");
                await eventSender.SendEvent(BatchCompleteEvent.Type, eventParams);
            };
            query.BatchCompleted += batchCompleteCallback;

            Batch.BatchAsyncMessageHandler batchMessageCallback = async m =>
            {
                MessageParams eventParams = new MessageParams
                {
                    Message  = m,
                    OwnerUri = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Message generated on Query:'{ownerUri}' :'{m}'");
                await eventSender.SendEvent(MessageEvent.Type, eventParams);
            };
            query.BatchMessageSent += batchMessageCallback;

            // Setup the ResultSet available callback
            ResultSet.ResultSetAsyncEventHandler resultAvailableCallback = async r =>
            {
                ResultSetAvailableEventParams eventParams = new ResultSetAvailableEventParams
                {
                    ResultSetSummary = r.Summary,
                    OwnerUri         = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is available");
                await eventSender.SendEvent(ResultSetAvailableEvent.Type, eventParams);
            };
            query.ResultSetAvailable += resultAvailableCallback;

            // Setup the ResultSet updated callback
            ResultSet.ResultSetAsyncEventHandler resultUpdatedCallback = async r =>
            {
                ResultSetUpdatedEventParams eventParams = new ResultSetUpdatedEventParams
                {
                    ResultSetSummary = r.Summary,
                    OwnerUri         = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is updated with additional rows");
                await eventSender.SendEvent(ResultSetUpdatedEvent.Type, eventParams);
            };
            query.ResultSetUpdated += resultUpdatedCallback;

            // Setup the ResultSet completion callback
            ResultSet.ResultSetAsyncEventHandler resultCompleteCallback = async r =>
            {
                ResultSetCompleteEventParams eventParams = new ResultSetCompleteEventParams
                {
                    ResultSetSummary = r.Summary,
                    OwnerUri         = ownerUri
                };

                Logger.Write(TraceEventType.Information, $"Result:'{r.Summary} on Query:'{ownerUri}' is complete");
                await eventSender.SendEvent(ResultSetCompleteEvent.Type, eventParams);
            };
            query.ResultSetCompleted += resultCompleteCallback;

            // Launch this as an asynchronous task
            query.Execute();
        }
コード例 #8
0
        private static async Task ExecuteAndCompleteQuery(QueryExecuteParams executeParams, RequestContext <QueryExecuteResult> requestContext, Query query)
        {
            // Skip processing if the query is null
            if (query == null)
            {
                return;
            }

            // Setup the query completion/failure callbacks
            Query.QueryAsyncEventHandler callback = async q =>
            {
                // Send back the results
                QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams
                {
                    OwnerUri       = executeParams.OwnerUri,
                    BatchSummaries = q.BatchSummaries
                };

                await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams);
            };

            Query.QueryAsyncErrorEventHandler errorCallback = async errorMessage =>
            {
                // Send back the error message
                QueryExecuteCompleteParams eventParams = new QueryExecuteCompleteParams
                {
                    OwnerUri = executeParams.OwnerUri,
                    Message  = errorMessage
                };
                await requestContext.SendEvent(QueryExecuteCompleteEvent.Type, eventParams);
            };

            query.QueryCompleted           += callback;
            query.QueryFailed              += callback;
            query.QueryConnectionException += errorCallback;

            // Setup the batch callbacks
            Batch.BatchAsyncEventHandler batchStartCallback = async b =>
            {
                QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = executeParams.OwnerUri
                };
                await requestContext.SendEvent(QueryExecuteBatchStartEvent.Type, eventParams);
            };
            query.BatchStarted += batchStartCallback;

            Batch.BatchAsyncEventHandler batchCompleteCallback = async b =>
            {
                QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams
                {
                    BatchSummary = b.Summary,
                    OwnerUri     = executeParams.OwnerUri
                };
                await requestContext.SendEvent(QueryExecuteBatchCompleteEvent.Type, eventParams);
            };
            query.BatchCompleted += batchCompleteCallback;

            // Setup the ResultSet completion callback
            ResultSet.ResultSetAsyncEventHandler resultCallback = async r =>
            {
                QueryExecuteResultSetCompleteParams eventParams = new QueryExecuteResultSetCompleteParams
                {
                    ResultSetSummary = r.Summary,
                    OwnerUri         = executeParams.OwnerUri
                };
                await requestContext.SendEvent(QueryExecuteResultSetCompleteEvent.Type, eventParams);
            };
            query.ResultSetCompleted += resultCallback;

            // Launch this as an asynchronous task
            query.Execute();

            // Send back a result showing we were successful
            string messages = null;

            if (query.Batches.Length == 0)
            {
                // If there were no batches to execute, send back an informational message that the commands were completed successfully
                messages = SR.QueryServiceCompletedSuccessfully;
            }
            await requestContext.SendResult(new QueryExecuteResult
            {
                Messages = messages
            });
        }
コード例 #9
0
        /// <summary>
        /// Handles a request to execute a string and return the result
        /// </summary>
        internal Task HandleSimpleExecuteRequest(SimpleExecuteParams executeParams,
                                                 RequestContext <SimpleExecuteResult> requestContext)
        {
            ExecuteStringParams executeStringParams = new ExecuteStringParams
            {
                Query = executeParams.QueryString,
                // generate guid as the owner uri to make sure every query is unique
                OwnerUri = Guid.NewGuid().ToString()
            };

            // get connection
            ConnectionInfo connInfo;

            if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connInfo))
            {
                return(requestContext.SendError(SR.QueryServiceQueryInvalidOwnerUri));
            }

            if (connInfo.ConnectionDetails.MultipleActiveResultSets == null || connInfo.ConnectionDetails.MultipleActiveResultSets == false)
            {
                // if multipleActive result sets is not allowed, don't specific a connection and make the ownerURI the true owneruri
                connInfo = null;
                executeStringParams.OwnerUri = executeParams.OwnerUri;
            }

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

            ResultOnlyContext <SimpleExecuteResult> newContext = new ResultOnlyContext <SimpleExecuteResult>(requestContext);

            // handle sending event back when the query completes
            Query.QueryAsyncEventHandler queryComplete = async q =>
            {
                Query removedQuery;
                // check to make sure any results were recieved
                if (q.Batches.Length == 0 || q.Batches[0].ResultSets.Count == 0)
                {
                    await requestContext.SendError(SR.QueryServiceResultSetHasNoResults);

                    ActiveQueries.TryRemove(executeStringParams.OwnerUri, out removedQuery);
                    return;
                }

                var rowCount = q.Batches[0].ResultSets[0].RowCount;
                // check to make sure there is a safe amount of rows to load into memory
                if (rowCount > Int32.MaxValue)
                {
                    await requestContext.SendError(SR.QueryServiceResultSetTooLarge);

                    ActiveQueries.TryRemove(executeStringParams.OwnerUri, out removedQuery);
                    return;
                }

                SubsetParams subsetRequestParams = new SubsetParams
                {
                    OwnerUri       = executeStringParams.OwnerUri,
                    BatchIndex     = 0,
                    ResultSetIndex = 0,
                    RowsStartIndex = 0,
                    RowsCount      = Convert.ToInt32(rowCount)
                };
                // get the data to send back
                ResultSetSubset subset = await InterServiceResultSubset(subsetRequestParams);

                SimpleExecuteResult result = new SimpleExecuteResult
                {
                    RowCount   = q.Batches[0].ResultSets[0].RowCount,
                    ColumnInfo = q.Batches[0].ResultSets[0].Columns,
                    Rows       = subset.Rows
                };
                await requestContext.SendResult(result);

                // remove the active query since we are done with it
                ActiveQueries.TryRemove(executeStringParams.OwnerUri, out removedQuery);
            };

            // handle sending error back when query fails
            Query.QueryAsyncErrorEventHandler queryFail = async(q, e) =>
            {
                await requestContext.SendError(e);
            };

            return(InterServiceExecuteQuery(executeStringParams, connInfo, newContext, null, queryCreateFailureAction, queryComplete, queryFail));
        }