Skip to content

Commit 6edb8d0

Browse files
Move magic numbers to constants (#465)
1 parent db2825c commit 6edb8d0

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

src/TriggerBinding/SqlTriggerConstants.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ internal static class SqlTriggerConstants
3232

3333
/// <summary>
3434
/// The resource name to use for getting the application lock. We use the same resource name for all instances
35-
/// of the function because there is some shared state across all the functions.
35+
/// of the function because there is some shared state across all the functions.
3636
/// </summary>
3737
/// <remarks>A future improvement could be to make unique application locks for each FuncId/TableId combination so that functions
3838
/// working on different tables aren't blocking each other</remarks>
3939
public const string AppLockResource = "_az_func_Trigger";
4040
/// <summary>
4141
/// Timeout for acquiring the application lock - 30sec chosen as a reasonable value to ensure we aren't
42-
/// hanging infinitely while also giving plenty of time for the blocking transaction to complete.
42+
/// hanging infinitely while also giving plenty of time for the blocking transaction to complete.
4343
/// </summary>
4444
public const int AppLockTimeoutMs = 30000;
4545

@@ -71,5 +71,10 @@ IF @result < 0
7171
BEGIN
7272
RAISERROR('Unable to acquire exclusive lock on {AppLockResource}. Result = %d', 16, 1, @result)
7373
END;";
74+
75+
/// <summary>
76+
/// There is already an object named '%.*ls' in the database.
77+
/// </summary>
78+
public const int ObjectAlreadyExistsErrorNumber = 2714;
7479
}
7580
}

src/TriggerBinding/SqlTriggerListener.cs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,14 @@ private async Task<int> GetUserTableIdAsync(SqlConnection connection, Cancellati
243243
/// </exception>
244244
private async Task<IReadOnlyList<(string name, string type)>> GetPrimaryKeyColumnsAsync(SqlConnection connection, int userTableId, CancellationToken cancellationToken)
245245
{
246+
const int NameIndex = 0, TypeIndex = 1, LengthIndex = 2, PrecisionIndex = 3, ScaleIndex = 4;
246247
string getPrimaryKeyColumnsQuery = $@"
247-
SELECT c.name, t.name, c.max_length, c.precision, c.scale
248+
SELECT
249+
c.name,
250+
t.name,
251+
c.max_length,
252+
c.precision,
253+
c.scale
248254
FROM sys.indexes AS i
249255
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
250256
INNER JOIN sys.columns AS c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
@@ -262,20 +268,20 @@ FROM sys.indexes AS i
262268

263269
while (await reader.ReadAsync(cancellationToken))
264270
{
265-
string name = reader.GetString(0);
266-
string type = reader.GetString(1);
271+
string name = reader.GetString(NameIndex);
272+
string type = reader.GetString(TypeIndex);
267273

268274
if (variableLengthTypes.Contains(type, StringComparer.OrdinalIgnoreCase))
269275
{
270276
// Special "max" case. I'm actually not sure it's valid to have varchar(max) as a primary key because
271277
// it exceeds the byte limit of an index field (900 bytes), but just in case
272-
short length = reader.GetInt16(2);
278+
short length = reader.GetInt16(LengthIndex);
273279
type += length == -1 ? "(max)" : $"({length})";
274280
}
275281
else if (variablePrecisionTypes.Contains(type))
276282
{
277-
byte precision = reader.GetByte(3);
278-
byte scale = reader.GetByte(4);
283+
byte precision = reader.GetByte(PrecisionIndex);
284+
byte scale = reader.GetByte(ScaleIndex);
279285
type += $"({precision},{scale})";
280286
}
281287

@@ -297,8 +303,12 @@ FROM sys.indexes AS i
297303
/// </summary>
298304
private async Task<IReadOnlyList<string>> GetUserTableColumnsAsync(SqlConnection connection, int userTableId, CancellationToken cancellationToken)
299305
{
306+
const int NameIndex = 0, TypeIndex = 1, IsAssemblyTypeIndex = 2;
300307
string getUserTableColumnsQuery = $@"
301-
SELECT c.name, t.name, t.is_assembly_type
308+
SELECT
309+
c.name,
310+
t.name,
311+
t.is_assembly_type
302312
FROM sys.columns AS c
303313
INNER JOIN sys.types AS t ON c.user_type_id = t.user_type_id
304314
WHERE c.object_id = {userTableId};
@@ -313,9 +323,9 @@ FROM sys.columns AS c
313323

314324
while (await reader.ReadAsync(cancellationToken))
315325
{
316-
string columnName = reader.GetString(0);
317-
string columnType = reader.GetString(1);
318-
bool isAssemblyType = reader.GetBoolean(2);
326+
string columnName = reader.GetString(NameIndex);
327+
string columnType = reader.GetString(TypeIndex);
328+
bool isAssemblyType = reader.GetBoolean(IsAssemblyTypeIndex);
319329

320330
userTableColumns.Add(columnName);
321331

@@ -374,12 +384,11 @@ IF SCHEMA_ID(N'{SchemaName}') IS NULL
374384
{
375385
TelemetryInstance.TrackException(TelemetryErrorName.CreateSchema, ex, this._telemetryProps);
376386
var sqlEx = ex as SqlException;
377-
if (sqlEx?.Number == 2714)
387+
if (sqlEx?.Number == ObjectAlreadyExistsErrorNumber)
378388
{
379-
// Error 2714 is for an object of that name already existing in the database. This generally shouldn't happen
380-
// since we check for its existence in the statement but occasionally a race condition can make it so
381-
// that multiple instances will try and create the schema at once. In that case we can just ignore the
382-
// error since all we care about is that the schema exists at all.
389+
// This generally shouldn't happen since we check for its existence in the statement but occasionally
390+
// a race condition can make it so that multiple instances will try and create the schema at once.
391+
// In that case we can just ignore the error since all we care about is that the schema exists at all.
383392
this._logger.LogWarning($"Failed to create schema '{SchemaName}'. Exception message: {ex.Message} This is informational only, function startup will continue as normal.");
384393
}
385394
else
@@ -427,12 +436,11 @@ PRIMARY KEY (UserFunctionID, UserTableID)
427436
{
428437
TelemetryInstance.TrackException(TelemetryErrorName.CreateGlobalStateTable, ex, this._telemetryProps);
429438
var sqlEx = ex as SqlException;
430-
if (sqlEx?.Number == 2714)
439+
if (sqlEx?.Number == ObjectAlreadyExistsErrorNumber)
431440
{
432-
// Error 2714 is for an object of that name already existing in the database. This generally shouldn't happen
433-
// since we check for its existence in the statement but occasionally a race condition can make it so
434-
// that multiple instances will try and create the table at once. In that case we can just ignore the
435-
// error since all we care about is that the table exists at all.
441+
// This generally shouldn't happen since we check for its existence in the statement but occasionally
442+
// a race condition can make it so that multiple instances will try and create the schema at once.
443+
// In that case we can just ignore the error since all we care about is that the schema exists at all.
436444
this._logger.LogWarning($"Failed to create global state table '{GlobalStateTableName}'. Exception message: {ex.Message} This is informational only, function startup will continue as normal.");
437445
}
438446
else
@@ -545,12 +553,11 @@ PRIMARY KEY ({primaryKeys})
545553
{
546554
TelemetryInstance.TrackException(TelemetryErrorName.CreateLeasesTable, ex, this._telemetryProps);
547555
var sqlEx = ex as SqlException;
548-
if (sqlEx?.Number == 2714)
556+
if (sqlEx?.Number == ObjectAlreadyExistsErrorNumber)
549557
{
550-
// Error 2714 is for an object of that name already existing in the database. This generally shouldn't happen
551-
// since we check for its existence in the statement but occasionally a race condition can make it so
552-
// that multiple instances will try and create the table at once. In that case we can just ignore the
553-
// error since all we care about is that the table exists at all.
558+
// This generally shouldn't happen since we check for its existence in the statement but occasionally
559+
// a race condition can make it so that multiple instances will try and create the schema at once.
560+
// In that case we can just ignore the error since all we care about is that the schema exists at all.
554561
this._logger.LogWarning($"Failed to create global state table '{leasesTableName}'. Exception message: {ex.Message} This is informational only, function startup will continue as normal.");
555562
}
556563
else

0 commit comments

Comments
 (0)