Example #1
0
        /// <summary>
        /// Reads from the reader until there are no more results to read
        /// </summary>
        /// <param name="dbDataReader">The data reader for getting results from the db</param>
        /// <param name="cancellationToken">Cancellation token for cancelling the query</param>
        public async Task ReadResultToEnd(DbDataReader dbDataReader, CancellationToken cancellationToken)
        {
            // Sanity check to make sure we got a reader
            //
            Validate.IsNotNull(nameof(dbDataReader), dbDataReader);

            try
            {
                // Verify the request hasn't been cancelled
                cancellationToken.ThrowIfCancellationRequested();

                StorageDataReader dataReader = new StorageDataReader(dbDataReader);

                // Open a writer for the file
                //
                var fileWriter = fileStreamFactory.GetWriter(outputFileName);
                using (fileWriter)
                {
                    // If we can initialize the columns using the column schema, use that
                    //
                    if (!dataReader.DbDataReader.CanGetColumnSchema())
                    {
                        throw new InvalidOperationException(SR.QueryServiceResultSetNoColumnSchema);
                    }
                    Columns = dataReader.Columns;
                    // Check if result set is 'for xml/json'. If it is, set isJson/isXml value in column metadata
                    //
                    SingleColumnXmlJsonResultSet();

                    // Mark that read of result has started
                    //
                    hasStartedRead = true;
                    while (await dataReader.ReadAsync(cancellationToken))
                    {
                        fileOffsets.Add(totalBytesWritten);
                        totalBytesWritten += fileWriter.WriteRow(dataReader);

                        //  If we have never triggered the timer to start sending the results available/updated notification
                        //   then:  Trigger the timer to start sending results update notification
                        //
                        if (LastUpdatedSummary == null)
                        {
                            // Invoke the timer to send available/update result set notification immediately
                            //
                            resultsTimer.Change(0, Timeout.Infinite);
                        }
                    }
                    CheckForIsJson();
                }
            }
            finally
            {
                hasCompletedRead = true; // set the flag to indicate that we are done reading

                // Make a final call to ResultUpdated by invoking the timer to send update result set notification immediately
                //
                resultsTimer.Change(0, Timeout.Infinite);

                // and finally:
                // Make a call to send ResultCompletion and await for it to Complete
                //
                await(ResultCompletion?.Invoke(this) ?? Task.CompletedTask);
            }
        }
        /// <summary>
        /// Reads from the reader until there are no more results to read
        /// </summary>
        /// <param name="dbDataReader">The data reader for getting results from the db</param>
        /// <param name="cancellationToken">Cancellation token for cancelling the query</param>
        public async Task ReadResultToEnd(DbDataReader dbDataReader, CancellationToken cancellationToken)
        {
            // Sanity check to make sure we got a reader
            //
            Validate.IsNotNull(nameof(dbDataReader), dbDataReader);

            Task availableTask = null;

            try
            {
                // Verify the request hasn't been cancelled
                cancellationToken.ThrowIfCancellationRequested();

                StorageDataReader dataReader = new StorageDataReader(dbDataReader);

                // Open a writer for the file
                //
                var fileWriter = fileStreamFactory.GetWriter(outputFileName);
                using (fileWriter)
                {
                    // If we can initialize the columns using the column schema, use that
                    //
                    if (!dataReader.DbDataReader.CanGetColumnSchema())
                    {
                        throw new InvalidOperationException(SR.QueryServiceResultSetNoColumnSchema);
                    }
                    Columns = dataReader.Columns;
                    // Check if result set is 'for xml/json'. If it is, set isJson/isXml value in column metadata
                    //
                    SingleColumnXmlJsonResultSet();

                    // Mark that read of result has started
                    //
                    hasStartedRead = true;

                    // Invoke the SendCurrentResults() asynchronously that will send the results available notification
                    //   and also trigger the timer to send periodic updates.
                    //
                    availableTask = SendCurrentResults();

                    while (await dataReader.ReadAsync(cancellationToken))
                    {
                        fileOffsets.Add(totalBytesWritten);
                        totalBytesWritten += fileWriter.WriteRow(dataReader);
                    }
                    CheckForIsJson();
                }
            }
            finally
            {
                // await the completion of available notification in case it is not already done before proceeding
                //
                await availableTask;

                // now set the flag to indicate that we are done reading. this equates to Complete flag to be marked 'True' in any future notifications.
                //
                hasCompletedRead = true;


                // Make a final call to SendCurrentResults() and await its completion. If the previously scheduled task already took care of latest status send then this should be a no-op
                //
                await SendCurrentResults();


                // and finally:
                // Make a call to send ResultCompletion and await its completion. This is just for backward compatibility with older protocol
                //
                await(ResultCompletion?.Invoke(this) ?? Task.CompletedTask);
            }
        }