Skip to content

Commit

Permalink
replace read async with read of SqlReader for perf (#904)
Browse files Browse the repository at this point in the history
* Revert "Remove trigger binding for GA release (#732)" (#733)

This reverts commit 9713259.

* vBump release/trigger 2.* -> 3.* (#738)

* Add JObject support for SQL trigger (#722)

* add support for jobject and js, ps, python samples

* use utils JsonSerializeObject + comment

* Update src/TriggerBinding/SqlTriggerBindingProvider.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* fix unit test + pylint

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fix trigger connection not being retried when connection is closed (#731)

* Add Privacy Statement to README and telemetry message (#751)

* Add link to privacy statement

* Add privacy link to output message

* add to output message

* Fix typos

(cherry picked from commit a9565f7)

* enable trigger oop (#750)

* add sqltrigger attribute

* add SqlChange type

* enable oop test

* add check

* fix the null reference

* use GetLogger

* Enable debug logging for Python and PS samples (#754)

* enable debug logging for ps and python samples

* enable debug logs for js samples

* Add docs & logging information for Leases table info (#756)

* Add ProductsTriggerWithValidation tests for Python, JS, PS (#753)

* add js, py, ps ProductsTriggerWithValidation test

* fix test + missing file

* Further clarifications to trigger retry docs (#770)

* Further clarifications to trigger retry docs

* Update description

* increase timeout to 120 minutes (#776)

* Enable more tests for OOP trigger (#777)

* add more oop test samples

* update logger

* bump jackson dependency (#782)

* Add detailed trigger docs (#780)

* Filter out more default telemetry properties

(cherry picked from commit d6ea6d7)

* bring back trigger text

* Fixes

* Add SQLTrigger annotation to java library (#783)

* add SQLTrigger annotation to java library

* remove default values

* use enum for commandtype

* Disable CSX trigger tests

* fix regex for java library version (#788)

* Adding rest of Trigger integration tests for Python, PS, JS (#763)

* add js, py, ps ProductsTriggerWithValidation test

* fix test + missing file

* add tests

* remove extra comments + powershell compress

* update comment

* Skip more trigger tests for CSX (#791)

* Introduce Target Based Scaling (#598)

* Refactor SqlTriggerListener scaling to SqlTriggerMetricsProvider and SqlTriggerScaleMonitor

* Create SqlTriggerTargetScaler

* Refactor unit tests

* Refactor to include common queries for scaling and listener class to SqlTriggerUtils

* Add doc comments for scaling classes

* Update src/TriggerBinding/SqlTriggerTargetScaler.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Fix log statement

* Update WebJobs package

* Update nuget.config

* Address review comments

* Address review comments pt2

* Update src/TriggerBinding/SqlTriggerTargetScaler.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Address comments, test failures

* Fix packages lock file

* Fix error message

* Address comments and test failures

* Apply suggestions from code review

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Change in documentation

* Fix log level

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Enable trace level logging for tests (#795)

* Enable trace level logging for tests

* one more

* Add java trigger samples (#793)

* add java trigger samples

* update test-java

* add SqlChangeProduct type

* add rest of tests

* fix polling interval test

* Fix up performance tests & enable schedule (#799)

* Minor trigger doc updates (#800)

* Minor trigger doc updates

* fix

* enable rest of the trigger tests for oop (#798)

* enable all trigger tests for OOP

* undo

* fix test

* merge conflict

* remove Java

* add sample for python v2 model (#803)

* Fix logs

* fix compile

* remove delegate (#809)

Signed-off-by: Maddy Koripalli <makoripa@microsoft.com>

* add csx trigger samples (#806)

* add trigger samples for csx

* enable csx tests

* add copy trigger sample

* use utils.josnserialize

* separate utils file

* reuse utils from sql extension

* remove deleted references

* Cleanup trigger logging (#808)

* Cleanup trigger logging

* more

* fix compile

* Default log level of debug

* Fix scale monitor tests

* [Trigger] Update from main (#820)

* update java library 0.1.1 -> 1.0.0 (#804)

* Pin Node version to 18.15 (#818)

* Pin Node version to 18.15

* Update build pipeline

* Set node modules path for all

* Debug

* Pass in env var

* Update pipeline comments (#819)

---------

Co-authored-by: Lucy Zhang <luczhan@microsoft.com>

* [Trigger] Rename csharpscript and align host.json (#825)

* Merge branch 'main' into release/trigger

# Conflicts:
#	docs/SetupGuide_DotnetCSharpScript.md
#	samples/samples-csharp/host.json
#	test/Microsoft.Azure.WebJobs.Extensions.Sql.Tests.csproj

* Move triggers

* Fix java version in setup guide (#821)

* Refactor integration tests (#813)

* create database once

* fix compat level test

* fix compat + logs

* start func host in the beginning

* fix change tracking

* fix tests

* fix tests

* add CSharpscript and fix change tracking

* set port

* update xunit analyzers & temp skip failling tests

* update port from fixture

* pass console writeline as logger

* enable identity tests

* fix case sensitive tests + temp disable identity

* fix indent

* AddProductWithIdentityColumnIncluded fix

* AddProductWithIdentityColumnIncluded

* cleanup

* remove extra fixture

* default port

* fix csx

* Clean csx samples (#812)

* sql attribute not needed

* simplify the folder structure for csx

* add local.settings.json

* rename folders in proj file

* clean up logs and unused

* remove TriggerSamples folder

* update trigger docs for csx

* Fix compilation error (#835)

* Add retry for Trigger tests (#836)

* add retry logic

* fix the csx compilation error

* use xRetry

* replace with RetryTheory

* add diagnostic messages to logs

* Update Trigger Binding set up in SetupGuide_DotnetOutOfProc.md (#845)

* Update SetupGuide_DotnetOutOfProc.md

* fixes

* Update Trigger Binding set up in SetupGuide_Java.md (#846)

* Update SetupGuide_Java.md

* fix annotation

* Update SetupGuide_Javascript.md (#847)

* Update SetupGuide_Javascript.md

* fix toc

* FIx perf pipeline (#838)

* dont start func host in fixture for perf

* don't use fixture in perf test

* finally block

* Update SetupGuide_PowerShell.md (#848)

* Update SetupGuide_Python.md (#849)

* enable test TriggerWithException (#801)

* enable the TriggerWithException test

* update comment

* remove logger delegate

* fix error

* add retry

* remove Java test and try

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Add additional check for closed/broken connection errors (#862)

* add timestamp to global state table for lease table cleanup (#861)

* add LastAccessTime column to GlobalState

* update docs with clean up scripts

* update createtable

* add comments

* refine comments

* fix script error

* add print

* add test to check LastAccessTime column creation for existing triggers (#865)

* add LastAccessTime column to GlobalState

* update docs with clean up scripts

* update createtable

* add comments

* refine comments

* fix script error

* add print

* add test

* fix test error

* use constants

* Merge latest from main into trigger (#866)

* Fix the race condition by adding the extension reference to build first. (#839)

* fix the correct path separator

* add the extension ref to avoid race condition

* format files

* pack and copy the sql nupkg to local-packages after build (#853)

* copy to local packages before build

* AfterTargets since package is created after build

* make sure pack runs after build

* address comments

* Remove doc/sample references to preview bundle (#744)

* Remove doc/sample references to preview bundle

* Few more

* undo

* Powershell -> PowerShell

* fix version

* use scriptdom nuget (#864)

* Revert "Remove doc/sample references to preview bundle (#744)"

This reverts commit d7cd728.

* Fix nuget package versioning

---------

Co-authored-by: Maddy <12754347+MaddyDev@users.noreply.github.com>
Co-authored-by: Lucy Zhang <luczhan@microsoft.com>

* Revert "Remove doc/sample references to preview bundle (#744)"

This reverts commit d7cd728.

* add troubleshooting information to the overview doc (#871)

* add troubleshooting section

* update format

* Update docs/BindingsOverview.md

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update docs/BindingsOverview.md

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* clarifying view change tracking command (#873)

* Add sql trigger test for different data types (#876)

* add productcolumntypestriggertest

* try running only csharp

* try running js

* comment out column values check temporarily

* skip date and byte checks

* fix build error

* skip byte check

* remove date/time, add back binary

* fix build error

* remove only binary check

* remove only nchar and nvarchar

* check equality of nchar and nvarchar

* fix tests

* change nchar to test

* Bump Version of Grpc.Net.Client (#877)

* Bump version of Grpc.Net.Client

* Bump grpc.net.client to latest

* Update packages.lock

* Add to Directory.Packages.props

* Fix code coverage in trigger branch (#880)

* run only csharp test task

* comment out trigger tests

* don't start func hosts in the beginning

* start three functions in beginning

* start only csharp host

* fix build error

* start both csharp and java hosts

* start only csharp and oop hosts

* add logging for disposefunctionhosts

* start only csharp host

* revert commented out code

* add comment

* Fix schema parse error when using reserved keys as table names (#881)

* bracketed name for reserved words as table name

* add test

* add tests

* fix csx test

* enable test only for csharp

* fix TableNotPresentTest

* revert GetUserTableIdAsync change

* refactor GetUserTableIdAsync

* comment out Java test

* refactor code to use SqlObject

* Add LeasesTableName to SqlTriggerAttribute (#893)

* addLeasesTableNameSetting to SqlTriggerAttribute

* add provider test

* add samples

* remove setting

* add new constructor

* fix metrics provider

* add integration test

* fix oop

* fix test

* cleanup + pr comments

* quote escape leasestablename

* Add leasesTableName to SqlTrigger Java annotation (#897)

* add leasestablename to java sqltrigger

* add default value for commandtype

* remove sample

* update java library to 2.1.0-preview (#899)

* Update docs with LeasesTableName (#898)

* add leasestablename to docs

* fix links

* GetLeaseLockedRows for debug logging (#900)

* add isLeaseLocked into the getchanges query

* add log message

* add debug logging for row counts

* update log msg

* create a separate query for getting the locked rows

* update ver name

* update

* remove user table join

* unused var

* correct xml info

* address comments

* remove extra line

* dont throw

* Update src/TriggerBinding/SqlTableChangeMonitor.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* rename leasesTableName to bracketedLeasesTableName (#902)

* rename leasesTableName to bracketedLeasesTableName

* merge error

* update ReadAsync with Read

* replace ExecuteReaderAsync

* remove missed ExecuteReaderAsync

* remove ReadAsync

* remove async from updated methods

* merge main

* fix perf uml

* resolve doc conflicts

* resolve remaining conflicts

* fix incomplete merge

---------

Signed-off-by: Maddy Koripalli <makoripa@microsoft.com>
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
Co-authored-by: Lucy Zhang <luczhan@microsoft.com>
Co-authored-by: AmeyaRele <35621237+AmeyaRele@users.noreply.github.com>
Co-authored-by: Drew Skwiers-Koballa <dzsquared@users.noreply.github.com>
Co-authored-by: Chris LaFreniere <40371649+chlafreniere@users.noreply.github.com>
  • Loading branch information
6 people committed Nov 1, 2023
1 parent 82d398e commit cfb4b85
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 32 deletions.
17 changes: 8 additions & 9 deletions src/SqlAsyncCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ private async Task UpsertRowsAsync(IList<T> rows, SqlAttribute attribute, IConfi
string cacheKey = $"{connection.ConnectionString.GetHashCode()}-{fullTableName}";

ObjectCache cachedTables = MemoryCache.Default;
var tableInfo = cachedTables[cacheKey] as TableInformation;

int timeout = AZ_FUNC_TABLE_INFO_CACHE_TIMEOUT_MINUTES;
string timeoutEnvVar = Environment.GetEnvironmentVariable("AZ_FUNC_TABLE_INFO_CACHE_TIMEOUT_MINUTES");
Expand All @@ -199,11 +198,11 @@ private async Task UpsertRowsAsync(IList<T> rows, SqlAttribute attribute, IConfi
}
}

if (tableInfo == null)
if (!(cachedTables[cacheKey] is TableInformation tableInfo))
{
TelemetryInstance.TrackEvent(TelemetryEventName.TableInfoCacheMiss, props);
// set the columnNames for supporting T as JObject since it doesn't have columns in the member info.
tableInfo = await TableInformation.RetrieveTableInformationAsync(connection, fullTableName, this._logger, GetColumnNamesFromItem(rows.First()), this._serverProperties);
tableInfo = TableInformation.RetrieveTableInformation(connection, fullTableName, this._logger, GetColumnNamesFromItem(rows.First()), this._serverProperties);
var policy = new CacheItemPolicy
{
// Re-look up the primary key(s) after timeout (default timeout is 10 minutes)
Expand Down Expand Up @@ -550,7 +549,7 @@ AS NewData
/// <param name="objectColumnNames">Column names from the object</param>
/// <param name="serverProperties">EngineEdition and Edition of the target Sql Server.</param>
/// <returns>TableInformation object containing primary keys, column types, etc.</returns>
public static async Task<TableInformation> RetrieveTableInformationAsync(SqlConnection sqlConnection, string fullName, ILogger logger, IEnumerable<string> objectColumnNames, ServerProperties serverProperties)
public static TableInformation RetrieveTableInformation(SqlConnection sqlConnection, string fullName, ILogger logger, IEnumerable<string> objectColumnNames, ServerProperties serverProperties)
{
Dictionary<TelemetryPropertyName, string> sqlConnProps = sqlConnection.AsConnectionProps(serverProperties);
var table = new SqlObject(fullName);
Expand All @@ -564,9 +563,9 @@ public static async Task<TableInformation> RetrieveTableInformationAsync(SqlConn
{
string getColumnDefinitionsQuery = GetColumnDefinitionsQuery(table);
var cmdColDef = new SqlCommand(getColumnDefinitionsQuery, sqlConnection);
using (SqlDataReader rdr = await cmdColDef.ExecuteReaderAsyncWithLogging(logger, CancellationToken.None))
using (SqlDataReader rdr = cmdColDef.ExecuteReaderWithLogging(logger))
{
while (await rdr.ReadAsync())
while (rdr.Read())
{
string columnName = rdr[ColumnName].ToString();
columnDefinitionsFromSQL.Add(columnName, rdr[ColumnDefinition].ToString());
Expand Down Expand Up @@ -599,9 +598,9 @@ public static async Task<TableInformation> RetrieveTableInformationAsync(SqlConn
{
string getPrimaryKeysQuery = GetPrimaryKeysQuery(table);
var cmd = new SqlCommand(getPrimaryKeysQuery, sqlConnection);
using (SqlDataReader rdr = await cmd.ExecuteReaderAsyncWithLogging(logger, CancellationToken.None))
using (SqlDataReader rdr = cmd.ExecuteReaderWithLogging(logger))
{
while (await rdr.ReadAsync())
while (rdr.Read())
{
string columnName = rdr[ColumnName].ToString();
primaryKeys.Add(new PrimaryKey(columnName, bool.Parse(rdr[IsIdentity].ToString()), bool.Parse(rdr[HasDefault].ToString())));
Expand Down Expand Up @@ -656,7 +655,7 @@ public static async Task<TableInformation> RetrieveTableInformationAsync(SqlConn
sqlConnProps.Add(TelemetryPropertyName.QueryType, queryType.ToString());
sqlConnProps.Add(TelemetryPropertyName.HasIdentityColumn, hasIdentityColumnPrimaryKeys.ToString());
TelemetryInstance.TrackDuration(TelemetryEventName.GetTableInfo, tableInfoSw.ElapsedMilliseconds, sqlConnProps, durations);
logger.LogDebug($"RetrieveTableInformationAsync DB and Table: {sqlConnection.Database}.{fullName}. Primary keys: [{string.Join(",", primaryKeys.Select(pk => pk.Name))}].\nSQL Column and Definitions: [{string.Join(",", columnDefinitionsFromSQL)}]\nObject columns: [{string.Join(",", objectColumnNames)}]");
logger.LogDebug($"RetrieveTableInformation DB and Table: {sqlConnection.Database}.{fullName}. Primary keys: [{string.Join(",", primaryKeys.Select(pk => pk.Name))}].\nSQL Column and Definitions: [{string.Join(",", columnDefinitionsFromSQL)}]\nObject columns: [{string.Join(",", objectColumnNames)}]");
return new TableInformation(primaryKeys, primaryKeyProperties, columnDefinitionsFromSQL, queryType, hasIdentityColumnPrimaryKeys);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/SqlAsyncEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public ValueTask DisposeAsync()
/// </returns>
public ValueTask<bool> MoveNextAsync()
{
return new ValueTask<bool>(this.GetNextRowAsync());
return new ValueTask<bool>(this.GetNextRow());
}

/// <summary>
Expand All @@ -99,7 +99,7 @@ public ValueTask<bool> MoveNextAsync()
/// <returns>
/// True if there is another row left in the query to process, or false if this was the last row
/// </returns>
private async Task<bool> GetNextRowAsync()
private bool GetNextRow()
{
// check connection state before trying to access the reader
// if DisposeAsync has already closed it due to the issue described here https://github.com/Azure/azure-functions-sql-extension/issues/350
Expand All @@ -109,10 +109,10 @@ private async Task<bool> GetNextRowAsync()
{
using (SqlCommand command = SqlBindingUtilities.BuildCommand(this._attribute, this._connection))
{
this._reader = await command.ExecuteReaderAsync();
this._reader = command.ExecuteReader();
}
}
if (await this._reader.ReadAsync())
if (this._reader.Read())
{
this.Current = Utils.JsonDeserializeObject<T>(this.SerializeRow());
return true;
Expand Down
11 changes: 5 additions & 6 deletions src/SqlBindingUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public static async Task VerifyDatabaseSupported(SqlConnection connection, ILogg
string verifyDatabaseSupportedQuery = $"SELECT compatibility_level FROM sys.databases WHERE Name = DB_NAME()";

using (var verifyDatabaseSupportedCommand = new SqlCommand(verifyDatabaseSupportedQuery, connection))
using (SqlDataReader reader = await verifyDatabaseSupportedCommand.ExecuteReaderAsyncWithLogging(logger, cancellationToken))
using (SqlDataReader reader = verifyDatabaseSupportedCommand.ExecuteReaderWithLogging(logger))
{
if (!await reader.ReadAsync(cancellationToken))
{
Expand Down Expand Up @@ -326,7 +326,7 @@ public static async Task<ServerProperties> GetServerTelemetryProperties(SqlConne
string serverPropertiesQuery = $"SELECT SERVERPROPERTY('EngineEdition'), SERVERPROPERTY('Edition')";

using (var selectServerEditionCommand = new SqlCommand(serverPropertiesQuery, connection))
using (SqlDataReader reader = await selectServerEditionCommand.ExecuteReaderAsyncWithLogging(logger, cancellationToken))
using (SqlDataReader reader = selectServerEditionCommand.ExecuteReaderWithLogging(logger))
{
if (await reader.ReadAsync(cancellationToken))
{
Expand Down Expand Up @@ -431,22 +431,21 @@ public static async Task<int> ExecuteNonQueryAsyncWithLogging(this SqlCommand cm
}

/// <summary>
/// Calls ExecuteReaderAsync and logs an error if it fails before rethrowing.
/// Calls ExecuteReader and logs an error if it fails before rethrowing.
/// </summary>
/// <param name="cmd">The SqlCommand being executed</param>
/// <param name="logger">The logger</param>
/// <param name="cancellationToken">The cancellation token to pass to the call</param>
/// <param name="logCommand">Defaults to false and when set logs the command being executed</param>
/// <returns>The result of the call</returns>
public static async Task<SqlDataReader> ExecuteReaderAsyncWithLogging(this SqlCommand cmd, ILogger logger, CancellationToken cancellationToken, bool logCommand = false)
public static SqlDataReader ExecuteReaderWithLogging(this SqlCommand cmd, ILogger logger, bool logCommand = false)
{
try
{
if (logCommand)
{
logger.LogDebug($"Executing query={cmd.CommandText}");
}
return await cmd.ExecuteReaderAsync(cancellationToken);
return cmd.ExecuteReader();
}
catch (Exception e)
{
Expand Down
5 changes: 3 additions & 2 deletions src/TriggerBinding/SqlTableChangeMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,11 @@ private async Task GetTableChangesAsync(SqlConnection connection, CancellationTo
{
var commandSw = Stopwatch.StartNew();

using (SqlDataReader reader = await getChangesCommand.ExecuteReaderAsync(token))
using (SqlDataReader reader = getChangesCommand.ExecuteReader())
{
while (await reader.ReadAsync(token))
while (reader.Read())
{
token.ThrowIfCancellationRequested();
rows.Add(SqlBindingUtilities.BuildDictionaryFromSqlRow(reader));
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/TriggerBinding/SqlTriggerListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ public async Task StartAsync(CancellationToken cancellationToken)
await VerifyDatabaseSupported(connection, this._logger, cancellationToken);

int userTableId = await GetUserTableIdAsync(connection, this._userTable, this._logger, cancellationToken);
IReadOnlyList<(string name, string type)> primaryKeyColumns = await GetPrimaryKeyColumnsAsync(connection, userTableId, this._logger, this._userTable.FullName, cancellationToken);
IReadOnlyList<string> userTableColumns = await this.GetUserTableColumnsAsync(connection, userTableId, cancellationToken);
IReadOnlyList<(string name, string type)> primaryKeyColumns = GetPrimaryKeyColumnsAsync(connection, userTableId, this._logger, this._userTable.FullName, cancellationToken);
IReadOnlyList<string> userTableColumns = this.GetUserTableColumns(connection, userTableId, cancellationToken);

string bracketedLeasesTableName = GetBracketedLeasesTableName(this._userDefinedLeasesTableName, this._userFunctionId, userTableId);
this._telemetryProps[TelemetryPropertyName.LeasesTableName] = bracketedLeasesTableName;
Expand Down Expand Up @@ -208,7 +208,7 @@ public Task StopAsync(CancellationToken cancellationToken)
/// <summary>
/// Gets the column names of the user table.
/// </summary>
private async Task<IReadOnlyList<string>> GetUserTableColumnsAsync(SqlConnection connection, int userTableId, CancellationToken cancellationToken)
private IReadOnlyList<string> GetUserTableColumns(SqlConnection connection, int userTableId, CancellationToken cancellationToken)
{
const int NameIndex = 0, TypeIndex = 1, IsAssemblyTypeIndex = 2;
string getUserTableColumnsQuery = $@"
Expand All @@ -222,13 +222,14 @@ private async Task<IReadOnlyList<string>> GetUserTableColumnsAsync(SqlConnection
";

using (var getUserTableColumnsCommand = new SqlCommand(getUserTableColumnsQuery, connection))
using (SqlDataReader reader = await getUserTableColumnsCommand.ExecuteReaderAsyncWithLogging(this._logger, cancellationToken))
using (SqlDataReader reader = getUserTableColumnsCommand.ExecuteReaderWithLogging(this._logger))
{
var userTableColumns = new List<string>();
var userDefinedTypeColumns = new List<(string name, string type)>();

while (await reader.ReadAsync(cancellationToken))
while (reader.Read())
{
cancellationToken.ThrowIfCancellationRequested();
string columnName = reader.GetString(NameIndex);
string columnType = reader.GetString(TypeIndex);
bool isAssemblyType = reader.GetBoolean(IsAssemblyTypeIndex);
Expand Down Expand Up @@ -373,7 +374,7 @@ private async Task<long> InsertGlobalStateTableRowAsync(SqlConnection connection
string getMinValidVersionQuery = $"SELECT CHANGE_TRACKING_MIN_VALID_VERSION({userTableId});";

using (var getMinValidVersionCommand = new SqlCommand(getMinValidVersionQuery, connection, transaction))
using (SqlDataReader reader = await getMinValidVersionCommand.ExecuteReaderAsyncWithLogging(this._logger, cancellationToken))
using (SqlDataReader reader = getMinValidVersionCommand.ExecuteReaderWithLogging(this._logger))
{
if (!await reader.ReadAsync(cancellationToken))
{
Expand Down
2 changes: 1 addition & 1 deletion src/TriggerBinding/SqlTriggerMetricsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private async Task<long> GetUnprocessedChangeCountAsync()
await connection.OpenAsync();

int userTableId = await GetUserTableIdAsync(connection, this._userTable, this._logger, CancellationToken.None);
IReadOnlyList<(string name, string type)> primaryKeyColumns = await GetPrimaryKeyColumnsAsync(connection, userTableId, this._logger, this._userTable.FullName, CancellationToken.None);
IReadOnlyList<(string name, string type)> primaryKeyColumns = GetPrimaryKeyColumnsAsync(connection, userTableId, this._logger, this._userTable.FullName, CancellationToken.None);

// Use a transaction to automatically release the app lock when we're done executing the query
using (SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.RepeatableRead))
Expand Down
9 changes: 5 additions & 4 deletions src/TriggerBinding/SqlTriggerUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static class SqlTriggerUtils
/// <exception cref="InvalidOperationException">
/// Thrown if there are no primary key columns present in the user table or if their names conflict with columns in leases table.
/// </exception>
public static async Task<IReadOnlyList<(string name, string type)>> GetPrimaryKeyColumnsAsync(SqlConnection connection, int userTableId, ILogger logger, string userTableName, CancellationToken cancellationToken)
public static IReadOnlyList<(string name, string type)> GetPrimaryKeyColumnsAsync(SqlConnection connection, int userTableId, ILogger logger, string userTableName, CancellationToken cancellationToken)
{
const int NameIndex = 0, TypeIndex = 1, LengthIndex = 2, PrecisionIndex = 3, ScaleIndex = 4;
string getPrimaryKeyColumnsQuery = $@"
Expand All @@ -44,15 +44,16 @@ public static async Task<IReadOnlyList<(string name, string type)>> GetPrimaryKe
WHERE i.is_primary_key = 1 AND i.object_id = {userTableId};
";
using (var getPrimaryKeyColumnsCommand = new SqlCommand(getPrimaryKeyColumnsQuery, connection))
using (SqlDataReader reader = await getPrimaryKeyColumnsCommand.ExecuteReaderAsyncWithLogging(logger, cancellationToken))
using (SqlDataReader reader = getPrimaryKeyColumnsCommand.ExecuteReaderWithLogging(logger))
{
string[] variableLengthTypes = new[] { "varchar", "nvarchar", "nchar", "char", "binary", "varbinary" };
string[] variablePrecisionTypes = new[] { "numeric", "decimal" };

var primaryKeyColumns = new List<(string name, string type)>();

while (await reader.ReadAsync(cancellationToken))
while (reader.Read())
{
cancellationToken.ThrowIfCancellationRequested();
string name = reader.GetString(NameIndex);
string type = reader.GetString(TypeIndex);

Expand Down Expand Up @@ -96,7 +97,7 @@ internal static async Task<int> GetUserTableIdAsync(SqlConnection connection, Sq
string getObjectIdQuery = $"SELECT OBJECT_ID(N{userTable.QuotedFullName}, 'U');";

using (var getObjectIdCommand = new SqlCommand(getObjectIdQuery, connection))
using (SqlDataReader reader = await getObjectIdCommand.ExecuteReaderAsyncWithLogging(logger, cancellationToken))
using (SqlDataReader reader = getObjectIdCommand.ExecuteReaderWithLogging(logger))
{
if (!await reader.ReadAsync(cancellationToken))
{
Expand Down

0 comments on commit cfb4b85

Please sign in to comment.