1 //------------------------------------------------------------------------------ 2 // <copyright file="OdbcConnectionFactory.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // <owner current="true" primary="true">Microsoft</owner> 6 // <owner current="true" primary="false">Microsoft</owner> 7 //------------------------------------------------------------------------------ 8 9 namespace System.Data.Odbc 10 { 11 using System; 12 using System.Data.Common; 13 using System.Data.ProviderBase; 14 using System.Diagnostics; 15 using System.Collections.Specialized; 16 using System.Configuration; 17 using System.IO; 18 using System.Runtime.Versioning; 19 20 sealed internal class OdbcConnectionFactory : DbConnectionFactory { OdbcConnectionFactory()21 private OdbcConnectionFactory() : base() {} 22 // At this time, the ODBC Provider doesn't have any connection pool counters 23 // because we'd only confuse people with "non-pooled" connections that are 24 // actually being pooled by the native pooler. 25 26 private const string _MetaData = ":MetaDataXml"; 27 private const string _defaultMetaDataXml = "defaultMetaDataXml"; 28 29 public static readonly OdbcConnectionFactory SingletonInstance = new OdbcConnectionFactory(); 30 31 override public DbProviderFactory ProviderFactory { 32 get { 33 return OdbcFactory.Instance; 34 } 35 } 36 CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)37 override protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) { 38 DbConnectionInternal result = new OdbcConnectionOpen(owningObject as OdbcConnection, options as OdbcConnectionString); 39 return result; 40 } 41 CreateConnectionOptions(string connectionString, DbConnectionOptions previous)42 override protected DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous) { 43 Debug.Assert(!ADP.IsEmpty(connectionString), "empty connectionString"); 44 OdbcConnectionString result = new OdbcConnectionString(connectionString, (null != previous)); 45 return result; 46 } 47 CreateConnectionPoolGroupOptions( DbConnectionOptions connectionOptions )48 override protected DbConnectionPoolGroupOptions CreateConnectionPoolGroupOptions( DbConnectionOptions connectionOptions ) { 49 // At this time, the ODBC provider only supports native pooling so we 50 // simply return NULL to indicate that. 51 return null; 52 } 53 CreateConnectionPoolGroupProviderInfo(DbConnectionOptions connectionOptions)54 override internal DbConnectionPoolGroupProviderInfo CreateConnectionPoolGroupProviderInfo (DbConnectionOptions connectionOptions) { 55 return new OdbcConnectionPoolGroupProviderInfo(); 56 } 57 58 // SxS (VSDD 545786): metadata files are opened from <.NetRuntimeFolder>\CONFIG\<metadatafilename.xml> 59 // this operation is safe in SxS because the file is opened in read-only mode and each NDP runtime accesses its own copy of the metadata 60 // under the runtime folder. 61 [ResourceExposure(ResourceScope.None)] 62 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] CreateMetaDataFactory(DbConnectionInternal internalConnection, out bool cacheMetaDataFactory)63 override protected DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal internalConnection, out bool cacheMetaDataFactory){ 64 65 Debug.Assert (internalConnection != null,"internalConnection may not be null."); 66 cacheMetaDataFactory = false; 67 68 OdbcConnection odbcOuterConnection = ((OdbcConnectionOpen)internalConnection).OuterConnection; 69 Debug.Assert(odbcOuterConnection != null,"outer connection may not be null."); 70 71 NameValueCollection settings = (NameValueCollection)PrivilegedConfigurationManager.GetSection("system.data.odbc"); 72 Stream XMLStream =null; 73 74 // get the DBMS Name 75 object driverName = null; 76 string stringValue = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DRIVER_NAME); 77 if (stringValue != null) { 78 driverName = stringValue; 79 } 80 81 if (settings != null){ 82 83 string [] values = null; 84 string metaDataXML = null; 85 // first try to get the provider specific xml 86 87 // if driver name is not supported we can't build the settings key needed to 88 // get the provider specific XML path 89 if (driverName != null){ 90 metaDataXML = ((string)driverName) + _MetaData; 91 values = settings.GetValues(metaDataXML); 92 } 93 94 // if we did not find provider specific xml see if there is new default xml 95 if (values == null) { 96 metaDataXML = _defaultMetaDataXml; 97 values = settings.GetValues(metaDataXML); 98 } 99 100 // If there is an XML file get it 101 if (values != null) { 102 XMLStream = ADP.GetXmlStreamFromValues(values,metaDataXML); 103 } 104 } 105 106 // use the embedded xml if the user did not over ride it 107 if (XMLStream == null){ 108 XMLStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.Odbc.OdbcMetaData.xml"); 109 cacheMetaDataFactory = true; 110 } 111 112 Debug.Assert (XMLStream != null,"XMLstream may not be null."); 113 114 String versionString = odbcOuterConnection.GetInfoStringUnhandled(ODBC32.SQL_INFO.DBMS_VER); 115 116 return new OdbcMetaDataFactory (XMLStream, 117 versionString, 118 versionString, 119 odbcOuterConnection); 120 } 121 GetConnectionPoolGroup(DbConnection connection)122 override internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnection connection) { 123 OdbcConnection c = (connection as OdbcConnection); 124 if (null != c) { 125 return c.PoolGroup; 126 } 127 return null; 128 } 129 GetInnerConnection(DbConnection connection)130 override internal DbConnectionInternal GetInnerConnection(DbConnection connection) { 131 OdbcConnection c = (connection as OdbcConnection); 132 if (null != c) { 133 return c.InnerConnection; 134 } 135 return null; 136 } 137 GetObjectId(DbConnection connection)138 override protected int GetObjectId(DbConnection connection) { 139 OdbcConnection c = (connection as OdbcConnection); 140 if (null != c) { 141 return c.ObjectID; 142 } 143 return 0; 144 } 145 PermissionDemand(DbConnection outerConnection)146 override internal void PermissionDemand(DbConnection outerConnection) { 147 OdbcConnection c = (outerConnection as OdbcConnection); 148 if (null != c) { 149 c.PermissionDemand(); 150 } 151 } 152 SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup)153 override internal void SetConnectionPoolGroup(DbConnection outerConnection, DbConnectionPoolGroup poolGroup) { 154 OdbcConnection c = (outerConnection as OdbcConnection); 155 if (null != c) { 156 c.PoolGroup = poolGroup; 157 } 158 } 159 SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to)160 override internal void SetInnerConnectionEvent(DbConnection owningObject, DbConnectionInternal to) { 161 OdbcConnection c = (owningObject as OdbcConnection); 162 if (null != c) { 163 c.SetInnerConnectionEvent(to); 164 } 165 } 166 SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from)167 override internal bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from) { 168 OdbcConnection c = (owningObject as OdbcConnection); 169 if (null != c) { 170 return c.SetInnerConnectionFrom(to, from); 171 } 172 return false; 173 } 174 SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to)175 override internal void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to) { 176 OdbcConnection c = (owningObject as OdbcConnection); 177 if (null != c) { 178 c.SetInnerConnectionTo(to); 179 } 180 } 181 182 183 184 } 185 } 186 187