public static async Task WriteToStream(Stream StreamToWrite, DataSet DS, CancellationToken cancellationToken, JsonWriterOptions JsonWriterOptions) { using (System.Text.Json.Utf8JsonWriter writter = new System.Text.Json.Utf8JsonWriter(StreamToWrite, JsonWriterOptions)) { writter.WriteStartObject(); writter.WriteStartArray("Tables"); if (DS.Tables.Count > 0) { foreach (DataTable table in DS.Tables) { writter.WriteStartObject(); writter.WriteString("TableName", table.TableName); writter.WriteStartArray("Columns"); foreach (DataColumn column in table.Columns) { writter.WriteStartArray(); JsonSerializer.Serialize(writter, column.ColumnName); JsonSerializer.Serialize(writter, ColumnType(column)); writter.WriteEndArray(); } writter.WriteEndArray(); writter.WriteStartArray("Rows"); await writter.FlushAsync(cancellationToken); if (table.Rows.Count > 0) { foreach (DataRow row in table.Rows) { writter.WriteStartArray(); foreach (var item in row.ItemArray) { JsonSerializer.Serialize(writter, item); } writter.WriteEndArray();; } } writter.WriteEndArray(); writter.WriteEndObject(); } } writter.WriteEndArray(); writter.WriteEndObject(); } await StreamToWrite.FlushAsync(); }
private static async Task Execute(string sql, HttpContext context) { context.Response.Headers.Add("Content-Type", "application/json"); var koraliumService = context.RequestServices.GetService <IKoraliumTransportService>(); var logger = context.RequestServices.GetService <ILogger <IKoraliumTransportService> >(); QueryResult result = null; try { result = await koraliumService.Execute(sql, new Shared.SqlParameters(), context); } catch (SqlErrorException error) { logger.LogWarning(error.Message); await WriteError(context, 400, error.Message); return; } catch (AuthorizationFailedException authFailed) { logger.LogWarning(authFailed.Message, authFailed); await WriteError(context, 401, authFailed.Message); return; } catch (Exception e) { logger.LogError(e, "Unexpected exception thrown"); await WriteError(context, 500, "Internal error"); return; } var responseStream = new System.Text.Json.Utf8JsonWriter(context.Response.Body); IJsonEncoder[] encoders = new IJsonEncoder[result.Columns.Count]; JsonEncodedText[] names = new JsonEncodedText[result.Columns.Count]; for (int i = 0; i < encoders.Length; i++) { encoders[i] = EncoderHelper.GetEncoder(result.Columns[i]); names[i] = JsonEncodedText.Encode(result.Columns[i].Name); } System.Diagnostics.Stopwatch encodingWatch = new System.Diagnostics.Stopwatch(); encodingWatch.Start(); responseStream.WriteStartObject(); responseStream.WriteStartArray(_valuesText); foreach (var row in result.Result) { responseStream.WriteStartObject(); for (int i = 0; i < encoders.Length; i++) { responseStream.WritePropertyName(names[i]); encoders[i].Encode(in responseStream, in row); } responseStream.WriteEndObject(); } responseStream.WriteEndArray(); responseStream.WriteEndObject(); encodingWatch.Stop(); await responseStream.FlushAsync(); }
private static bool HandleEnumerable( JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, ref WriteStack state) { Debug.Assert(state.Current.JsonPropertyInfo !.ClassType == ClassType.Enumerable); if (state.Current.CollectionEnumerator == null) { IEnumerable?enumerable = (IEnumerable?)state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { // If applicable, we only want to ignore object properties. if (state.Current.JsonClassInfo !.ClassType != ClassType.Object || !state.Current.JsonPropertyInfo.IgnoreNullValues) { // Write a null object or enumerable. state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer, options, writeNull: true); } if (state.Current.PopStackOnEndCollection) { state.Pop(); } return(true); } if (options.ReferenceHandling.ShouldWritePreservedReferences()) { if (WriteReference(ref state, writer, options, ClassType.Enumerable, enumerable)) { return(WriteEndArray(ref state)); } } else { state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer, options); } state.Current.CollectionEnumerator = enumerable.GetEnumerator(); } if (state.Current.CollectionEnumerator.MoveNext()) { // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) { object?currentValue = state.Current.CollectionEnumerator.Current; GetRuntimeClassInfo(currentValue, ref elementClassInfo, options); } if (elementClassInfo.ClassType == ClassType.Value) { elementClassInfo.PolicyProperty !.WriteEnumerable(ref state, writer); } else if (state.Current.CollectionEnumerator.Current == null) { // Write a null object or enumerable. writer.WriteNullValue(); } else { // An object or another enumerator requires a new stack frame. object nextValue = state.Current.CollectionEnumerator.Current; state.Push(elementClassInfo, nextValue); } return(false); } // We are done enumerating. writer.WriteEndArray(); // Used for ReferenceHandling.Preserve if (state.Current.WriteWrappingBraceOnEndPreservedArray) { writer.WriteEndObject(); } return(WriteEndArray(ref state)); }
/// <summary> /// Writes this instance to provided writer. /// </summary> /// <param name="writer">Writer to wrtire this instance to.</param> public void WriteTo(Utf8JsonWriter writer) { var recursionStack = new Stack <RecursionStackFrame>(); recursionStack.Push(new RecursionStackFrame(null, this)); while (recursionStack.TryPop(out RecursionStackFrame currentFrame)) { if (currentFrame.PropertyValue == null) { // Current object/array is finished. // PropertyValue is null, so we need to check ValueKind: Debug.Assert(currentFrame.ValueKind == JsonValueKind.Object || currentFrame.ValueKind == JsonValueKind.Array); if (currentFrame.ValueKind == JsonValueKind.Object) { writer.WriteEndObject(); } if (currentFrame.ValueKind == JsonValueKind.Array) { writer.WriteEndArray(); } continue; } if (currentFrame.PropertyName != null) { writer.WritePropertyName(currentFrame.PropertyName); } switch (currentFrame.PropertyValue) { case JsonObject jsonObject: writer.WriteStartObject(); // Add end of object marker: recursionStack.Push(new RecursionStackFrame(null, null, JsonValueKind.Object)); // Add properties to recursion stack. Reverse enumerate to keep properties order: foreach (KeyValuePair <string, JsonNode> jsonProperty in jsonObject.Reverse()) { recursionStack.Push(new RecursionStackFrame(jsonProperty.Key, jsonProperty.Value)); } break; case JsonArray jsonArray: writer.WriteStartArray(); // Add end of array marker: recursionStack.Push(new RecursionStackFrame(null, null, JsonValueKind.Array)); // Add items to recursion stack. Reverse enumerate to keep items order: for (int i = jsonArray.Count - 1; i >= 0; i--) { recursionStack.Push(new RecursionStackFrame(null, jsonArray[i])); } break; case JsonString jsonString: writer.WriteStringValue(jsonString.Value); break; case JsonNumber jsonNumber: writer.WriteNumberValue(Encoding.UTF8.GetBytes(jsonNumber.ToString())); break; case JsonBoolean jsonBoolean: writer.WriteBooleanValue(jsonBoolean.Value); break; case JsonNull _: writer.WriteNullValue(); break; } writer.Flush(); } writer.Flush(); }
private static bool HandleEnumerable( JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, ref WriteStack state) { Debug.Assert(state.Current.JsonPropertyInfo.ClassType == ClassType.Enumerable); if (state.Current.Enumerator == null) { IEnumerable enumerable = (IEnumerable)state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { if (!state.Current.JsonPropertyInfo.IgnoreNullValues) { // Write a null object or enumerable. state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer, writeNull: true); } return(true); } state.Current.Enumerator = enumerable.GetEnumerator(); state.Current.WriteObjectOrArrayStart(ClassType.Enumerable, writer); } if (state.Current.Enumerator.MoveNext()) { // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) { object currentValue = state.Current.Enumerator.Current; GetRuntimeClassInfo(currentValue, ref elementClassInfo, options); } if (elementClassInfo.ClassType == ClassType.Value) { elementClassInfo.GetPolicyProperty().WriteEnumerable(ref state.Current, writer); } else if (state.Current.Enumerator.Current == null) { // Write a null object or enumerable. writer.WriteNullValue(); } else { // An object or another enumerator requires a new stack frame. object nextValue = state.Current.Enumerator.Current; state.Push(elementClassInfo, nextValue); } return(false); } // We are done enumerating. writer.WriteEndArray(); if (state.Current.PopStackOnEnd) { state.Pop(); } else { state.Current.EndArray(); } return(true); }