diff --git a/src/Core/Resolvers/IQueryExecutor.cs b/src/Core/Resolvers/IQueryExecutor.cs index a9bb00b2a0..8110004444 100644 --- a/src/Core/Resolvers/IQueryExecutor.cs +++ b/src/Core/Resolvers/IQueryExecutor.cs @@ -24,15 +24,15 @@ public interface IQueryExecutor /// in the DbDataReader obtained after executing the query. /// Current request httpContext. /// List of string arguments to the DbDataReader handler. - /// dataSourceName against which to run query. + /// dataSourceName against which to run query. Can specify null or empty to run against default db. /// An object formed using the results of the query as returned by the given handler. public Task ExecuteQueryAsync( string sqltext, IDictionary parameters, Func?, Task>? dataReaderHandler, + string dataSourceName, HttpContext? httpContext = null, - List? args = null, - string dataSourceName = ""); + List? args = null); /// /// Extracts the rows from the given DbDataReader to populate diff --git a/src/Core/Resolvers/QueryExecutor.cs b/src/Core/Resolvers/QueryExecutor.cs index 0736d2fc1b..ba40651414 100644 --- a/src/Core/Resolvers/QueryExecutor.cs +++ b/src/Core/Resolvers/QueryExecutor.cs @@ -65,9 +65,9 @@ public QueryExecutor(DbExceptionParser dbExceptionParser, string sqltext, IDictionary parameters, Func?, Task>? dataReaderHandler, + string dataSourceName, HttpContext? httpContext = null, - List? args = null, - string dataSourceName = "") + List? args = null) { if (string.IsNullOrEmpty(dataSourceName)) { diff --git a/src/Core/Resolvers/SqlMutationEngine.cs b/src/Core/Resolvers/SqlMutationEngine.cs index d0bf798797..74356358cf 100644 --- a/src/Core/Resolvers/SqlMutationEngine.cs +++ b/src/Core/Resolvers/SqlMutationEngine.cs @@ -277,6 +277,7 @@ await queryExecutor.ExecuteQueryAsync( queryText, executeQueryStructure.Parameters, queryExecutor.GetJsonArrayAsync, + dataSourceName, GetHttpContext()); transactionScope.Complete(); @@ -840,9 +841,9 @@ await queryExecutor.ExecuteQueryAsync( queryString, queryParameters, queryExecutor.ExtractResultSetFromDbDataReader, + dataSourceName, GetHttpContext(), - primaryKeyExposedColumnNames.Count > 0 ? primaryKeyExposedColumnNames : sourceDefinition.PrimaryKey, - dataSourceName); + primaryKeyExposedColumnNames.Count > 0 ? primaryKeyExposedColumnNames : sourceDefinition.PrimaryKey); dbResultSetRow = dbResultSet is not null ? (dbResultSet.Rows.FirstOrDefault() ?? new DbResultSetRow()) : null; @@ -991,9 +992,9 @@ private async Task queryString, queryParameters, queryExecutor.GetMultipleResultSetsIfAnyAsync, + dataSourceName, GetHttpContext(), - new List { prettyPrintPk, entityName }, - dataSourceName); + new List { prettyPrintPk, entityName }); } private Dictionary PrepareParameters(RestRequestContext context) diff --git a/src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs b/src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs index c9cda7e8fd..3bc4e876e1 100644 --- a/src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs +++ b/src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs @@ -66,7 +66,8 @@ public override async Task PopulateTriggerMetadataForTable(string entityName, st JsonArray? resultArray = await QueryExecutor.ExecuteQueryAsync( sqltext: enumerateEnabledTriggers, parameters: parameters, - dataReaderHandler: QueryExecutor.GetJsonArrayAsync); + dataReaderHandler: QueryExecutor.GetJsonArrayAsync, + dataSourceName: _dataSourceName); using JsonDocument sqlResult = JsonDocument.Parse(resultArray!.ToJsonString()); foreach (JsonElement element in sqlResult.RootElement.EnumerateArray()) diff --git a/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs b/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs index 900812c9bb..65027306f2 100644 --- a/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs +++ b/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs @@ -1183,7 +1183,8 @@ private async Task PopulateColumnDefinitionsWithReadOnlyFlag(string tableName, s List? readOnlyFields = await QueryExecutor.ExecuteQueryAsync( sqltext: queryToGetReadOnlyColumns, parameters: parameters, - dataReaderHandler: SummarizeReadOnlyFieldsMetadata); + dataReaderHandler: SummarizeReadOnlyFieldsMetadata, + dataSourceName: _dataSourceName); if (readOnlyFields is not null && readOnlyFields.Count > 0) { @@ -1496,7 +1497,7 @@ private async Task PopulateForeignKeyDefinitionAsync() // Gather all the referencing and referenced columns for each pair // of referencing and referenced tables. PairToFkDefinition = await QueryExecutor.ExecuteQueryAsync( - queryForForeignKeyInfo, parameters, SummarizeFkMetadata, httpContext: null, args: null, _dataSourceName); + queryForForeignKeyInfo, parameters, SummarizeFkMetadata, _dataSourceName, httpContext: null, args: null); if (PairToFkDefinition is not null) { diff --git a/src/Service.Tests/Caching/DabCacheServiceIntegrationTests.cs b/src/Service.Tests/Caching/DabCacheServiceIntegrationTests.cs index e83c670bae..785c8a572b 100644 --- a/src/Service.Tests/Caching/DabCacheServiceIntegrationTests.cs +++ b/src/Service.Tests/Caching/DabCacheServiceIntegrationTests.cs @@ -74,7 +74,7 @@ public async Task FirstCacheServiceInvocationCallsFactory() IReadOnlyList actualExecuteQueryAsyncArguments = mockQueryExecutor.Invocations[0].Arguments; Assert.AreEqual(expected: queryMetadata.QueryText, actual: actualExecuteQueryAsyncArguments[0], message: "QueryText " + ERROR_FAILED_ARG_PASSTHROUGH); Assert.AreEqual(expected: queryMetadata.QueryParameters, actual: actualExecuteQueryAsyncArguments[1], message: "Query parameters " + ERROR_FAILED_ARG_PASSTHROUGH); - Assert.AreEqual(expected: queryMetadata.DataSource, actual: actualExecuteQueryAsyncArguments[5], message: "Data source " + ERROR_FAILED_ARG_PASSTHROUGH); + Assert.AreEqual(expected: queryMetadata.DataSource, actual: actualExecuteQueryAsyncArguments[3], message: "Data source " + ERROR_FAILED_ARG_PASSTHROUGH); } /// @@ -217,7 +217,7 @@ public async Task CacheServiceFactoryInvocationReturnsNull() IReadOnlyList actualExecuteQueryAsyncArguments = mockQueryExecutor.Invocations[0].Arguments; Assert.AreEqual(expected: queryMetadata.QueryText, actual: actualExecuteQueryAsyncArguments[0], message: "QueryText " + ERROR_FAILED_ARG_PASSTHROUGH); Assert.AreEqual(expected: queryMetadata.QueryParameters, actual: actualExecuteQueryAsyncArguments[1], message: "Query parameters " + ERROR_FAILED_ARG_PASSTHROUGH); - Assert.AreEqual(expected: queryMetadata.DataSource, actual: actualExecuteQueryAsyncArguments[5], message: "Data source " + ERROR_FAILED_ARG_PASSTHROUGH); + Assert.AreEqual(expected: queryMetadata.DataSource, actual: actualExecuteQueryAsyncArguments[3], message: "Data source " + ERROR_FAILED_ARG_PASSTHROUGH); // Validate that the null value retrned by the factory method is propogated through to and returned by the cache service. Assert.AreEqual(expected: null, actual: result, message: "Expected factory to return a null result."); @@ -422,9 +422,9 @@ private static Mock CreateMockQueryExecutor(string rawJsonRespon It.IsAny(), It.IsAny>(), It.IsAny?, Task>>(), + It.IsAny(), httpContext, - args, - It.IsAny()).Result) + args).Result) .Returns((JsonElement?)null); break; case ExecutorReturnType.Exception: @@ -432,9 +432,9 @@ private static Mock CreateMockQueryExecutor(string rawJsonRespon It.IsAny(), It.IsAny>(), It.IsAny?, Task>>(), + It.IsAny(), httpContext, - args, - It.IsAny()).Result) + args).Result) .Throws(new DataApiBuilderException( message: "DB ERROR", statusCode: HttpStatusCode.InternalServerError, @@ -446,9 +446,9 @@ private static Mock CreateMockQueryExecutor(string rawJsonRespon It.IsAny(), It.IsAny>(), It.IsAny?, Task>>(), + It.IsAny(), httpContext, - args, - It.IsAny()).Result) + args).Result) .Returns(executorJsonResponse.RootElement.Clone()); break; } diff --git a/src/Service.Tests/SqlTests/RestBootstrapTests/PrimaryKeyTestsForCompositeViews.cs b/src/Service.Tests/SqlTests/RestBootstrapTests/PrimaryKeyTestsForCompositeViews.cs index b37ba5fb54..8d8e81aea2 100644 --- a/src/Service.Tests/SqlTests/RestBootstrapTests/PrimaryKeyTestsForCompositeViews.cs +++ b/src/Service.Tests/SqlTests/RestBootstrapTests/PrimaryKeyTestsForCompositeViews.cs @@ -133,7 +133,7 @@ await SetupAndRunRestApiTest( public async Task TestCleanup() { string dropViewQuery = $"DROP VIEW IF EXISTS {_compositeViewName}"; - await _queryExecutor.ExecuteQueryAsync(dropViewQuery, parameters: null, dataReaderHandler: null); + await _queryExecutor.ExecuteQueryAsync(dropViewQuery, parameters: null, dataReaderHandler: null, dataSourceName: string.Empty); } } } diff --git a/src/Service.Tests/SqlTests/SqlTestBase.cs b/src/Service.Tests/SqlTests/SqlTestBase.cs index 57e4e9630c..56fd892d4b 100644 --- a/src/Service.Tests/SqlTests/SqlTestBase.cs +++ b/src/Service.Tests/SqlTests/SqlTestBase.cs @@ -238,7 +238,7 @@ private static async Task ExecuteQueriesOnDbAsync(List customQueries) { foreach (string query in customQueries) { - await _queryExecutor.ExecuteQueryAsync(query, parameters: null, dataReaderHandler: null); + await _queryExecutor.ExecuteQueryAsync(query, dataSourceName: string.Empty, parameters: null, dataReaderHandler: null); } } } @@ -367,6 +367,7 @@ protected static async Task ResetDbStateAsync() { await _queryExecutor.ExecuteQueryAsync( File.ReadAllText($"DatabaseSchema-{DatabaseEngine}.sql"), + dataSourceName: string.Empty, parameters: null, dataReaderHandler: null); } @@ -388,7 +389,8 @@ protected static async Task GetDatabaseResultAsync( await _queryExecutor.ExecuteQueryAsync( queryText, parameters: null, - _queryExecutor.GetJsonResultAsync); + _queryExecutor.GetJsonResultAsync, + string.Empty); result = sqlResult is not null ? sqlResult.RootElement.ToString() : @@ -400,7 +402,8 @@ await _queryExecutor.ExecuteQueryAsync( await _queryExecutor.ExecuteQueryAsync( queryText, parameters: null, - _queryExecutor.GetJsonArrayAsync); + _queryExecutor.GetJsonArrayAsync, + string.Empty); using JsonDocument sqlResult = resultArray is not null ? JsonDocument.Parse(resultArray.ToJsonString()) : null; result = sqlResult is not null ? sqlResult.RootElement.ToString() : null; } diff --git a/src/Service.Tests/Unittests/SqlQueryExecutorUnitTests.cs b/src/Service.Tests/Unittests/SqlQueryExecutorUnitTests.cs index 38f4c9f77c..999c3ff028 100644 --- a/src/Service.Tests/Unittests/SqlQueryExecutorUnitTests.cs +++ b/src/Service.Tests/Unittests/SqlQueryExecutorUnitTests.cs @@ -184,9 +184,9 @@ Mock queryExecutor It.IsAny(), It.IsAny>(), It.IsAny, Task>>(), + It.IsAny(), It.IsAny(), - It.IsAny>(), - It.IsAny())).CallBase(); + It.IsAny>())).CallBase(); DataApiBuilderException ex = await Assert.ThrowsExceptionAsync(async () => { @@ -194,6 +194,7 @@ await queryExecutor.Object.ExecuteQueryAsync( sqltext: string.Empty, parameters: new Dictionary(), dataReaderHandler: null, + dataSourceName: String.Empty, httpContext: null, args: null); }); @@ -242,14 +243,15 @@ Mock queryExecutor It.IsAny(), It.IsAny>(), It.IsAny, Task>>(), + It.IsAny(), It.IsAny(), - It.IsAny>(), - It.IsAny())).CallBase(); + It.IsAny>())).CallBase(); string sqltext = "SELECT * from books"; await queryExecutor.Object.ExecuteQueryAsync( sqltext: sqltext, + dataSourceName: String.Empty, parameters: new Dictionary(), dataReaderHandler: null, args: null);