From e0bb56d87510b657403b3ccd574b1c746a4ac142 Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Wed, 29 Mar 2023 18:52:33 -0700 Subject: [PATCH 1/6] Add case for datetimeoffset and datetime2 for MsSql --- src/Service.GraphQLBuilder/Sql/SchemaConverter.cs | 1 + src/Service.Tests/DatabaseSchema-MsSql.sql | 2 ++ src/Service/Parsers/EdmModelBuilder.cs | 1 + 3 files changed, 4 insertions(+) diff --git a/src/Service.GraphQLBuilder/Sql/SchemaConverter.cs b/src/Service.GraphQLBuilder/Sql/SchemaConverter.cs index 521e59616a..683f0b672c 100644 --- a/src/Service.GraphQLBuilder/Sql/SchemaConverter.cs +++ b/src/Service.GraphQLBuilder/Sql/SchemaConverter.cs @@ -243,6 +243,7 @@ public static string GetGraphQLTypeForColumnType(Type type) "Decimal" => DECIMAL_TYPE, "Boolean" => BOOLEAN_TYPE, "DateTime" => DATETIME_TYPE, + "DateTimeOffset" => DATETIME_TYPE, "Byte[]" => BYTEARRAY_TYPE, _ => throw new DataApiBuilderException( message: $"Column type {type} not handled by case. Please add a case resolving {type} to the appropriate GraphQL type", diff --git a/src/Service.Tests/DatabaseSchema-MsSql.sql b/src/Service.Tests/DatabaseSchema-MsSql.sql index f8dfb7a171..ba1dc9f65b 100644 --- a/src/Service.Tests/DatabaseSchema-MsSql.sql +++ b/src/Service.Tests/DatabaseSchema-MsSql.sql @@ -144,6 +144,8 @@ CREATE TABLE type_table( decimal_types decimal(38, 19), boolean_types bit, datetime_types datetime, + datetime2_types datetime2, + datetimeoffset_types datetimeoffset, bytearray_types varbinary(max), guid_types uniqueidentifier DEFAULT newid() ); diff --git a/src/Service/Parsers/EdmModelBuilder.cs b/src/Service/Parsers/EdmModelBuilder.cs index 1279c4817a..92de91423f 100644 --- a/src/Service/Parsers/EdmModelBuilder.cs +++ b/src/Service/Parsers/EdmModelBuilder.cs @@ -110,6 +110,7 @@ SourceDefinition sourceDefinition type = EdmPrimitiveTypeKind.Boolean; break; case "DateTime": + case "DateTimeOffset": type = EdmPrimitiveTypeKind.DateTimeOffset; break; case "Date": From 7951627cb6915678a8a5b468b43e725180d3cac2 Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Fri, 31 Mar 2023 16:34:23 -0700 Subject: [PATCH 2/6] Add datetimeoffset tests --- src/Service.Tests/DatabaseSchema-MsSql.sql | 29 +++++++++++++++---- .../Sql/SchemaConverterTests.cs | 1 + .../MsSqlGraphQLPaginationTests.cs | 2 ++ .../Unittests/ODataASTVisitorUnitTests.cs | 2 ++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Service.Tests/DatabaseSchema-MsSql.sql b/src/Service.Tests/DatabaseSchema-MsSql.sql index ba1dc9f65b..a49516bff9 100644 --- a/src/Service.Tests/DatabaseSchema-MsSql.sql +++ b/src/Service.Tests/DatabaseSchema-MsSql.sql @@ -143,9 +143,11 @@ CREATE TABLE type_table( float_types float, decimal_types decimal(38, 19), boolean_types bit, + date_types date, datetime_types datetime, datetime2_types datetime2, datetimeoffset_types datetimeoffset, + smalldatetime_types smalldatetime, bytearray_types varbinary(max), guid_types uniqueidentifier DEFAULT newid() ); @@ -361,12 +363,27 @@ INSERT INTO reviews(id, book_id, content) VALUES (567, 1, 'Indeed a great book') SET IDENTITY_INSERT reviews OFF SET IDENTITY_INSERT type_table ON -INSERT INTO type_table(id, byte_types, short_types, int_types, long_types, string_types, single_types, float_types, decimal_types, boolean_types, datetime_types, bytearray_types) VALUES - (1, 1, 1, 1, 1, '', 0.33, 0.33, 0.333333, 1, '1999-01-08 10:23:54', 0xABCDEF0123), - (2, 0, -1, -1, -1, 'lksa;jdflasdf;alsdflksdfkldj', -9.2, -9.2, -9.292929, 0, '1999-01-08 10:23:00', 0x98AB7511AABB1234), - (3, 0, -32768, -2147483648, -9223372036854775808, 'null', -3.4E38, -1.7E308, 2.929292E-19, 1, '1753-01-01 00:00:00.000', 0x00000000), - (4, 255, 32767, 2147483647, 9223372036854775807, 'null', 3.4E38, 1.7E308, 2.929292E-14, 1, '9999-12-31 23:59:59', 0xFFFFFFFF), - (5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO type_table(id, +byte_types, short_types, int_types, long_types, +string_types, +single_types, float_types, decimal_types, +boolean_types, +date_types, datetime_types, datetime2_types, datetimeoffset_types, smalldatetime_types, +bytearray_types) +VALUES + (1, 1, 1, 1, 1, '', 0.33, 0.33, 0.333333, 1, + '1999-01-08', '1999-01-08 10:23:54', '1999-01-08 10:23:54.9999999', '1999-01-08 10:23:54.9999999-14:00', '1999-01-08 10:23:54', + 0xABCDEF0123), + (2, 0, -1, -1, -1, 'lksa;jdflasdf;alsdflksdfkldj', -9.2, -9.2, -9.292929, 0, + '1999-01-08', '1999-01-08 10:23:00', '1999-01-08 10:23:00.9999999', '1999-01-08 10:23:00.9999999+13:00', '1999-01-08 10:23:00', + 0x98AB7511AABB1234), + (3, 0, -32768, -2147483648, -9223372036854775808, 'null', -3.4E38, -1.7E308, 2.929292E-19, 1, + '0001-01-01', '1753-01-01 00:00:00.000', '0001-01-01 00:00:00.0000000', '0001-01-01 00:00:00.0000000+0:00', '1900-01-01 00:00:00', + 0x00000000), + (4, 255, 32767, 2147483647, 9223372036854775807, 'null', 3.4E38, 1.7E308, 2.929292E-14, 1, + '9999-12-31', '9999-12-31 23:59:59', '9999-12-31 23:59:59.9999999', '9999-12-31 23:59:59.9999999+14:00', '2079-06-06', + 0xFFFFFFFF), + (5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); SET IDENTITY_INSERT type_table OFF SET IDENTITY_INSERT sales ON diff --git a/src/Service.Tests/GraphQLBuilder/Sql/SchemaConverterTests.cs b/src/Service.Tests/GraphQLBuilder/Sql/SchemaConverterTests.cs index 20bf8d158a..b4dae0bd36 100644 --- a/src/Service.Tests/GraphQLBuilder/Sql/SchemaConverterTests.cs +++ b/src/Service.Tests/GraphQLBuilder/Sql/SchemaConverterTests.cs @@ -226,6 +226,7 @@ public void MultipleColumnsAllMapped() [DataRow(typeof(decimal), DECIMAL_TYPE)] [DataRow(typeof(bool), BOOLEAN_TYPE)] [DataRow(typeof(DateTime), DATETIME_TYPE)] + [DataRow(typeof(DateTimeOffset), DATETIME_TYPE)] [DataRow(typeof(byte[]), BYTEARRAY_TYPE)] public void SystemTypeMapsToCorrectGraphQLType(Type systemType, string graphQLType) { diff --git a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs index 31023fdc72..631992f245 100644 --- a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs +++ b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs @@ -48,6 +48,8 @@ public static async Task SetupAsync(TestContext context) DisplayName = "Test after token for datetime values.")] [DataRow("bytearray_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, DisplayName = "Test after token for bytearray values.")] + [DataRow("datetimeoffset_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, + DisplayName = "Test after token for datetimeoffset values.")] [TestMethod] public override async Task RequestAfterTokenOnly( string exposedFieldName, diff --git a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs index 6765b0caa0..249e700b9c 100644 --- a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs +++ b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs @@ -58,6 +58,8 @@ public static async Task SetupAsync(TestContext context) [DataRow("datetime_types eq 2023-01-24T12:51:59Z", "([datetime_types] = @param1)", DisplayName = "Equate datetime types.")] [DataRow("bytearray_types eq 1000", "([bytearray_types] = @param1)", DisplayName = "Equate bytearray types.")] [DataRow("guid_types eq 9A19103F-16F7-4668-BE54-9A1E7A4F7556", "([guid_types] = @param1)", DisplayName = "Equate guid types.")] + [DataRow("datetimeoffset_types eq 9999-12-31 23:59:59.9999999+14:00", + "([datetimeoffset_types] = @param1)", DisplayName = "Equate datetimeoffset types.")] [TestMethod] public void VisitorLeftFieldRightConstantFilterTest(string filterExp, string expectedPredicate) { From c03ef65809b794a45ff28391d8d0a2cfbf0ddcd3 Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Fri, 31 Mar 2023 18:02:11 -0700 Subject: [PATCH 3/6] Fix the tests --- .../GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs | 3 ++- src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs | 2 +- .../Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs index 631992f245..0882ecc73f 100644 --- a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs +++ b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs @@ -48,7 +48,8 @@ public static async Task SetupAsync(TestContext context) DisplayName = "Test after token for datetime values.")] [DataRow("bytearray_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, DisplayName = "Test after token for bytearray values.")] - [DataRow("datetimeoffset_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, + [DataRow("datetimeoffset_types", "\"0001-01-01 00:00:00.0000000+0:00\"", + "\"9999-12-31T23:59:59.9999999+14:00\"", 3, 4, DisplayName = "Test after token for datetimeoffset values.")] [TestMethod] public override async Task RequestAfterTokenOnly( diff --git a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs index 249e700b9c..07ca9a383c 100644 --- a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs +++ b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs @@ -58,7 +58,7 @@ public static async Task SetupAsync(TestContext context) [DataRow("datetime_types eq 2023-01-24T12:51:59Z", "([datetime_types] = @param1)", DisplayName = "Equate datetime types.")] [DataRow("bytearray_types eq 1000", "([bytearray_types] = @param1)", DisplayName = "Equate bytearray types.")] [DataRow("guid_types eq 9A19103F-16F7-4668-BE54-9A1E7A4F7556", "([guid_types] = @param1)", DisplayName = "Equate guid types.")] - [DataRow("datetimeoffset_types eq 9999-12-31 23:59:59.9999999+14:00", + [DataRow("datetimeoffset_types eq 9998-12-31T21:59:59.99999-14:00", "([datetimeoffset_types] = @param1)", DisplayName = "Equate datetimeoffset types.")] [TestMethod] public void VisitorLeftFieldRightConstantFilterTest(string filterExp, string expectedPredicate) diff --git a/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs b/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs index 1f38b029b7..5f03207782 100644 --- a/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs +++ b/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs @@ -376,7 +376,8 @@ protected object ParseParamAsSystemType(string param, Type systemType) "Double" => double.Parse(param), "Decimal" => decimal.Parse(param), "Boolean" => bool.Parse(param), - "DateTime" => DateTimeOffset.Parse(param), + "DateTime" => DateTime.Parse(param), + "DateTimeOffset" => DateTimeOffset.Parse(param), "Guid" => Guid.Parse(param), _ => throw new NotSupportedException($"{systemType.Name} is not supported") }; From 36d4b6a870463e565d98e2c197643d2fde096147 Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Fri, 31 Mar 2023 18:22:08 -0700 Subject: [PATCH 4/6] Add more tests to DateTime2, smalldatetime, date types --- .../MsSqlGraphQLPaginationTests.cs | 13 +++++++++++-- .../Sql Query Structures/BaseSqlQueryStructure.cs | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs index 0882ecc73f..1a958ce783 100644 --- a/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs +++ b/src/Service.Tests/SqlTests/GraphQLPaginationTests/MsSqlGraphQLPaginationTests.cs @@ -43,14 +43,23 @@ public static async Task SetupAsync(TestContext context) DisplayName = "Test after token for decimal values.")] [DataRow("boolean_types", "false", "true", 2, 4, DisplayName = "Test after token for boolean values.")] + [DataRow("date_types", "\"0001-01-01\"", + "\"9999-12-31\"", 3, 4, + DisplayName = "Test after token for date values.")] [DataRow("datetime_types", "\"1753-01-01T00:00:00.000\"", "\"9999-12-31T23:59:59\"", 3, 4, DisplayName = "Test after token for datetime values.")] - [DataRow("bytearray_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, - DisplayName = "Test after token for bytearray values.")] + [DataRow("datetime2_types", "\"0001-01-01 00:00:00.0000000\"", + "\"9999-12-31T23:59:59.9999999\"", 3, 4, + DisplayName = "Test after token for datetime2 values.")] [DataRow("datetimeoffset_types", "\"0001-01-01 00:00:00.0000000+0:00\"", "\"9999-12-31T23:59:59.9999999+14:00\"", 3, 4, DisplayName = "Test after token for datetimeoffset values.")] + [DataRow("smalldatetime_types", "\"1900-01-01 00:00:00\"", + "\"2079-06-06T00:00:00\"", 3, 4, + DisplayName = "Test after token for smalldate values.")] + [DataRow("bytearray_types", "\"AAAAAA==\"", "\"/////w==\"", 3, 4, + DisplayName = "Test after token for bytearray values.")] [TestMethod] public override async Task RequestAfterTokenOnly( string exposedFieldName, diff --git a/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs b/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs index 5f03207782..2edaa6cee5 100644 --- a/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs +++ b/src/Service/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs @@ -376,8 +376,9 @@ protected object ParseParamAsSystemType(string param, Type systemType) "Double" => double.Parse(param), "Decimal" => decimal.Parse(param), "Boolean" => bool.Parse(param), - "DateTime" => DateTime.Parse(param), + "DateTime" => DateTimeOffset.Parse(param), "DateTimeOffset" => DateTimeOffset.Parse(param), + "Date" => DateOnly.Parse(param), "Guid" => Guid.Parse(param), _ => throw new NotSupportedException($"{systemType.Name} is not supported") }; From 8231d33e981609678fca12ac0b58433a4c383ee5 Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Fri, 31 Mar 2023 18:28:05 -0700 Subject: [PATCH 5/6] Add OData unit tests for smalldatetime, date, datetime2 --- .../Unittests/ODataASTVisitorUnitTests.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs index 07ca9a383c..27521f1418 100644 --- a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs +++ b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs @@ -55,11 +55,18 @@ public static async Task SetupAsync(TestContext context) [DataRow("float_types eq 65535.9", "([float_types] = @param1)", DisplayName = "Equate float types.")] [DataRow("decimal_types eq 25.5", "([decimal_types] = @param1)", DisplayName = "Equate decimal types.")] [DataRow("boolean_types eq true", "([boolean_types] = @param1)", DisplayName = "Equate boolean types.")] - [DataRow("datetime_types eq 2023-01-24T12:51:59Z", "([datetime_types] = @param1)", DisplayName = "Equate datetime types.")] - [DataRow("bytearray_types eq 1000", "([bytearray_types] = @param1)", DisplayName = "Equate bytearray types.")] - [DataRow("guid_types eq 9A19103F-16F7-4668-BE54-9A1E7A4F7556", "([guid_types] = @param1)", DisplayName = "Equate guid types.")] + [DataRow("date_types eq 9999-12-31", "([date_types] = @param1)", + DisplayName = "Equate date types.")] + [DataRow("datetime_types eq 2023-01-24T12:51:59Z", "([datetime_types] = @param1)", + DisplayName = "Equate datetime types.")] + [DataRow("datetime2_types eq 9998-12-31T21:59:59.99999", "([datetime2_types] = @param1)", + DisplayName = "Equate datetime2 types.")] [DataRow("datetimeoffset_types eq 9998-12-31T21:59:59.99999-14:00", "([datetimeoffset_types] = @param1)", DisplayName = "Equate datetimeoffset types.")] + [DataRow("smalldatetime_types eq 2079-06-06", "([smalldatetime_types] = @param1)", + DisplayName = "Equate smalldatetime types.")] + [DataRow("bytearray_types eq 1000", "([bytearray_types] = @param1)", DisplayName = "Equate bytearray types.")] + [DataRow("guid_types eq 9A19103F-16F7-4668-BE54-9A1E7A4F7556", "([guid_types] = @param1)", DisplayName = "Equate guid types.")] [TestMethod] public void VisitorLeftFieldRightConstantFilterTest(string filterExp, string expectedPredicate) { From 71dd730be5113528c3fe8ee4f36007262e8d98ab Mon Sep 17 00:00:00 2001 From: Aniruddh Munde Date: Fri, 31 Mar 2023 18:30:40 -0700 Subject: [PATCH 6/6] Specify timezone info even for datetime2 since it is mapped to DateTimeOffset as a System.Type to accommodate the range --- src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs index 27521f1418..c8e6313ce4 100644 --- a/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs +++ b/src/Service.Tests/Unittests/ODataASTVisitorUnitTests.cs @@ -59,7 +59,7 @@ public static async Task SetupAsync(TestContext context) DisplayName = "Equate date types.")] [DataRow("datetime_types eq 2023-01-24T12:51:59Z", "([datetime_types] = @param1)", DisplayName = "Equate datetime types.")] - [DataRow("datetime2_types eq 9998-12-31T21:59:59.99999", "([datetime2_types] = @param1)", + [DataRow("datetime2_types eq 9998-12-31T21:59:59.99999Z", "([datetime2_types] = @param1)", DisplayName = "Equate datetime2 types.")] [DataRow("datetimeoffset_types eq 9998-12-31T21:59:59.99999-14:00", "([datetimeoffset_types] = @param1)", DisplayName = "Equate datetimeoffset types.")]