// 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"); }
public async Task InterServiceExecuteNullEventSender() { // Setup: Create a query service, and execute params var qes = new QueryExecutionService(null, null); var executeParams = new ExecuteStringParams(); // If: I call the inter-service API to execute a query with a a null event sender // Then: It should throw await Assert.ThrowsAsync <ArgumentNullException>( () => qes.InterServiceExecuteQuery(executeParams, null, null, null, null, null, null)); }
public async Task InterServiceExecuteNullFailureFunc() { // Setup: Create a query service, and execute params var qes = new QueryExecutionService(null, null); var executeParams = new ExecuteStringParams(); var eventSender = new EventFlowValidator<ExecuteRequestResult>().Complete().Object; Func<Task> successFunc = () => Task.FromResult(0); // If: I call the inter-service API to execute a query with a a null failure function // Then: It should throw await Assert.ThrowsAsync<ArgumentNullException>( () => qes.InterServiceExecuteQuery(executeParams, eventSender, successFunc, null)); }
public void GetSqlTextFromStringRequest() { // Setup: // ... Create a query execution service without a connection service or workspace // service (we won't execute code that uses either var queryService = new QueryExecutionService(null, null); // If: I attempt to get query text from execute string params var queryParams = new ExecuteStringParams {OwnerUri = Common.OwnerUri, Query = Common.StandardQuery}; var queryText = queryService.GetSqlText(queryParams); // Then: The text should match the standard query Assert.Equal(Common.StandardQuery, queryText); }
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); }
// 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"); }
/// <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()); } }
/// <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)); }