Skip to content

Commit

Permalink
Add UnPivot Multi
Browse files Browse the repository at this point in the history
  • Loading branch information
nh43de committed Apr 19, 2024
1 parent 9fa18e0 commit a00f1ad
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 27 deletions.
35 changes: 33 additions & 2 deletions src/DataPowerTools.Tests/ReaderTests/UnPivotDataReaderTests.cs
Expand Up @@ -23,7 +23,7 @@ public void TestUnPivot()

var rr = ddr.AsCsv(true);

var checkCsv = @"""DimensionA"",""DimensionB"",""Value""
var checkCsv = @"""Dimension1"",""Dimension2"",""Value""
""10"",""0.01"",""1""
""10"",""0.03"",""2""
""10"",""0.05"",""3""
Expand All @@ -36,11 +36,42 @@ public void TestUnPivot()
""40"",""0.01"",""10""
""40"",""0.03"",""11""
""40"",""0.05"",""12""
";

Assert.AreEqual(checkCsv.Trim(), rr.Trim());
}




[TestMethod]
public void TestUnPivotMulti()
{
var csv = @"sku item count t096 t144 t192
sk1 sk 1 x x x
sk2 sk 2 x x x
sk3 sk 3 x x";

var dr = csv.ReadCsvString('\t', true);

var ddr = dr.UnPivot(3);

var rr = ddr.AsCsv(true);

var checkCsv = @"""Dimension1"",""Dimension2"",""Dimension3"",""Dimension4"",""Value""
""sk1"",""sk"",""1"",""t096"",""x""
""sk1"",""sk"",""1"",""t144"",""x""
""sk1"",""sk"",""1"",""t192"",""x""
""sk2"",""sk"",""2"",""t096"",""x""
""sk2"",""sk"",""2"",""t144"",""x""
""sk2"",""sk"",""2"",""t192"",""x""
""sk3"",""sk"",""3"",""t096"",""""
""sk3"",""sk"",""3"",""t144"",""x""
""sk3"",""sk"",""3"",""t192"",""x""
";

Assert.AreEqual(checkCsv, rr);
}




Expand Down
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using DataPowerTools.DataReaderExtensibility.Columns;
using DataPowerTools.DataStructures;
using DataPowerTools.Extensions;
Expand All @@ -14,15 +15,25 @@ namespace DataPowerTools.DataReaderExtensibility.TransformingReaders
/// <typeparam name="TDataReader"></typeparam>
public class UnPivotingDataReader<TDataReader> : ExtensibleDataReaderExplicit<TDataReader> where TDataReader : IDataReader
{
private readonly int _leftDimensionColumns;
//these need to be lazy because of the way data readers work (field names may not be available until first read)

private Lazy<BasicDataColumnInfo[]> _fieldInfo;

private int _index = 0; //the current pivot value index (starts at 1, range between 1 and field count - 1). Starts at zero and if zero then will do the initial read.

public UnPivotingDataReader(TDataReader reader) : base(reader)
private readonly int _fieldCount;

/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="leftDimensionColumns">Number of left dimensions</param>
public UnPivotingDataReader(TDataReader reader, int leftDimensionColumns = 1) : base(reader)
{
_leftDimensionColumns = leftDimensionColumns;
_fieldInfo = new Lazy<BasicDataColumnInfo[]>(() => DataReader.GetFieldInfo());
_fieldCount = 2 + _leftDimensionColumns;
}

public override object this[int index] //by field index
Expand All @@ -31,9 +42,9 @@ public UnPivotingDataReader(TDataReader reader) : base(reader)
public override object this[string fieldname] //by field name
=> GetValue(GetOrdinal(fieldname));

public override int FieldCount => 3;
public override int FieldCount => _fieldCount;

public override int Depth => DataReader.Depth * 3;
public override int Depth => DataReader.Depth * _fieldCount;

public override bool IsClosed => DataReader.IsClosed;

Expand All @@ -42,10 +53,13 @@ public UnPivotingDataReader(TDataReader reader) : base(reader)

public override object GetValue(int i)
{
return i switch
if (i < _leftDimensionColumns)
{
return DataReader.GetValue(i);
}

return (i - _leftDimensionColumns + 1) switch
{
//dimension A - from data reader first col
0 => DataReader.GetValue(0),
//dimension B - from header
1 => _fieldInfo.Value[_index].ColumnName,
//use _index
Expand Down Expand Up @@ -76,12 +90,13 @@ public override void Dispose()

public override string GetName(int i)
{
return i switch
if (i < _leftDimensionColumns + 1)
{
return $"Dimension{i + 1}";
}

return (i - _leftDimensionColumns + 1) switch
{
//dimension A - from data reader first col
0 => "DimensionA",
//dimension B - from header
1 => "DimensionB",
//use _index
2 => "Value",
_ => throw new ArgumentOutOfRangeException(nameof(i), "UnPivoting data reader only has 3 columns")
Expand All @@ -90,16 +105,18 @@ public override string GetName(int i)

public override int GetOrdinal(string name)
{
return name switch
{
//dimension A - from data reader first col
"DimensionA" => 0,
//dimension B - from header
"DimensionB" => 1,
//use _index
"Value" => 2,
_ => throw new ArgumentOutOfRangeException(nameof(name), "UnPivoting data reader only has 3 columns")
};
throw new NotImplementedException("Unpivoting data reader doesn't support getting by col name.");

//return name switch
//{
// //dimension A - from data reader first col
// "DimensionA" => 0,
// //dimension B - from header
// "DimensionB" => 1,
// //use _index
// "Value" => 2,
// _ => throw new ArgumentOutOfRangeException(nameof(name), "UnPivoting data reader only has 3 columns")
//};
}

public override void Close() => DataReader.Close();
Expand All @@ -108,7 +125,7 @@ public override bool Read()
{
if (_index == 0)
{
_index = 1;
_index = _leftDimensionColumns;
return DataReader.Read();
}

Expand All @@ -123,7 +140,7 @@ public override bool Read()
}

var r = DataReader.Read();
_index = 1;
_index = _leftDimensionColumns;

return r;
}
Expand Down
5 changes: 3 additions & 2 deletions src/DataPowerTools/Extensions/DataReaderExtensions.cs
Expand Up @@ -55,10 +55,11 @@ public static string AsCsv(this IDataReader reader, bool writeHeaders = true, bo
/// </summary>
/// <typeparam name="TDataReader"></typeparam>
/// <param name="reader"></param>
/// <param name="leftDimCount">Number of left dimensions</param>
/// <returns></returns>
public static UnPivotingDataReader<TDataReader> UnPivot<TDataReader>(this TDataReader reader) where TDataReader : IDataReader
public static UnPivotingDataReader<TDataReader> UnPivot<TDataReader>(this TDataReader reader, int leftDimCount = 1) where TDataReader : IDataReader
{
var rr = new UnPivotingDataReader<TDataReader>(reader);
var rr = new UnPivotingDataReader<TDataReader>(reader, leftDimCount);

return rr;
}
Expand Down

0 comments on commit a00f1ad

Please sign in to comment.