diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index b396caf6fd819..5159f07bf3162 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -156,7 +156,7 @@ internal int PropertySetCount } } - internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset) + internal ItagDBPROP[] GetPropertySet(int index, out Guid propertyset) { if ((index < 0) || (PropertySetCount <= index)) { @@ -173,7 +173,7 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset) } tagDBPROPSET propset = new tagDBPROPSET(); - tagDBPROP[] properties = null; + ItagDBPROP[] properties = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); @@ -184,10 +184,10 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset) Marshal.PtrToStructure(propertySetPtr, propset); propertyset = propset.guidPropertySet; - properties = new tagDBPROP[propset.cProperties]; + properties = new ItagDBPROP[propset.cProperties]; for (int i = 0; i < properties.Length; ++i) { - properties[i] = new tagDBPROP(); + properties[i] = OleDbStructHelpers.CreateTagDbProp(); IntPtr ptr = ADP.IntPtrOffset(propset.rgProperties, i * ODB.SizeOf_tagDBPROP); Marshal.PtrToStructure(ptr, properties[i]); } @@ -202,7 +202,7 @@ internal tagDBPROP[] GetPropertySet(int index, out Guid propertyset) return properties; } - internal void SetPropertySet(int index, Guid propertySet, tagDBPROP[] properties) + internal void SetPropertySet(int index, Guid propertySet, ItagDBPROP[] properties) { if ((index < 0) || (PropertySetCount <= index)) { @@ -271,9 +271,9 @@ internal void SetPropertySet(int index, Guid propertySet, tagDBPROP[] properties internal static DBPropSet CreateProperty(Guid propertySet, int propertyId, bool required, object value) { - tagDBPROP dbprop = new tagDBPROP(propertyId, required, value); + ItagDBPROP dbprop = OleDbStructHelpers.CreateTagDbProp(propertyId, required, value); DBPropSet propertyset = new DBPropSet(1); - propertyset.SetPropertySet(0, propertySet, new tagDBPROP[1] { dbprop }); + propertyset.SetPropertySet(0, propertySet, new ItagDBPROP[1] { dbprop }); return propertyset; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index 23d7124e8434e..e503bcd12a389 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -1246,7 +1246,7 @@ internal object GetPropertyValue(Guid propertySet, int propertyID) if (null != _icommandText) { OleDbHResult hr; - tagDBPROP[] dbprops; + ItagDBPROP[] dbprops; UnsafeNativeMethods.ICommandProperties icommandProperties = ICommandProperties(); using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID)) @@ -1329,22 +1329,22 @@ private DBPropSet CommandPropertySets() { propSet = new DBPropSet(1); - tagDBPROP[] dbprops = new tagDBPROP[count]; + ItagDBPROP[] dbprops = new ItagDBPROP[count]; - dbprops[0] = new tagDBPROP(ODB.DBPROP_COMMANDTIMEOUT, false, CommandTimeout); + dbprops[0] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_COMMANDTIMEOUT, false, CommandTimeout); if (_executeQuery) { // 'Microsoft.Jet.OLEDB.4.0' default is DBPROPVAL_AO_SEQUENTIAL - dbprops[1] = new tagDBPROP(ODB.DBPROP_ACCESSORDER, false, ODB.DBPROPVAL_AO_RANDOM); + dbprops[1] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_ACCESSORDER, false, ODB.DBPROPVAL_AO_RANDOM); if (keyInfo) { // 'Unique Rows' property required for SQLOLEDB to retrieve things like 'BaseTableName' - dbprops[2] = new tagDBPROP(ODB.DBPROP_UNIQUEROWS, false, keyInfo); + dbprops[2] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_UNIQUEROWS, false, keyInfo); // otherwise 'Microsoft.Jet.OLEDB.4.0' doesn't support IColumnsRowset - dbprops[3] = new tagDBPROP(ODB.DBPROP_IColumnsRowset, false, true); + dbprops[3] = OleDbStructHelpers.CreateTagDbProp(ODB.DBPROP_IColumnsRowset, false, true); } } propSet.SetPropertySet(0, OleDbPropertySetGuid.Rowset, dbprops); diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 913475fff15a8..00d72f24cee83 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -355,7 +355,8 @@ public override void Close() private void DisposeMe(bool disposing) { if (disposing) - { // release mananged objects + { + // release mananged objects if (DesignMode) { // release the object pool in design-mode so that @@ -547,7 +548,7 @@ internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, strin StringBuilder builder = new StringBuilder(); Debug.Assert(1 == propSet.PropertySetCount, "too many PropertySets"); - tagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet); + ItagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet); Debug.Assert(1 == dbprops.Length, "too many Properties"); ODB.PropsetSetFailure(builder, description, dbprops[0].dwStatus); diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs index ebd13dcea2801..719af202bb04e 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs @@ -357,7 +357,7 @@ internal object GetDataSourceValue(Guid propertySet, int propertyID) internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) { OleDbHResult hr; - tagDBPROP[] dbprops; + ItagDBPROP[] dbprops; using (IDBPropertiesWrapper idbProperties = IDBProperties()) { using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID)) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs index 258538540e00d..ac2182ea34009 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs @@ -470,10 +470,10 @@ private Dictionary GetProviderInfo(string provider) for (int i = 0; i < count; ++i) { Guid propertyset; - tagDBPROP[] props = propset.GetPropertySet(i, out propertyset); + ItagDBPROP[] props = propset.GetPropertySet(i, out propertyset); // attach the default property value to the property info - foreach (tagDBPROP prop in props) + foreach (ItagDBPROP prop in props) { foreach (KeyValuePair entry in hash) { diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs index 38d750038223c..9ba4878743bc0 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs @@ -502,12 +502,8 @@ private void BuildSchemaTableInfoTable(int columnCount, IntPtr columnInfos, bool for (int i = 0, offset = 0; i < columnCount; ++i, offset += ODB.SizeOf_tagDBCOLUMNINFO) { Marshal.PtrToStructure(ADP.IntPtrOffset(columnInfos, offset), dbColumnInfo); -#if WIN32 - if (0 >= (int) dbColumnInfo.iOrdinal) { -#else - if (0 >= (long)dbColumnInfo.iOrdinal) + if ((ODB.IsRunningOnX86 && 0 >= (int)dbColumnInfo.iOrdinal) || (!ODB.IsRunningOnX86 && 0 >= (long)dbColumnInfo.iOrdinal)) { -#endif continue; } if (OleDbDataReader.DoColumnDropFilter(dbColumnInfo.dwFlags)) @@ -536,12 +532,15 @@ private void BuildSchemaTableInfoTable(int columnCount, IntPtr columnInfos, bool info.columnName = dbColumnInfo.pwszName; info.type = dbType; info.ordinal = dbColumnInfo.iOrdinal; -#if WIN32 + if (ODB.IsRunningOnX86) + { info.size = (int)dbColumnInfo.ulColumnSize; -#else - long maxsize = (long)dbColumnInfo.ulColumnSize; - info.size = (((maxsize < 0) || (int.MaxValue < maxsize)) ? int.MaxValue : (int)maxsize); -#endif + } + else + { + long maxsize = (long)dbColumnInfo.ulColumnSize; + info.size = (((maxsize < 0) || (int.MaxValue < maxsize)) ? int.MaxValue : (int)maxsize); + } info.flags = dbColumnInfo.dwFlags; info.precision = dbColumnInfo.bPrecision; info.scale = dbColumnInfo.bScale; @@ -1204,21 +1203,30 @@ private void ProcessResults(OleDbHResult hr) private static IntPtr AddRecordsAffected(IntPtr recordsAffected, IntPtr affected) { -#if WIN32 - if (0 <= (int)affected) { - if (0 <= (int)recordsAffected) { - return (IntPtr)((int)recordsAffected + (int)affected); -#else - if (0 <= (long)affected) + if (ODB.IsRunningOnX86) { - if (0 <= (long)recordsAffected) + if (0 <= (int)affected) { - return (IntPtr)((long)recordsAffected + (long)affected); -#endif + if (0 <= (int)recordsAffected) + { + return (IntPtr)((int)recordsAffected + (int)affected); + } + return affected; + } + return recordsAffected; + } + else + { + if (0 <= (long)affected) + { + if (0 <= (long)recordsAffected) + { + return (IntPtr)((long)recordsAffected + (long)affected); + } + return affected; } - return affected; + return recordsAffected; } - return recordsAffected; } public override int VisibleFieldCount @@ -1833,7 +1841,7 @@ private object GetPropertyValue(int propertyId) private object GetPropertyOnRowset(Guid propertySet, int propertyID) { OleDbHResult hr; - tagDBPROP[] dbprops; + ItagDBPROP[] dbprops; UnsafeNativeMethods.IRowsetInfo irowsetinfo = IRowsetInfo(); using (PropertyIDSet propidset = new PropertyIDSet(propertySet, propertyID)) @@ -2494,12 +2502,8 @@ internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset) info.isHidden = true; visibleCount--; } -#if WIN32 - else if (0 >= (int)info.ordinal) { -#else - else if (0 >= (long)info.ordinal) + else if ((ODB.IsRunningOnX86 && 0 >= (int)info.ordinal) || (!ODB.IsRunningOnX86 && 0 >= (long)info.ordinal)) { -#endif #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { @@ -2612,13 +2616,15 @@ int IComparable.CompareTo(object obj) { if (isHidden == (obj as MetaData).isHidden) { -#if WIN32 - return ((int)ordinal - (int)(obj as MetaData).ordinal); -#else - long v = ((long)ordinal - (long)(obj as MetaData).ordinal); - return ((0 < v) ? 1 : ((v < 0) ? -1 : 0)); -#endif - + if (ODB.IsRunningOnX86) + { + return ((int)ordinal - (int)(obj as MetaData).ordinal); + } + else + { + long v = ((long)ordinal - (long)(obj as MetaData).ordinal); + return ((0 < v) ? 1 : ((v < 0) ? -1 : 0)); + } } return (isHidden) ? 1 : -1; // ensure that all hidden columns come after non-hidden columns } diff --git a/src/libraries/System.Data.OleDb/src/OleDbStruct.cs b/src/libraries/System.Data.OleDb/src/OleDbStruct.cs index 2dfff4fc61101..4e81c374034ee 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbStruct.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbStruct.cs @@ -306,13 +306,52 @@ typedef struct tagDBPROP { VARIANT vValue; } #endif -#if (WIN32 && !ARCH_arm) - [StructLayoutAttribute(LayoutKind.Sequential, Pack = 2)] -#else + + internal interface ItagDBPROP + { + OleDbPropertyStatus dwStatus { get; } + object vValue { get; } + int dwPropertyID { get; } + } + + [StructLayout(LayoutKind.Sequential, Pack = 2)] + internal sealed class tagDBPROP_x86 : ItagDBPROP + { + OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus; + + object ItagDBPROP.vValue => this.vValue; + + int ItagDBPROP.dwPropertyID => this.dwPropertyID; + + internal int dwPropertyID; + internal int dwOptions; + internal OleDbPropertyStatus dwStatus; + + internal tagDBIDX columnid; + + // Variant + [MarshalAs(UnmanagedType.Struct)] internal object vValue; + + internal tagDBPROP_x86() + { + } + + internal tagDBPROP_x86(int propertyID, bool required, object value) + { + dwPropertyID = propertyID; + dwOptions = ((required) ? ODB.DBPROPOPTIONS_REQUIRED : ODB.DBPROPOPTIONS_OPTIONAL); + vValue = value; + } + } + [StructLayout(LayoutKind.Sequential, Pack = 8)] -#endif - internal sealed class tagDBPROP + internal sealed class tagDBPROP : ItagDBPROP { + OleDbPropertyStatus ItagDBPROP.dwStatus => this.dwStatus; + + object ItagDBPROP.vValue => this.vValue; + + int ItagDBPROP.dwPropertyID => this.dwPropertyID; internal int dwPropertyID; internal int dwOptions; internal OleDbPropertyStatus dwStatus; @@ -449,13 +488,55 @@ typedef struct tagDBPROPINFO { VARIANT vValues; } #endif -#if (WIN32 && !ARCH_arm) - [StructLayoutAttribute(LayoutKind.Sequential, Pack = 2)] -#else + + internal interface ItagDBPROPINFO + { + int dwPropertyID { get; } + int dwFlags { get; } + int vtType { get; } + object vValue { get; } + string pwszDescription { get; } + } + + [StructLayout(LayoutKind.Sequential, Pack = 2)] + internal sealed class tagDBPROPINFO_x86 : ItagDBPROPINFO + { + int ItagDBPROPINFO.dwPropertyID => this.dwPropertyID; + + int ItagDBPROPINFO.dwFlags => this.dwFlags; + + int ItagDBPROPINFO.vtType => this.vtType; + + object ItagDBPROPINFO.vValue => this.vValue; + + string ItagDBPROPINFO.pwszDescription => this.pwszDescription; + + [MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription; + + internal int dwPropertyID; + internal int dwFlags; + + internal short vtType; + + [MarshalAs(UnmanagedType.Struct)] internal object vValue; + + internal tagDBPROPINFO_x86() + { + } + } + [StructLayout(LayoutKind.Sequential, Pack = 8)] -#endif - internal sealed class tagDBPROPINFO + internal sealed class tagDBPROPINFO : ItagDBPROPINFO { + int ItagDBPROPINFO.dwPropertyID => this.dwPropertyID; + + int ItagDBPROPINFO.dwFlags => this.dwFlags; + + int ItagDBPROPINFO.vtType => this.vtType; + + object ItagDBPROPINFO.vValue => this.vValue; + + string ItagDBPROPINFO.pwszDescription => this.pwszDescription; [MarshalAs(UnmanagedType.LPWStr)] internal string pwszDescription; internal int dwPropertyID; @@ -488,4 +569,17 @@ internal struct tagDBPROPIDSET internal int cPropertyIDs; internal Guid guidPropertySet; } + + internal static class OleDbStructHelpers + { + internal static ItagDBPROPINFO CreateTagDbPropInfo() => + ODB.IsRunningOnX86 ? (ItagDBPROPINFO)new tagDBPROPINFO_x86() : new tagDBPROPINFO(); + + internal static ItagDBPROP CreateTagDbProp(int propertyID, bool required, object value) => + ODB.IsRunningOnX86 ? (ItagDBPROP) new tagDBPROP_x86(propertyID, required, value) : + new tagDBPROP(propertyID, required, value); + + internal static ItagDBPROP CreateTagDbProp() => + ODB.IsRunningOnX86 ? (ItagDBPROP) new tagDBPROP_x86() : new tagDBPROP(); + } } diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index 475c8f4d44bc4..796f9812fa9e4 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs @@ -558,22 +558,24 @@ internal static InvalidOperationException IDBInfoNotSupported() internal static readonly IntPtr DB_NULL_HCHAPTER = ADP.PtrZero; internal static readonly IntPtr DB_NULL_HROW = ADP.PtrZero; + internal static readonly bool IsRunningOnX86 = RuntimeInformation.ProcessArchitecture == Architecture.X86; + /*internal static readonly int SizeOf_tagDBPARAMINFO = Marshal.SizeOf(typeof(tagDBPARAMINFO));*/ internal static readonly int SizeOf_tagDBBINDING = Marshal.SizeOf(typeof(tagDBBINDING)); internal static readonly int SizeOf_tagDBCOLUMNINFO = Marshal.SizeOf(typeof(tagDBCOLUMNINFO)); internal static readonly int SizeOf_tagDBLITERALINFO = Marshal.SizeOf(typeof(tagDBLITERALINFO)); internal static readonly int SizeOf_tagDBPROPSET = Marshal.SizeOf(typeof(tagDBPROPSET)); - internal static readonly int SizeOf_tagDBPROP = Marshal.SizeOf(typeof(tagDBPROP)); + internal static readonly int SizeOf_tagDBPROP = IsRunningOnX86 ? Marshal.SizeOf(typeof(tagDBPROP_x86)) : Marshal.SizeOf(typeof(tagDBPROP)); internal static readonly int SizeOf_tagDBPROPINFOSET = Marshal.SizeOf(typeof(tagDBPROPINFOSET)); - internal static readonly int SizeOf_tagDBPROPINFO = Marshal.SizeOf(typeof(tagDBPROPINFO)); + internal static readonly int SizeOf_tagDBPROPINFO = IsRunningOnX86 ? Marshal.SizeOf(typeof(tagDBPROPINFO_x86)) : Marshal.SizeOf(typeof(tagDBPROPINFO)); internal static readonly int SizeOf_tagDBPROPIDSET = Marshal.SizeOf(typeof(tagDBPROPIDSET)); internal static readonly int SizeOf_Guid = Marshal.SizeOf(typeof(Guid)); internal static readonly int SizeOf_Variant = 8 + (2 * ADP.PtrSize); // 16 on 32bit, 24 on 64bit - internal static readonly int OffsetOf_tagDBPROP_Status = Marshal.OffsetOf(typeof(tagDBPROP), "dwStatus").ToInt32(); - internal static readonly int OffsetOf_tagDBPROP_Value = Marshal.OffsetOf(typeof(tagDBPROP), "vValue").ToInt32(); + internal static readonly int OffsetOf_tagDBPROP_Status = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROP_x86), "dwStatus").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROP), "dwStatus").ToInt32(); + internal static readonly int OffsetOf_tagDBPROP_Value = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROP_x86), "vValue").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROP), "vValue").ToInt32(); internal static readonly int OffsetOf_tagDBPROPSET_Properties = Marshal.OffsetOf(typeof(tagDBPROPSET), "rgProperties").ToInt32(); - internal static readonly int OffsetOf_tagDBPROPINFO_Value = Marshal.OffsetOf(typeof(tagDBPROPINFO), "vValue").ToInt32(); + internal static readonly int OffsetOf_tagDBPROPINFO_Value = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROPINFO_x86), "vValue").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROPINFO), "vValue").ToInt32(); internal static readonly int OffsetOf_tagDBPROPIDSET_PropertySet = Marshal.OffsetOf(typeof(tagDBPROPIDSET), "guidPropertySet").ToInt32(); internal static readonly int OffsetOf_tagDBLITERALINFO_it = Marshal.OffsetOf(typeof(tagDBLITERALINFO), "it").ToInt32(); internal static readonly int OffsetOf_tagDBBINDING_obValue = Marshal.OffsetOf(typeof(tagDBBINDING), "obValue").ToInt32(); @@ -687,8 +689,6 @@ internal static InvalidOperationException IDBInfoNotSupported() internal const string DbInfoKeywords = "DbInfoKeywords"; internal const string Keyword = "Keyword"; - internal static readonly bool IsRunningOnX86 = RuntimeInformation.ProcessArchitecture == Architecture.X86; - // Debug error string writeline internal static string ELookup(OleDbHResult hr) { diff --git a/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs b/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs index c89a6065f1310..1b77dfea7c659 100644 --- a/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs +++ b/src/libraries/System.Data.OleDb/src/PropertyInfoSet.cs @@ -69,7 +69,7 @@ internal Dictionary GetValues() propertyLookup = new Dictionary(StringComparer.OrdinalIgnoreCase); IntPtr setPtr = this.handle; - tagDBPROPINFO propinfo = new tagDBPROPINFO(); + ItagDBPROPINFO propinfo = OleDbStructHelpers.CreateTagDbPropInfo(); tagDBPROPINFOSET propinfoset = new tagDBPROPINFOSET(); for (int i = 0; i < setCount; ++i, setPtr = ADP.IntPtrOffset(setPtr, ODB.SizeOf_tagDBPROPINFOSET)) diff --git a/src/libraries/System.Data.OleDb/tests/OleDbConnectionTests.cs b/src/libraries/System.Data.OleDb/tests/OleDbConnectionTests.cs index 6321553da8076..f2e2a9ff06d6a 100644 --- a/src/libraries/System.Data.OleDb/tests/OleDbConnectionTests.cs +++ b/src/libraries/System.Data.OleDb/tests/OleDbConnectionTests.cs @@ -369,5 +369,53 @@ public void TransactionRollBackTest() transaction.Rollback(); } } + + [ConditionalFact(Helpers.IsDriverAvailable)] + public void ServerVersionTest() + { + using (OleDbConnection connection = new OleDbConnection(ConnectionString)) + { + connection.Open(); + string version = connection.ServerVersion; + Assert.False(string.IsNullOrEmpty(version)); + } + } + + [ConditionalFact(Helpers.IsDriverAvailable)] + public void ConnectionDatabasePropertyTest() + { + using (OleDbConnection connection = new OleDbConnection(ConnectionString)) + { + connection.Open(); + + // This call shouldn't throw + _ = connection.Database; + } + } + + public static IEnumerable ProviderNamesForConnectionString + { + get + { + // This provider must exist on the test OS. + yield return new object[] { Helpers.ProviderName }; + // This is a non-existent provider. + yield return new object[] { "Unavailable" }; + } + } + + [ConditionalTheory(Helpers.IsDriverAvailable)] + [MemberData(nameof(ProviderNamesForConnectionString))] + public void ConnectionStringTest(string provider) + { + // This should be a provider that exists in the test environment + OleDbConnectionStringBuilder builder = new OleDbConnectionStringBuilder + { + Provider = provider, + DataSource = "myDB.mdb" + }; + string connStr = builder.ConnectionString; + Assert.Equal($"Provider={provider};Data Source=myDB.mdb", connStr); + } } }