/// <summary> /// Generates a subset of the rows from the result set /// </summary> /// <param name="startRow">The starting row of the results</param> /// <param name="rowCount">How many rows to retrieve</param> /// <returns>A subset of results</returns> public Task <ResultSetSubset> GetSubset(long startRow, int rowCount) { // Sanity check to make sure that results read has started if (!hasStartedRead) { throw new InvalidOperationException(SR.QueryServiceResultSetNotRead); } // Sanity check to make sure that the row and the row count are within bounds if (startRow < 0 || startRow >= RowCount) { throw new ArgumentOutOfRangeException(nameof(startRow), SR.QueryServiceResultSetStartRowOutOfRange); } if (rowCount <= 0) { throw new ArgumentOutOfRangeException(nameof(rowCount), SR.QueryServiceResultSetRowCountOutOfRange); } return(Task.Factory.StartNew(() => { DbCellValue[][] rows; using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName)) { // If result set is 'for xml' or 'for json', // Concatenate all the rows together into one row if (isSingleColumnXmlJsonResultSet) { // Iterate over all the rows and process them into a list of string builders // ReSharper disable once AccessToDisposedClosure The lambda is used immediately in string.Join call IEnumerable <string> rowValues = fileOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, 0, Columns)[0].DisplayValue); string singleString = string.Join(string.Empty, rowValues); DbCellValue cellValue = new DbCellValue { DisplayValue = singleString, IsNull = false, RawObject = singleString, RowId = 0 }; rows = new[] { new[] { cellValue } }; } else { // Figure out which rows we need to read back IEnumerable <long> rowOffsets = fileOffsets.LongSkip(startRow).Take(rowCount); // Iterate over the rows we need and process them into output // ReSharper disable once AccessToDisposedClosure The lambda is used immediately in .ToArray call rows = rowOffsets.Select((offset, id) => fileStreamReader.ReadRow(offset, id, Columns).ToArray()).ToArray(); } } // Retrieve the subset of the results as per the request return new ResultSetSubset { Rows = rows, RowCount = rows.Length }; })); }
/// <summary> /// Generates a subset of the rows from the result set /// </summary> /// <param name="startRow">The starting row of the results</param> /// <param name="rowCount">How many rows to retrieve</param> /// <returns>A subset of results</returns> public Task <ResultSetSubset> GetSubset(int startRow, int rowCount) { // Sanity check to make sure that the results have been read beforehand if (!hasBeenRead) { throw new InvalidOperationException(SR.QueryServiceResultSetNotRead); } // Sanity check to make sure that the row and the row count are within bounds if (startRow < 0 || startRow >= RowCount) { throw new ArgumentOutOfRangeException(nameof(startRow), SR.QueryServiceResultSetStartRowOutOfRange); } if (rowCount <= 0) { throw new ArgumentOutOfRangeException(nameof(rowCount), SR.QueryServiceResultSetRowCountOutOfRange); } return(Task.Factory.StartNew(() => { string[][] rows; using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName)) { // If result set is 'for xml' or 'for json', // Concatenate all the rows together into one row if (isSingleColumnXmlJsonResultSet) { // Iterate over all the rows and process them into a list of string builders IEnumerable <string> rowValues = FileOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, Columns)[0].DisplayValue); rows = new[] { new[] { string.Join(string.Empty, rowValues) } }; } else { // Figure out which rows we need to read back IEnumerable <long> rowOffsets = FileOffsets.Skip(startRow).Take(rowCount); // Iterate over the rows we need and process them into output rows = rowOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, Columns).Select(cell => cell.DisplayValue).ToArray()) .ToArray(); } } // Retrieve the subset of the results as per the request return new ResultSetSubset { Rows = rows, RowCount = rows.Length }; })); }
/// <summary> /// Returns a specific row from the result set. /// </summary> /// <remarks> /// Creates a new file reader for a single reader. This method should only be used for one /// off requests, not for requesting a large subset of the results. /// </remarks> /// <param name="rowId">The internal ID of the row to read</param> /// <returns>The requested row</returns> public IList <DbCellValue> GetRow(long rowId) { // Sanity check to make sure that results read has started if (!hasStartedRead) { throw new InvalidOperationException(SR.QueryServiceResultSetNotRead); } // Sanity check to make sure that the row exists if (rowId >= RowCount) { throw new ArgumentOutOfRangeException(nameof(rowId), SR.QueryServiceResultSetStartRowOutOfRange); } using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName)) { return(fileStreamReader.ReadRow(fileOffsets[rowId], rowId, Columns)); } }
/// <summary> /// Generates the execution plan from the table returned /// </summary> /// <returns>An execution plan object</returns> public Task <ExecutionPlan> GetExecutionPlan() { // Process the action just in case it hasn't been yet ProcessSpecialAction(); // Sanity check to make sure that results read has started if (!hasStartedRead) { throw new InvalidOperationException(SR.QueryServiceResultSetNotRead); } // Check that we this result set contains a showplan if (!specialAction.ExpectYukonXMLShowPlan) { throw new Exception(SR.QueryServiceExecutionPlanNotFound); } return(Task.Factory.StartNew(() => { string content; string format = null; using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName)) { // Determine the format and get the first col/row of XML content = fileStreamReader.ReadRow(0, 0, Columns)[0].DisplayValue; if (specialAction.ExpectYukonXMLShowPlan) { format = "xml"; } } return new ExecutionPlan { Format = format, Content = content }; })); }