Skip to content

Commit 049a95c

Browse files
committed
fix json and csv output for dateonly and timespan
1 parent 9250633 commit 049a95c

File tree

8 files changed

+263
-130
lines changed

8 files changed

+263
-130
lines changed

src/FluentCommand.Csv/CsvCommandExtensions.cs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using CsvHelper;
88
using CsvHelper.Configuration;
99

10+
using FluentCommand.Extensions;
11+
1012
using Microsoft.IO;
1113

1214
namespace FluentCommand;
@@ -257,17 +259,53 @@ private static void WriteValue(IDataReader reader, CsvWriter writer, int index)
257259
return;
258260
}
259261

262+
#if NET6_0_OR_GREATER
263+
if (type == typeof(DateOnly))
264+
{
265+
var value = reader.GetValue<DateOnly>(index);
266+
var formatted = value.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
267+
268+
writer.WriteField(formatted);
269+
return;
270+
}
271+
272+
if (type == typeof(TimeOnly))
273+
{
274+
var value = reader.GetValue<TimeOnly>(index);
275+
string formatted = value.Second == 0 && value.Millisecond == 0
276+
? value.ToString("HH':'mm", CultureInfo.InvariantCulture)
277+
: value.ToString(CultureInfo.InvariantCulture);
278+
279+
writer.WriteField(formatted);
280+
return;
281+
}
282+
#endif
283+
260284
if (type == typeof(TimeSpan))
261285
{
262-
var value = reader.GetDateTime(index);
263-
writer.WriteField(value);
286+
var value = reader.GetValue<TimeSpan>(index);
287+
string formatted = value.Seconds == 0 && value.Milliseconds == 0
288+
? value.ToString(@"hh\:mm", CultureInfo.InvariantCulture)
289+
: value.ToString();
290+
291+
writer.WriteField(formatted);
264292
return;
265293
}
266294

267295
if (type == typeof(DateTime))
268296
{
269297
var value = reader.GetDateTime(index);
270-
writer.WriteField(value);
298+
var dataType = reader.GetDataTypeName(index).ToLowerInvariant();
299+
300+
if (string.Equals(dataType, "date", StringComparison.OrdinalIgnoreCase))
301+
{
302+
var formattedDate = value.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
303+
writer.WriteField(formattedDate);
304+
}
305+
else
306+
{
307+
writer.WriteField(value);
308+
}
271309
return;
272310
}
273311

src/FluentCommand.Json/JsonCommandExtensions.cs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
using System;
12
using System.Buffers;
23
using System.Data;
34
using System.Data.Common;
5+
using System.Globalization;
46
using System.Text;
57
using System.Text.Json;
68

9+
using FluentCommand.Extensions;
10+
711
using Microsoft.IO;
812

913
namespace FluentCommand;
@@ -173,7 +177,6 @@ private static void WriteValue(IDataReader reader, Utf8JsonWriter writer, int in
173177
}
174178

