@@ -346,5 +346,160 @@ public static void WriteTransactionRollbackError(this SqlDiagnosticListener @thi
346
346
} ) ;
347
347
}
348
348
}
349
+
350
+ public static DiagnosticScope CreateCommandScope ( this SqlDiagnosticListener @this , SqlCommand command , SqlTransaction transaction , [ CallerMemberName ] string operationName = "" )
351
+ {
352
+ return DiagnosticScope . CreateCommandScope ( @this , command , transaction , operationName ) ;
353
+ }
354
+
355
+ public static DiagnosticTransactionScope CreateTransactionCommitScope ( this SqlDiagnosticListener @this , IsolationLevel isolationLevel , SqlConnection connection , SqlInternalTransaction transaction , [ CallerMemberName ] string operationName = "" )
356
+ {
357
+ return DiagnosticTransactionScope . CreateTransactionCommitScope ( @this , isolationLevel , connection , transaction , operationName ) ;
358
+ }
359
+
360
+ public static DiagnosticTransactionScope CreateTransactionRollbackScope ( this SqlDiagnosticListener @this , IsolationLevel isolationLevel , SqlConnection connection , SqlInternalTransaction transaction , string transactionName , [ CallerMemberName ] string operationName = "" )
361
+ {
362
+ return DiagnosticTransactionScope . CreateTransactionRollbackScope ( @this , isolationLevel , connection , transaction , transactionName , operationName ) ;
363
+ }
364
+ }
365
+
366
+ internal ref struct DiagnosticScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching
367
+ {
368
+ private const int CommandOperation = 1 ;
369
+ private const int ConnectionOpenOperation = 2 ;
370
+
371
+ private readonly SqlDiagnosticListener _diagnostics ;
372
+ private readonly int _operation ;
373
+ private readonly string _operationName ;
374
+ private readonly Guid _operationId ;
375
+ private readonly object _context1 ;
376
+ private readonly object _context2 ;
377
+ private Exception _exception ;
378
+
379
+ private DiagnosticScope ( SqlDiagnosticListener diagnostics , int operation , Guid operationsId , string operationName , object context1 , object context2 )
380
+ {
381
+ _diagnostics = diagnostics ;
382
+ _operation = operation ;
383
+ _operationId = operationsId ;
384
+ _operationName = operationName ;
385
+ _context1 = context1 ;
386
+ _context2 = context2 ;
387
+ _exception = null ;
388
+ }
389
+
390
+ public void Dispose ( )
391
+ {
392
+ switch ( _operation )
393
+ {
394
+ case CommandOperation :
395
+ if ( _exception != null )
396
+ {
397
+ _diagnostics . WriteCommandError ( _operationId , ( SqlCommand ) _context1 , ( SqlTransaction ) _context2 , _exception , _operationName ) ;
398
+ }
399
+ else
400
+ {
401
+ _diagnostics . WriteCommandAfter ( _operationId , ( SqlCommand ) _context1 , ( SqlTransaction ) _context2 , _operationName ) ;
402
+ }
403
+ break ;
404
+
405
+ case ConnectionOpenOperation :
406
+ if ( _exception != null )
407
+ {
408
+ _diagnostics . WriteConnectionOpenError ( _operationId , ( SqlConnection ) _context1 , _exception , _operationName ) ;
409
+ }
410
+ else
411
+ {
412
+ _diagnostics . WriteConnectionOpenAfter ( _operationId , ( SqlConnection ) _context1 , _operationName ) ;
413
+ }
414
+ break ;
415
+
416
+ // ConnectionCloseOperation is not implemented because it is conditionally emitted and that requires manual calls to the write apis
417
+ }
418
+ }
419
+
420
+ public void SetException ( Exception ex )
421
+ {
422
+ _exception = ex ;
423
+ }
424
+
425
+ public static DiagnosticScope CreateCommandScope ( SqlDiagnosticListener diagnostics , SqlCommand command , SqlTransaction transaction , [ CallerMemberName ] string operationName = "" )
426
+ {
427
+ Guid operationId = diagnostics . WriteCommandBefore ( command , transaction , operationName ) ;
428
+ return new DiagnosticScope ( diagnostics , CommandOperation , operationId , operationName , command , transaction ) ;
429
+ }
430
+ }
431
+
432
+ internal ref struct DiagnosticTransactionScope //: IDisposable //ref structs cannot implement interfaces but the compiler will use pattern matching
433
+ {
434
+ public const int TransactionCommit = 1 ;
435
+ public const int TransactionRollback = 2 ;
436
+
437
+ private readonly SqlDiagnosticListener _diagnostics ;
438
+ private readonly int _operation ;
439
+ private readonly Guid _operationId ;
440
+ private readonly string _operationName ;
441
+ private readonly IsolationLevel _isolationLevel ;
442
+ private readonly SqlConnection _connection ;
443
+ private readonly SqlInternalTransaction _transaction ;
444
+ private readonly string _transactionName ;
445
+ private Exception _exception ;
446
+
447
+ public DiagnosticTransactionScope ( SqlDiagnosticListener diagnostics , int operation , Guid operationId , string operationName , IsolationLevel isolationLevel , SqlConnection connection , SqlInternalTransaction transaction , string transactionName )
448
+ {
449
+ _diagnostics = diagnostics ;
450
+ _operation = operation ;
451
+ _operationId = operationId ;
452
+ _operationName = operationName ;
453
+ _isolationLevel = isolationLevel ;
454
+ _connection = connection ;
455
+ _transaction = transaction ;
456
+ _transactionName = transactionName ;
457
+ _exception = null ;
458
+ }
459
+
460
+ public void Dispose ( )
461
+ {
462
+ switch ( _operation )
463
+ {
464
+ case TransactionCommit :
465
+ if ( _exception != null )
466
+ {
467
+ _diagnostics . WriteTransactionCommitError ( _operationId , _isolationLevel , _connection , _transaction , _exception , _operationName ) ;
468
+ }
469
+ else
470
+ {
471
+ _diagnostics . WriteTransactionCommitAfter ( _operationId , _isolationLevel , _connection , _transaction , _operationName ) ;
472
+ }
473
+ break ;
474
+
475
+ case TransactionRollback :
476
+ if ( _exception != null )
477
+ {
478
+ _diagnostics . WriteTransactionRollbackError ( _operationId , _isolationLevel , _connection , _transaction , _exception , _transactionName , _operationName ) ;
479
+ }
480
+ else
481
+ {
482
+ _diagnostics . WriteTransactionRollbackAfter ( _operationId , _isolationLevel , _connection , _transaction , _transactionName , _operationName ) ;
483
+ }
484
+ break ;
485
+ }
486
+ }
487
+
488
+ public void SetException ( Exception ex )
489
+ {
490
+ _exception = ex ;
491
+ }
492
+
493
+ public static DiagnosticTransactionScope CreateTransactionCommitScope ( SqlDiagnosticListener diagnostics , IsolationLevel isolationLevel , SqlConnection connection , SqlInternalTransaction transaction , [ CallerMemberName ] string operationName = "" )
494
+ {
495
+ Guid operationId = diagnostics . WriteTransactionCommitBefore ( isolationLevel , connection , transaction , operationName ) ;
496
+ return new DiagnosticTransactionScope ( diagnostics , TransactionCommit , operationId , operationName , isolationLevel , connection , transaction , null ) ;
497
+ }
498
+
499
+ public static DiagnosticTransactionScope CreateTransactionRollbackScope ( SqlDiagnosticListener diagnostics , IsolationLevel isolationLevel , SqlConnection connection , SqlInternalTransaction transaction , string transactionName , [ CallerMemberName ] string operationName = "" )
500
+ {
501
+ Guid operationId = diagnostics . WriteTransactionRollbackBefore ( isolationLevel , connection , transaction , transactionName , operationName ) ;
502
+ return new DiagnosticTransactionScope ( diagnostics , TransactionCommit , operationId , operationName , isolationLevel , connection , transaction , transactionName ) ;
503
+ }
349
504
}
350
505
}
0 commit comments