|
4 | 4 |
|
5 | 5 | namespace ParquetViewer.Engine.Types
|
6 | 6 | {
|
7 |
| - public class StructValue |
| 7 | + public class StructValue : IComparable<StructValue>, IComparable |
8 | 8 | {
|
9 | 9 | public string Name { get; }
|
10 | 10 |
|
11 |
| - //we are always guaranteed to have exactly one row in 'Data' since we don't allow nested structs right now |
| 11 | + //we are always guaranteed to have exactly one row in 'Data' as that is how we handle Structs |
12 | 12 | public DataRow Data { get; }
|
13 | 13 |
|
14 | 14 | public StructValue(string name, DataRow data)
|
@@ -113,5 +113,56 @@ private static void WriteValue(Utf8JsonWriter jsonWriter, object value, bool tru
|
113 | 113 | /// </summary>
|
114 | 114 | private static bool IsNumber(Type type) =>
|
115 | 115 | Array.Exists(type.GetInterfaces(), i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(INumber<>));
|
| 116 | + |
| 117 | + private IReadOnlyCollection<string>? _columnNames = null; |
| 118 | + private IReadOnlyCollection<string> GetFieldNames() => |
| 119 | + _columnNames ??= GetColumns(Data).Select(c => c.ColumnName).ToList().AsReadOnly(); |
| 120 | + |
| 121 | + /// <summary> |
| 122 | + /// Sorts by field names first, then by values |
| 123 | + /// </summary> |
| 124 | + public int CompareTo(StructValue? other) |
| 125 | + { |
| 126 | + if (other?.Data is null || other.GetFieldNames().Count == 0) |
| 127 | + return 1; |
| 128 | + |
| 129 | + if (Data is null || GetFieldNames().Count == 0) |
| 130 | + return -1; |
| 131 | + |
| 132 | + var otherColumnNames = string.Join("|", other.GetFieldNames()); |
| 133 | + var columnNames = string.Join("|", this.GetFieldNames()); |
| 134 | + |
| 135 | + int schemaComparison = columnNames.CompareTo(otherColumnNames); |
| 136 | + if (schemaComparison != 0) |
| 137 | + return schemaComparison; |
| 138 | + |
| 139 | + int fieldCount = GetFieldNames().Count; |
| 140 | + for (var i = 0; i < fieldCount; i++) |
| 141 | + { |
| 142 | + var otherValue = other.Data[i]; |
| 143 | + var value = Data[i]; |
| 144 | + int comparison = Helpers.CompareTo(value, otherValue); |
| 145 | + if (comparison != 0) |
| 146 | + return comparison; |
| 147 | + } |
| 148 | + |
| 149 | + return 0; //Both structs appear equal |
| 150 | + } |
| 151 | + |
| 152 | + private static IEnumerable<DataColumn> GetColumns(DataRow dataRow) |
| 153 | + { |
| 154 | + foreach (DataColumn column in dataRow.Table.Columns) |
| 155 | + { |
| 156 | + yield return column; |
| 157 | + } |
| 158 | + } |
| 159 | + |
| 160 | + public int CompareTo(object? obj) |
| 161 | + { |
| 162 | + if (obj is StructValue @struct) |
| 163 | + return CompareTo(@struct); |
| 164 | + else |
| 165 | + return 1; |
| 166 | + } |
116 | 167 | }
|
117 | 168 | }
|
0 commit comments