Skip to content

Commit 9bb4918

Browse files
committed
Automap/Infer mapping for TimeSpan and TimeSpan? property types as long (ticks)
Closes #1705
1 parent 9a2a3b4 commit 9bb4918

File tree

5 files changed

+71
-4
lines changed

5 files changed

+71
-4
lines changed

Diff for: src/Nest/CommonAbstractions/SerializationBehavior/ElasticContractResolver.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ protected override JsonContract CreateContract(Type objectType)
4242
contract.Converter = new VerbatimDictionaryKeysJsonConverter();
4343
else if (objectType == typeof(ServerError))
4444
contract.Converter = new ServerErrorJsonConverter();
45-
else if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
45+
else if (objectType == typeof(DateTime) ||
46+
objectType == typeof(DateTime?) ||
47+
objectType == typeof(DateTimeOffset) ||
48+
objectType == typeof(DateTimeOffset?))
4649
contract.Converter = new IsoDateTimeConverter();
50+
else if (objectType == typeof(TimeSpan) ||
51+
objectType == typeof(TimeSpan?))
52+
contract.Converter = new TimeSpanConverter();
4753

4854
if (this._contractConverters.HasAny())
4955
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
internal class TimeSpanConverter : JsonConverter
7+
{
8+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
9+
{
10+
if (value == null)
11+
writer.WriteNull();
12+
else
13+
{
14+
var timeSpan = (TimeSpan) value;
15+
writer.WriteValue(timeSpan.Ticks);
16+
}
17+
}
18+
19+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
20+
{
21+
if (reader.TokenType == JsonToken.Null)
22+
{
23+
if (!objectType.IsGeneric() || objectType.GetGenericTypeDefinition() != typeof (Nullable<>))
24+
throw new JsonSerializationException($"Cannot convert null value to {objectType}.");
25+
26+
return null;
27+
}
28+
29+
if (reader.TokenType != JsonToken.Integer)
30+
throw new JsonSerializationException($"Cannot convert token of type {reader.TokenType} to {objectType}.");
31+
32+
return new TimeSpan((long)reader.Value);
33+
}
34+
35+
public override bool CanConvert(Type objectType) =>
36+
objectType == typeof (TimeSpan) || objectType == typeof (TimeSpan?);
37+
}
38+
}

Diff for: src/Nest/Mapping/Visitor/PropertyWalker.cs

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ private IProperty InferProperty(Type type)
106106
return new NumberProperty(NumberType.Byte);
107107
case "Int64":
108108
case "UInt32":
109+
case "TimeSpan":
109110
return new NumberProperty(NumberType.Long);
110111
case "Single":
111112
return new NumberProperty(NumberType.Float);

Diff for: src/Tests/Framework/MockData/CommitActivity.cs

+11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class CommitActivity
1111
public long SizeInBytes { get; set; }
1212
public double ConfidenceFactor { get; set; }
1313
public Developer Committer { get; set; }
14+
public TimeSpan? Duration { get; set; }
1415

1516
public static Faker<CommitActivity> Generator { get; } =
1617
new Faker<CommitActivity>()
@@ -20,6 +21,16 @@ public class CommitActivity
2021
.RuleFor(p => p.Message, p => p.Lorem.Paragraph(Gimme.Random.Number(1, 3)))
2122
.RuleFor(p => p.SizeInBytes, p => p.Random.Number(0, 100000))
2223
.RuleFor(p => p.ConfidenceFactor, p => p.Random.Double())
24+
.RuleFor(p => p.Duration, p => p.Random.ArrayElement(new TimeSpan?[]
25+
{
26+
TimeSpan.MinValue,
27+
TimeSpan.MaxValue,
28+
null,
29+
TimeSpan.Zero,
30+
TimeSpan.FromMinutes(7.5),
31+
TimeSpan.FromHours(4.23),
32+
TimeSpan.FromDays(5),
33+
}))
2334
;
2435
}
2536
}

Diff for: src/Tests/Mapping/Types/Core/Number/NumberMappingTests.cs

+14-3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class NumberTest
4343
public double Double { get; set; }
4444

4545
public decimal Decimal { get; set; }
46+
47+
public TimeSpan TimeSpan { get; set; }
4648
}
4749

4850
public class NumberMappingTests
@@ -114,7 +116,11 @@ public class NumberMappingTests
114116
@decimal = new
115117
{
116118
type = "double"
117-
}
119+
},
120+
timeSpan = new
121+
{
122+
type = "long"
123+
}
118124
}
119125
};
120126

@@ -174,8 +180,13 @@ public class NumberMappingTests
174180
)
175181
.Number(d => d
176182
.Name(o => o.Double)
177-
).Number(d => d
183+
)
184+
.Number(d => d
178185
.Name(o => o.Decimal)
179-
);
186+
)
187+
.Number(d => d
188+
.Name(o => o.TimeSpan)
189+
.Type(NumberType.Long)
190+
);
180191
}
181192
}

0 commit comments

Comments
 (0)