SqlConnectionPoolGroupProviderInfo.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //------------------------------------------------------------------------------
  2. // <copyright file="SqlConnectionPoolGroupProviderInfo.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. namespace System.Data.SqlClient
  9. {
  10. using System;
  11. using System.Data;
  12. using System.Data.Common;
  13. using System.Data.ProviderBase;
  14. sealed internal class SqlConnectionPoolGroupProviderInfo : DbConnectionPoolGroupProviderInfo {
  15. private string _alias;
  16. private System.Security.PermissionSet _failoverPermissionSet;
  17. private string _failoverPartner;
  18. private bool _useFailoverPartner;
  19. internal SqlConnectionPoolGroupProviderInfo(SqlConnectionString connectionOptions) {
  20. // This is for the case where the user specified the failover partner
  21. // in the connection string and we have not yet connected to get the
  22. // env change.
  23. _failoverPartner = connectionOptions.FailoverPartner;
  24. if (ADP.IsEmpty(_failoverPartner)) {
  25. _failoverPartner = null;
  26. }
  27. }
  28. internal string FailoverPartner {
  29. get {
  30. return _failoverPartner;
  31. }
  32. }
  33. internal bool UseFailoverPartner {
  34. get {
  35. return _useFailoverPartner;
  36. }
  37. }
  38. internal void AliasCheck(string server) {
  39. if (_alias != server) {
  40. lock(this) {
  41. if (null == _alias) {
  42. _alias = server;
  43. }
  44. else if (_alias != server) {
  45. Bid.Trace("<sc.SqlConnectionPoolGroupProviderInfo|INFO> alias change detected. Clearing PoolGroup\n");
  46. base.PoolGroup.Clear();
  47. _alias = server;
  48. }
  49. }
  50. }
  51. }
  52. private System.Security.PermissionSet CreateFailoverPermission(SqlConnectionString userConnectionOptions, string actualFailoverPartner) {
  53. string keywordToReplace;
  54. // RULES FOR CONSTRUCTING THE CONNECTION STRING TO DEMAND ON:
  55. //
  56. // 1) If no Failover Partner was specified in the original string:
  57. //
  58. // Server=actualFailoverPartner
  59. //
  60. // 2) If Failover Partner was specified in the original string:
  61. //
  62. // Server=originalValue; Failover Partner=actualFailoverPartner
  63. //
  64. // NOTE: in all cases, when we get a failover partner name from
  65. // the server, we will use that name over what was specified
  66. // in the original connection string.
  67. if (null == userConnectionOptions[SqlConnectionString.KEY.FailoverPartner]) {
  68. keywordToReplace = SqlConnectionString.KEY.Data_Source;
  69. }
  70. else {
  71. keywordToReplace = SqlConnectionString.KEY.FailoverPartner;
  72. }
  73. string failoverConnectionString = userConnectionOptions.ExpandKeyword(keywordToReplace, actualFailoverPartner);
  74. return (new SqlConnectionString(failoverConnectionString)).CreatePermissionSet();
  75. }
  76. internal void FailoverCheck(SqlInternalConnection connection, bool actualUseFailoverPartner, SqlConnectionString userConnectionOptions, string actualFailoverPartner) {
  77. if (UseFailoverPartner != actualUseFailoverPartner) {
  78. //
  79. Bid.Trace("<sc.SqlConnectionPoolGroupProviderInfo|INFO> Failover detected. failover partner='%ls'. Clearing PoolGroup\n", actualFailoverPartner);
  80. base.PoolGroup.Clear();
  81. _useFailoverPartner = actualUseFailoverPartner;
  82. }
  83. // Only construct a new permission set when we're connecting to the
  84. // primary data source, not the failover partner.
  85. if (!_useFailoverPartner && _failoverPartner != actualFailoverPartner) {
  86. // NOTE: we optimisitically generate the permission set to keep
  87. // lock short, but we only do this when we get a new
  88. // failover partner.
  89. //
  90. System.Security.PermissionSet failoverPermissionSet = CreateFailoverPermission(userConnectionOptions, actualFailoverPartner);
  91. lock (this) {
  92. if (_failoverPartner != actualFailoverPartner) {
  93. _failoverPartner = actualFailoverPartner;
  94. _failoverPermissionSet = failoverPermissionSet;
  95. }
  96. }
  97. }
  98. }
  99. internal void FailoverPermissionDemand() {
  100. if (_useFailoverPartner) {
  101. // Note that we only demand when there is a permission set, which only
  102. // happens once we've identified a failover situation in FailoverCheck
  103. System.Security.PermissionSet failoverPermissionSet = _failoverPermissionSet;
  104. if (null != failoverPermissionSet) {
  105. // demand on pooled failover connections
  106. failoverPermissionSet.Demand();
  107. }
  108. }
  109. }
  110. }
  111. }