Created
December 6, 2018 04:04
-
-
Save suryapratap/83c8f75b39753660f295c98d0673bf66 to your computer and use it in GitHub Desktop.
Create a JSON writer for IDataReader aiming to achieve a mild compression using a format similar to protobuf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Newtonsoft.Json.Serialization; | |
using System; | |
using System.Collections.Generic; | |
using System.Data; | |
namespace NewtonSoft.Json.Converters | |
{ | |
public class DataReaderConverter : JsonConverter | |
{ | |
public override bool CanConvert(Type objectType) | |
{ | |
return typeof(IDataReader).IsAssignableFrom(objectType); | |
} | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
throw new NotImplementedException(); | |
} | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
var reader = value as IDataReader; | |
if (reader == null) | |
{ | |
writer.WriteNull(); | |
return; | |
} | |
DefaultContractResolver r = serializer.ContractResolver as DefaultContractResolver; | |
Func<string, string> resolver; | |
if (r == null) | |
{ | |
resolver = (string colName) => r.GetResolvedPropertyName(colName); | |
} | |
else | |
{ | |
resolver = (string colName) => colName; | |
} | |
writer.WriteStartArray(); | |
MapTable(writer, reader, serializer, resolver); | |
while (reader.NextResult()) | |
{ | |
MapTable(writer, reader, serializer, resolver); | |
} | |
writer.WriteEndArray(); | |
} | |
private class Column | |
{ | |
public readonly Type Type; | |
public readonly string Name; | |
public readonly string Map; | |
public Column(Type type, string name,int ordinal) | |
{ | |
Type = type; | |
Name = name; | |
Map = "C" + ordinal.ToString(); | |
} | |
} | |
private void MapTable(JsonWriter writer, IDataReader reader, JsonSerializer serializer, Func<string, string> resolver) | |
{ | |
writer.WriteStartObject(); | |
var columns = new List<Column>(); | |
int fieldCount = reader.FieldCount; | |
writer.WritePropertyName("schema"); | |
writer.WriteStartObject(); | |
for (var i = 0; i < fieldCount; i++) | |
{ | |
var col = new Column(reader.GetFieldType(i), reader.GetName(i),i); | |
columns.Add(col); | |
writer.WritePropertyName(col.Map); | |
writer.WriteValue(col.Name); | |
} | |
writer.WriteEndObject(); | |
writer.WritePropertyName("data"); | |
writer.WriteStartArray(); | |
while (reader.Read()) | |
{ | |
writer.WriteStartObject(); | |
for (var i = 0; i < fieldCount; i++) | |
{ | |
var col = columns[i]; | |
var value = reader.GetValue(i); | |
if (serializer.NullValueHandling == NullValueHandling.Ignore && (value == null || value == DBNull.Value)) | |
{ | |
continue; | |
} | |
writer.WritePropertyName(resolver(col.Map)); | |
serializer.Serialize(writer, value, col.Type); | |
} | |
writer.WriteEndObject(); | |
} | |
writer.WriteEndArray(); | |
writer.WriteEndObject(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment