private List <string> EnumerateResults(ProgressiveDataSet reader) { List <string> csvRecords = new List <string>(); bool finalResults = false; bool isProgressive = false; try { IEnumerator <ProgressiveDataSetFrame> resultFrames = reader.GetFrames(); while (!finalResults && resultFrames.MoveNext()) //while (resultFrames.MoveNext()) { ProgressiveDataSetFrame resultFrame = resultFrames.Current; Log.Debug($"resultFrame:", resultFrame); switch (resultFrame.FrameType) { case FrameType.DataSetCompletion: { ProgressiveDataSetCompletionFrame result = resultFrame as ProgressiveDataSetCompletionFrame; Log.Info($"{result.GetType()}", result); break; } case FrameType.DataSetHeader: { ProgressiveDataSetHeaderFrame result = resultFrame as ProgressiveDataSetHeaderFrame; Log.Info($"{result.GetType()}", result); isProgressive = result.IsProgressive; break; } case FrameType.DataTable: { ProgressiveDataSetDataTableFrame result = resultFrame as ProgressiveDataSetDataTableFrame; Log.Info($"{result.GetType()}", result); if (result.TableName.Equals("@ExtendedProperties")) { ExtendedResults = EnumerateResults(result.TableData); if (ExtendedResults.Any(x => x.Contains("Cursor"))) { string cursorRecord = ExtendedResults.FirstOrDefault(x => x.Contains("Cursor")); Cursor = $"'{Regex.Match(cursorRecord, @"Cursor,(?<cursor>\d+?)(?:,|$)").Groups["cursor"].Value}'"; Log.Info($"setting db cursor to {Cursor}"); } } if (result.TableKind.Equals(WellKnownDataSet.PrimaryResult)) { csvRecords = EnumerateResults(result.TableData); } // if non progressive, this may be last frame if (!isProgressive) { finalResults = true; } break; } case FrameType.TableCompletion: { ProgressiveDataSetTableCompletionFrame result = resultFrame as ProgressiveDataSetTableCompletionFrame; Log.Info($"{result.GetType()}", result); break; } case FrameType.TableFragment: { ProgressiveDataSetDataTableFragmentFrame result = resultFrame as ProgressiveDataSetDataTableFragmentFrame; Log.Error($"not implemented: {result.GetType()}", result); result.ToDataTable(); break; } case FrameType.TableHeader: { ProgressiveDataSetHeaderFrame result = resultFrame as ProgressiveDataSetHeaderFrame; Log.Info($"{result.GetType()}", result); break; } case FrameType.TableProgress: { ProgressiveDataSetTableProgressFrame result = resultFrame as ProgressiveDataSetTableProgressFrame; Log.Info($"{result.GetType()}", result); break; } case FrameType.LastInvalid: default: { Log.Warning($"unknown frame type:{resultFrame.FrameType}"); return(csvRecords); } } } return(csvRecords); } catch (Exception e) { Log.Exception($"{e}"); return(csvRecords); } }
static void WriteFrameResultsToConsole(int frameNum, ProgressiveDataSetFrame frame) { var tableKind = WellKnownDataSet.Unknown; switch (frame.FrameType) { case FrameType.DataSetHeader: { // This is the first frame we'll get back var frameex = frame as ProgressiveDataSetHeaderFrame; var banner = $"[{frameNum}] DataSet/HeaderFrame: Version={frameex.Version}, IsProgressive={frameex.IsProgressive}"; Console.WriteLine(banner); Console.WriteLine(); } break; case FrameType.TableHeader: // (Progressive mode only) // This frame appears once for each table, before the table's data // is reported. { var frameex = frame as ProgressiveDataSetDataTableSchemaFrame; var banner = $"[{frameNum}] DataTable/SchemaFrame: TableId={frameex.TableId}, TableName={frameex.TableName}, TableKind={frameex.TableKind}"; WriteSchema(banner, frameex.TableSchema); } break; case FrameType.TableFragment: // (Progressive mode only) // This frame provides one part of the table's data { var frameex = frame as ProgressiveDataSetDataTableFragmentFrame; var banner = $"[{frameNum}] DataTable/FragmentFrame: TableId={frameex.TableId}, FieldCount={frameex.FieldCount}, FrameSubType={frameex.FrameSubType}"; WriteProgressiveResults(banner, frameex); } break; case FrameType.TableCompletion: // (Progressive mode only) // This frame announces the completion of a table (no more data in it). { var frameex = frame as ProgressiveDataSetTableCompletionFrame; var banner = $"[{frameNum}] DataTable/TableCompletionFrame: TableId={frameex.TableId}, RowCount={frameex.RowCount}"; Console.WriteLine(banner); Console.WriteLine(); } break; case FrameType.TableProgress: // (Progressive mode only) // This frame appears periodically to provide a progress estimateion. { var frameex = frame as ProgressiveDataSetTableProgressFrame; var banner = $"[{frameNum}] DataTable/TableProgressFrame: TableId={frameex.TableId}, TableProgress={frameex.TableProgress}"; Console.WriteLine(banner); Console.WriteLine(); } break; case FrameType.DataTable: { // This frame represents one data table (in all, when progressive results // are not used or there's no need for multiple-frames-per-table). // There are usually multiple such tables in the response, differentiated // by purpose (TableKind). // Note that we can't skip processing the data -- we must consume it. var frameex = frame as ProgressiveDataSetDataTableFrame; var banner = $"[{frameNum}] DataTable/DataTableFrame: TableId={frameex.TableId}, TableName={frameex.TableName}, TableKind={frameex.TableKind}"; WriteResults(banner, frameex.TableData); } break; case FrameType.DataSetCompletion: { // This is the last frame in the data set. // It provides information on the overall success of the query: // Whether there were any errors, whether it got cancelled mid-stream, // and what exceptions were raised if either is true. var frameex = frame as ProgressiveDataSetCompletionFrame; var banner = $"[{frameNum}] DataSet/CompletionFrame: HasErrors={frameex.HasErrors}, Cancelled={frameex.Cancelled}, Exception={ExtendedString.SafeToString(frameex.Exception)}"; Console.WriteLine(banner); Console.WriteLine(); } break; case FrameType.LastInvalid: default: // In general this should not happen break; } }