175179
var type = reader.GetFieldType(index);
176-
177180
if (type == typeof(string))
178181
{
179182
var value = reader.GetString(index);
@@ -237,17 +240,53 @@ private static void WriteValue(IDataReader reader, Utf8JsonWriter writer, int in
237240
return;
238241
}
239242

243+
#if NET6_0_OR_GREATER
244+
if (type == typeof(DateOnly))
245+
{
246+
var value = reader.GetValue<DateOnly>(index);
247+
var formatted = value.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
248+
249+
writer.WriteStringValue(formatted);
250+
return;
251+
}
252+
253+
if (type == typeof(TimeOnly))
254+
{
255+
var value = reader.GetValue<TimeOnly>(index);
256+
string formatted = value.Second == 0 && value.Millisecond == 0
257+
? value.ToString("HH':'mm", CultureInfo.InvariantCulture)
258+
: value.ToString("HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture);
259+
260+
writer.WriteStringValue(formatted);
261+
return;
262+
}
263+
#endif
264+
240265
if (type == typeof(TimeSpan))
241266
{
242-
var value = reader.GetDateTime(index);
243-
writer.WriteStringValue(value);
267+
var value = reader.GetValue<TimeSpan>(index);
268+
string formatted = value.Seconds == 0 && value.Milliseconds == 0
269+
? value.ToString(@"hh\:mm", CultureInfo.InvariantCulture)
270+
: value.ToString();
271+
272+
writer.WriteStringValue(formatted);
244273
return;
245274
}
246275

247276
if (type == typeof(DateTime))
248277
{
249278
var value = reader.GetDateTime(index);
250-
writer.WriteStringValue(value);
279+
var dataType = reader.GetDataTypeName(index).ToLowerInvariant();
280+
281+
if (string.Equals(dataType, "date", StringComparison.OrdinalIgnoreCase))
282+
{
283+
var formattedDate = value.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
284+
writer.WriteStringValue(formattedDate);
285+
}
286+
else
287+
{
288+
writer.WriteStringValue(value);
289+
}
251290
return;
252291
}
253292

test/FluentCommand.Entities/DataType.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System;
2+
using System.ComponentModel.DataAnnotations;
23
using System.ComponentModel.DataAnnotations.Schema;
34

45
namespace FluentCommand.Entities;
56

67
[Table("DataType", Schema = "dbo")]
78
public class DataType
89
{
9-
public int Id { get; set; }
10+
[Key]
11+
public long Id { get; set; }
1012

1113
public string Name { get; set; }
1214

test/FluentCommand.SqlServer.Tests/DataMergeGeneratorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public async System.Threading.Tasks.Task BuildMergeDataTypeTests()
166166
column.IsKey = true;
167167
column.CanUpdate = false;
168168

169-
var users = new List<DataType>
169+
var items = new List<DataType>
170170
{
171171
new() {
172172
Id = 1,
@@ -214,7 +214,7 @@ public async System.Threading.Tasks.Task BuildMergeDataTypeTests()
214214
}
215215
};
216216

217-
var listDataReader = new ListDataReader<DataType>(users);
217+
var listDataReader = new ListDataReader<DataType>(items);
218218

219219
var mergeDataStatement = DataMergeGenerator.BuildMerge(definition, listDataReader);
220220
mergeDataStatement.Should().NotBeNullOrEmpty();

test/FluentCommand.SqlServer.Tests/JsonTests.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,58 @@ public async Task QuerySelectAsync()
128128

129129
json.Should().NotBeNull();
130130
}
131+
132+
[Fact]
133+
public async Task QueryDataTypeSelectAsync()
134+
{
135+
var session = Services.GetRequiredService<IDataSession>();
136+
session.Should().NotBeNull();
137+
138+
var item = new DataType()
139+
{
140+
Id = DateTime.Now.Ticks,
141+
Name = "Test1",
142+
Boolean = false,
143+
Short = 2,
144+
Long = 200,
145+
Float = 200.20F,
146+
Double = 300.35,
147+
Decimal = 456.12M,
148+
DateTime = new DateTime(2024, 5, 1, 8, 0, 0),
149+
DateTimeOffset = new DateTimeOffset(2024, 5, 1, 8, 0, 0, TimeSpan.FromHours(-6)),
150+
Guid = Guid.Empty,
151+
TimeSpan = TimeSpan.FromHours(1),
152+
DateOnly = new DateOnly(2022, 12, 1),
153+
TimeOnly = new TimeOnly(1, 30, 0),
154+
BooleanNull = false,
155+
ShortNull = 2,
156+
LongNull = 200,
157+
FloatNull = 200.20F,
158+
DoubleNull = 300.35,
159+
DecimalNull = 456.12M,
160+
DateTimeNull = new DateTime(2024, 4, 1, 8, 0, 0),
161+
DateTimeOffsetNull = new DateTimeOffset(2024, 4, 1, 8, 0, 0, TimeSpan.FromHours(-6)),
162+
GuidNull = Guid.Empty,
163+
TimeSpanNull = TimeSpan.FromHours(1),
164+
DateOnlyNull = new DateOnly(2022, 12, 1),
165+
TimeOnlyNull = new TimeOnly(1, 30, 0),
166+
};
167+
168+
await session
169+
.Sql(builder => builder
170+
.Insert<DataType>()
171+
.Values(item)
172+
)
173+
.ExecuteAsync();
174+
175+
var json = await session
176+
.Sql(builder => builder
177+
.Select<DataType>()
178+
.OrderBy(p => p.Id)
179+
.Limit(0, 1000)
180+
)
181+
.QueryJsonAsync();
182+
183+
json.Should().NotBeNull();
184+
}
131185
}

test/FluentCommand.SqlServer.Tests/Scripts/Script001.Tracker.Schema.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ CREATE TABLE [dbo].[UserRole] (
146146

147147
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DataType]') AND type in (N'U'))
148148
CREATE TABLE [dbo].[DataType] (
149-
[Id] int NOT NULL,
149+
[Id] bigint NOT NULL,
150150
[Name] nvarchar(100) NOT NULL,
151151
[Boolean] bit NOT NULL,
152152
[Short] smallint NOT NULL,
@@ -176,7 +176,7 @@ CREATE TABLE [dbo].[DataType] (
176176
);
177177

178178
-- Types
179-
CREATE TYPE [dbo].[UserImportType] AS TABLE
179+
CREATE TYPE [dbo].[UserImportType] AS TABLE
180180
(
181181
[EmailAddress] [nvarchar](256) NOT NULL,
182182
[DisplayName] [nvarchar](256) NOT NULL,
@@ -249,5 +249,5 @@ CREATE INDEX [IX_UserLogin_UserId]
249249
ON [dbo].[UserLogin] ([UserId]);
250250

251251
-- change tracking
252-
ALTER TABLE [dbo].[User]
252+
ALTER TABLE [dbo].[User]
253253
ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = OFF);

0 commit comments

Comments
 (0)