Skip to content

Instantly share code, notes, and snippets.

@suryapratap
Created December 6, 2018 04:04
Show Gist options
  • Save suryapratap/83c8f75b39753660f295c98d0673bf66 to your computer and use it in GitHub Desktop.
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
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