Skip to content

Commit 60e38a2

Browse files
When databasename is empty it should not be added to prefix. (#1605)
## Why make this change? - Reference associated issue using `#` syntax. e.g. Closes #XX - Include summary (1-2 sentences) of linked issue to avoid redirecting reviewers to different pages. Fixes issue mentioned in : #1604 ## What is this change? - Summary of how your changes work to give reviewers context of your intent. Added check to see if databasename is null or empty then we will not add it to the table prefix. ## How was this tested? - [ ] Integration Tests existing integration tests test this path of code - [ ] Unit Tests Added new test called checkTablePrefix. Chose to go with internalsvisibleto route as the main goal was to test gettableprefix method and ROI on moqing out components of the public method initializeasync to do the test was low. --------- Co-authored-by: Sean Leonard <[email protected]>
1 parent 7696013 commit 60e38a2

2 files changed

Lines changed: 51 additions & 7 deletions

File tree

src/Core/Services/MetadataProviders/SqlMetadataProvider.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Data.Common;
66
using System.Diagnostics.CodeAnalysis;
77
using System.Net;
8+
using System.Runtime.CompilerServices;
89
using System.Text;
910
using System.Text.Json;
1011
using System.Text.Json.Nodes;
@@ -18,6 +19,7 @@
1819
using Microsoft.Extensions.Logging;
1920
using static Azure.DataApiBuilder.Service.GraphQLBuilder.GraphQLNaming;
2021

22+
[assembly: InternalsVisibleTo("Azure.DataApiBuilder.Service.Tests")]
2123
namespace Azure.DataApiBuilder.Core.Services
2224
{
2325
/// <summary>
@@ -278,8 +280,6 @@ private async Task FillSchemaForStoredProcedureAsync(
278280
await QueryExecutor.SetManagedIdentityAccessTokenIfAnyAsync(conn);
279281
await conn.OpenAsync();
280282

281-
string tablePrefix = GetTablePrefix(conn.Database, schemaName);
282-
283283
string[] procedureRestrictions = new string[NUMBER_OF_RESTRICTIONS];
284284

285285
// To restrict the parameters for the current stored procedure, specify its name
@@ -1140,21 +1140,38 @@ private async Task<DataTable> FillSchemaForTableAsync(
11401140
};
11411141

11421142
string tablePrefix = GetTablePrefix(conn.Database, schemaName);
1143+
string queryPrefix = string.IsNullOrEmpty(tablePrefix) ? string.Empty : $"{tablePrefix}.";
11431144
selectCommand.CommandText
1144-
= $"SELECT * FROM {tablePrefix}.{SqlQueryBuilder.QuoteIdentifier(tableName)}";
1145+
= $"SELECT * FROM {queryPrefix}{SqlQueryBuilder.QuoteIdentifier(tableName)}";
11451146
adapterForTable.SelectCommand = selectCommand;
11461147

11471148
DataTable[] dataTable = adapterForTable.FillSchema(EntitiesDataSet, SchemaType.Source, tableName);
11481149
return dataTable[0];
11491150
}
11501151

1151-
private string GetTablePrefix(string databaseName, string schemaName)
1152+
internal string GetTablePrefix(string databaseName, string schemaName)
11521153
{
1153-
StringBuilder tablePrefix = new(SqlQueryBuilder.QuoteIdentifier(databaseName));
1154-
if (!string.IsNullOrEmpty(schemaName))
1154+
StringBuilder tablePrefix = new();
1155+
1156+
if (!string.IsNullOrEmpty(databaseName))
1157+
{
1158+
// Determine databaseName for prefix.
1159+
databaseName = SqlQueryBuilder.QuoteIdentifier(databaseName);
1160+
tablePrefix.Append(databaseName);
1161+
1162+
if (!string.IsNullOrEmpty(schemaName))
1163+
{
1164+
// Determine schemaName for prefix.
1165+
schemaName = SqlQueryBuilder.QuoteIdentifier(schemaName);
1166+
tablePrefix.Append($".{schemaName}");
1167+
}
1168+
}
1169+
else if (!string.IsNullOrEmpty(schemaName))
11551170
{
1171+
// Determine schemaName for prefix.
11561172
schemaName = SqlQueryBuilder.QuoteIdentifier(schemaName);
1157-
tablePrefix.Append($".{schemaName}");
1173+
// Database name is empty we just need the schema name.
1174+
tablePrefix.Append(schemaName);
11581175
}
11591176

11601177
return tablePrefix.ToString();

src/Service.Tests/Unittests/SqlMetadataProviderUnitTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
using Azure.DataApiBuilder.Config.ObjectModel;
99
using Azure.DataApiBuilder.Core.Authorization;
1010
using Azure.DataApiBuilder.Core.Configurations;
11+
using Azure.DataApiBuilder.Core.Resolvers;
1112
using Azure.DataApiBuilder.Core.Services;
1213
using Azure.DataApiBuilder.Service.Exceptions;
1314
using Azure.DataApiBuilder.Service.Tests.Configuration;
1415
using Azure.DataApiBuilder.Service.Tests.SqlTests;
16+
using Microsoft.Data.SqlClient;
1517
using Microsoft.Extensions.Logging;
1618
using Microsoft.VisualStudio.TestTools.UnitTesting;
1719
using Moq;
@@ -83,6 +85,31 @@ public async Task CheckExceptionForBadConnectionStringForMsSql(string connection
8385
await CheckExceptionForBadConnectionStringHelperAsync(DatabaseEngine, connectionString);
8486
}
8587

88+
/// <summary>
89+
/// <code>Do: </code> Tests with different combinations of connection string to ensure
90+
/// tableprefix generated is correctly.
91+
/// <code>Check: </code> Making sure table prefix matches expected prefix.
92+
/// </summary>
93+
[DataTestMethod]
94+
[DataRow("", "", "")]
95+
[DataRow("", "model", "[model]")]
96+
[DataRow("TestDB", "", "[TestDB]")]
97+
[DataRow("TestDB", "model", "[TestDB].[model]")]
98+
public void CheckTablePrefix(string databaseName, string schemaName, string expectedPrefix)
99+
{
100+
TestHelper.SetupDatabaseEnvironment(TestCategory.MSSQL);
101+
RuntimeConfig baseConfigFromDisk = SqlTestHelper.SetupRuntimeConfig();
102+
RuntimeConfigProvider runtimeConfigProvider = TestHelper.GenerateInMemoryRuntimeConfigProvider(baseConfigFromDisk);
103+
104+
ILogger<ISqlMetadataProvider> sqlMetadataLogger = new Mock<ILogger<ISqlMetadataProvider>>().Object;
105+
Mock<IQueryExecutor> queryExecutor = new();
106+
IQueryBuilder queryBuilder = new MsSqlQueryBuilder();
107+
108+
SqlMetadataProvider<SqlConnection, SqlDataAdapter, SqlCommand> provider = new MsSqlMetadataProvider(runtimeConfigProvider, queryExecutor.Object, queryBuilder, sqlMetadataLogger);
109+
string tableprefix = provider.GetTablePrefix(databaseName, schemaName);
110+
Assert.AreEqual(tableprefix, expectedPrefix);
111+
}
112+
86113
/// <summary>
87114
/// <code>Do: </code> Load runtimeConfig and set connection string and db type
88115
/// according to data row.

0 commit comments

Comments
 (0)