OleDbMetaDataFactory.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Data / System / Data / OleDb / OleDbMetaDataFactory.cs / 1 / OleDbMetaDataFactory.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// [....]
// Mugunm 
// 
//-----------------------------------------------------------------------------
 
namespace System.Data.OleDb{

    using System;
    using System.Data; 
    using System.IO;
    using System.Collections; 
    using System.Data.ProviderBase; 
    using System.Data.Common;
    using System.Diagnostics; 
    using System.Globalization;
    using System.Text;
    using System.Xml;
    using System.Xml.Schema; 

    internal sealed class OleDbMetaDataFactory : DbMetaDataFactory{ // V1.2.3300 
 
        private struct SchemaRowsetName {
            internal SchemaRowsetName(string schemaName, Guid schemaRowset) { 
                _schemaName = schemaName;
                _schemaRowset = schemaRowset;
            }
            internal readonly string  _schemaName; 
            internal readonly Guid    _schemaRowset;
        } 
 

 
        private const string _collectionName = "CollectionName";
        private const string _populationMechanism = "PopulationMechanism";
        private const string _prepareCollection = "PrepareCollection";
 
        private readonly SchemaRowsetName[] _schemaMapping;
 
        internal OleDbMetaDataFactory(Stream XMLStream, 
                                    string serverVersion,
                                    string serverVersionNormalized, 
                                    SchemaSupport[] schemaSupport):
            base(XMLStream, serverVersion, serverVersionNormalized) {

            // set up the colletion mane schema rowset guid mapping 
           _schemaMapping = new SchemaRowsetName[] {
 
                 new SchemaRowsetName(DbMetaDataCollectionNames.DataTypes,OleDbSchemaGuid.Provider_Types), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Catalogs,OleDbSchemaGuid.Catalogs),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Collations,OleDbSchemaGuid.Collations), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Columns,OleDbSchemaGuid.Columns),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Indexes,OleDbSchemaGuid.Indexes),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Procedures,OleDbSchemaGuid.Procedures),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.ProcedureColumns,OleDbSchemaGuid.Procedure_Columns), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.ProcedureParameters,OleDbSchemaGuid.Procedure_Parameters),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Tables,OleDbSchemaGuid.Tables), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Views,OleDbSchemaGuid.Views)}; 

            // verify the existance of the table in the data set 
            DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections];
            if (metaDataCollectionsTable == null){
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.MetaDataCollections);
            } 

            // copy the table filtering out any rows that don't apply to the current version of the provider 
            metaDataCollectionsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.MetaDataCollections, null); 

            // verify the existance of the table in the data set 
            DataTable restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions];
            if (restrictionsTable != null){
                // copy the table filtering out any rows that don't apply to the current version of the provider
                restrictionsTable= CloneAndFilterCollection(DbMetaDataCollectionNames.Restrictions, null); 
            }
 
            // need to filter out any of the collections where 
            // 1) it is populated using prepare collection
            // 2) it is in the collection to schema rowset mapping above 
            // 3) the provider does not support the necessary schema rowset


 
            DataColumn populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism];
            if ((null == populationMechanism) || (typeof(System.String) != populationMechanism.DataType)) { 
                throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections,_populationMechanism); 
            }
            DataColumn collectionName = metaDataCollectionsTable.Columns[_collectionName]; 
            if ((null == collectionName) || (typeof(System.String) != collectionName.DataType)) {
                 throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections,_collectionName);
            }
            DataColumn restrictionCollectionName = null; 
            if (restrictionsTable != null){
                restrictionCollectionName = restrictionsTable.Columns[_collectionName]; 
                if ((null == restrictionCollectionName) || (typeof(System.String) != restrictionCollectionName.DataType)) { 
                    throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.Restrictions,_collectionName);
                } 
            }

            foreach (DataRow collection in metaDataCollectionsTable.Rows){
 
                string populationMechanismValue = collection[populationMechanism] as string;
                if (ADP.IsEmpty(populationMechanismValue )) { 
                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections,_populationMechanism); 
                }
                string collectionNameValue = collection[collectionName] as string; 
                if (ADP.IsEmpty(collectionNameValue)) {
                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections,_collectionName);
                }
 
                if (populationMechanismValue == _prepareCollection) {
                    // is the collection in the mapping 
                    int mapping = -1; 
                    for (int i = 0; i < _schemaMapping.Length; i++){
                        if (_schemaMapping[i]._schemaName == collectionNameValue){ 
                            mapping = i;
                            break;
                        }
                    } 
                    // no go on to the next collection
                    if (mapping == -1) { 
                        continue; 
                    }
 
                    // does the provider support the necessary schema rowset
                    bool isSchemaRowsetSupported = false;
                    if (schemaSupport != null){
                        for (int i = 0; i < schemaSupport.Length; i++){ 
                            if (_schemaMapping[mapping]._schemaRowset == schemaSupport[i]._schemaRowset){
                                isSchemaRowsetSupported = true; 
                                break; 
                            }
                        } 
                    }
                    // if not delete the row from the table
                    if (isSchemaRowsetSupported == false){
                        // but first delete any related restrictions 
                        if (restrictionsTable != null) {
                            foreach (DataRow restriction in restrictionsTable.Rows) { 
                                string restrictionCollectionNameValue = restriction[restrictionCollectionName] as string; 
                                if (ADP.IsEmpty(restrictionCollectionNameValue)) {
                                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.Restrictions,_collectionName); 
                                }
                                if (collectionNameValue == restrictionCollectionNameValue) {
                                    restriction.Delete();
                                } 
                            }
                            restrictionsTable.AcceptChanges(); 
                        } 
                        collection.Delete();
                    } 

                }
            }
 
            // replace the original table with the updated one
            metaDataCollectionsTable.AcceptChanges(); 
            CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]); 
            CollectionDataSet.Tables.Add(metaDataCollectionsTable);
 
            if (restrictionsTable != null) {
                CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]);
                CollectionDataSet.Tables.Add(restrictionsTable);
            } 

        } 
 
        private String BuildRegularExpression(string invalidChars, string invalidStartingChars){
 
            StringBuilder regularExpression = new StringBuilder("[^");
            ADP.EscapeSpecialCharacters(invalidStartingChars,regularExpression);
            regularExpression.Append("][^");
            ADP.EscapeSpecialCharacters(invalidChars,regularExpression); 
            regularExpression.Append("]*");
 
            return regularExpression.ToString(); 
        }
 


        private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleDbConnectionInternal internalConnection){
 
            // verify that the data source information table is in the data set
            DataTable dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; 
            if (dataSourceInformationTable == null){ 
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataSourceInformation);
            } 

            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            dataSourceInformationTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataSourceInformation, null);
 
            // after filtering there better be just one row
            if (dataSourceInformationTable.Rows.Count != 1){ 
                throw ADP.IncorrectNumberOfDataSourceInformationRows(); 
            }
            DataRow dataSourceInformation = dataSourceInformationTable.Rows[0]; 

            // update the identifier separator
            string catalogSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_CATALOG_SEPARATOR);
            string schemaSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_SCHEMA_SEPARATOR); 

            if (catalogSeparatorPattern != null) { 
                StringBuilder compositeSeparatorPattern = new StringBuilder(); 
                StringBuilder patternEscaped = new StringBuilder();
                ADP.EscapeSpecialCharacters(catalogSeparatorPattern,patternEscaped); 
                compositeSeparatorPattern.Append(patternEscaped.ToString());
                if ((schemaSeparatorPattern != null) && (schemaSeparatorPattern != catalogSeparatorPattern)) {
                    compositeSeparatorPattern.Append("|");
                    patternEscaped.Length = 0; 
                    ADP.EscapeSpecialCharacters(schemaSeparatorPattern,patternEscaped);
                    compositeSeparatorPattern.Append(patternEscaped.ToString()); 
                } 
                    dataSourceInformation[DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern] = compositeSeparatorPattern.ToString();
            } 
            else if (schemaSeparatorPattern != null){
                StringBuilder patternEscaped = new StringBuilder();
                ADP.EscapeSpecialCharacters(schemaSeparatorPattern, patternEscaped);
                dataSourceInformation[DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern] = patternEscaped.ToString();; 
            }
 
            // update the DataSourceProductName 
            object property;
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_DBMSNAME); 
            if (property != null) {
                dataSourceInformation[DbMetaDataColumnNames.DataSourceProductName] = (string) property;
            }
 
            // update the server version strings
            dataSourceInformation[DbMetaDataColumnNames.DataSourceProductVersion] = ServerVersion; 
            dataSourceInformation[DbMetaDataColumnNames.DataSourceProductVersionNormalized] = ServerVersionNormalized; 

 
                // values that are the same for all OLE DB Providers. See SQLBU 308529
                dataSourceInformation[DbMetaDataColumnNames.ParameterMarkerFormat] =  "?";
                dataSourceInformation[DbMetaDataColumnNames.ParameterMarkerPattern] =  "\\?";
                dataSourceInformation[DbMetaDataColumnNames.ParameterNameMaxLength] = 0; 

 
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_GROUPBY); 
            GroupByBehavior groupByBehavior = GroupByBehavior.Unknown;
            if (property != null) { 
                switch ((int)property) {

                    case ODB.DBPROPVAL_GB_CONTAINS_SELECT:
                        groupByBehavior = GroupByBehavior.MustContainAll; 
                        break;
 
                    case ODB.DBPROPVAL_GB_EQUALS_SELECT: 
                        groupByBehavior = GroupByBehavior.ExactMatch;
                        break; 

                    case ODB.DBPROPVAL_GB_NO_RELATION:
                        groupByBehavior = GroupByBehavior.Unrelated;
                        break; 

                    case ODB.DBPROPVAL_GB_NOT_SUPPORTED: 
                        groupByBehavior = GroupByBehavior.NotSupported; 
                        break;
                } 
            }
            dataSourceInformation[DbMetaDataColumnNames.GroupByBehavior] = groupByBehavior;

            SetIdentifierCase(DbMetaDataColumnNames.IdentifierCase,ODB.DBPROP_IDENTIFIERCASE,dataSourceInformation, connection); 
            SetIdentifierCase(DbMetaDataColumnNames.QuotedIdentifierCase,ODB.DBPROP_QUOTEDIDENTIFIERCASE,dataSourceInformation, connection);
 
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_ORDERBYCOLUNSINSELECT); 
            if (property != null) {
                dataSourceInformation[DbMetaDataColumnNames.OrderByColumnsInSelect] = (bool) property; 
            }

            DataTable infoLiterals = internalConnection.BuildInfoLiterals();
            if (infoLiterals != null){ 
                DataRow[] tableNameRow = infoLiterals.Select("Literal = " + ODB.DBLITERAL_TABLE_NAME.ToString(CultureInfo.InvariantCulture));
                if (tableNameRow != null) { 
                    object invalidCharsObject = tableNameRow[0]["InvalidChars"]; 
                    if (invalidCharsObject.GetType() == typeof(string)) {
                        string invalidChars = (string)invalidCharsObject; 
                        object invalidStartingCharsObject = tableNameRow[0]["InvalidStartingChars"];
                        string invalidStartingChars;
                        if (invalidStartingCharsObject.GetType() == typeof(string)) {
                            invalidStartingChars = (string)invalidStartingCharsObject; 
                        }
                        else { 
                            invalidStartingChars = invalidChars; 
                        }
                        dataSourceInformation[DbMetaDataColumnNames.IdentifierPattern] = 
                                                    BuildRegularExpression(invalidChars,invalidStartingChars);
                    }
                }
            } 

            // build the QuotedIdentifierPattern using the quote prefix and suffix from the provider and 
            // assuming that the quote suffix is escaped via repetion (i.e " becomes "") 
            string quotePrefix;
            string quoteSuffix; 
            connection.GetLiteralQuotes(ADP.GetSchema, out quotePrefix, out quoteSuffix);

            if (quotePrefix != null){
 
                // if the quote suffix is null assume that it is the same as the prefix (See OLEDB spec
                // IDBInfo::GetLiteralInfo DBLITERAL_QUOTE_SUFFIX.) 
                if (quoteSuffix == null) { 
                    quoteSuffix = quotePrefix;
                } 

                // only know how to build the parttern if the suffix is 1 character
                // in all other cases just leave the field null
                if (quoteSuffix.Length == 1) { 
                    StringBuilder scratchStringBuilder = new StringBuilder();
                    ADP.EscapeSpecialCharacters(quoteSuffix,scratchStringBuilder ); 
                    string escapedQuoteSuffixString = scratchStringBuilder.ToString(); 
                    scratchStringBuilder.Length = 0;
 
                    ADP.EscapeSpecialCharacters(quotePrefix, scratchStringBuilder);
                    scratchStringBuilder.Append("(([^");
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    scratchStringBuilder.Append("]|"); 
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    scratchStringBuilder.Append(escapedQuoteSuffixString); 
                    scratchStringBuilder.Append(")*)"); 
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    dataSourceInformation[DbMetaDataColumnNames.QuotedIdentifierPattern] = scratchStringBuilder.ToString(); 
                }
            }

            dataSourceInformationTable.AcceptChanges(); 

            return dataSourceInformationTable; 
        } 

        private DataTable GetDataTypesTable(OleDbConnection connection){ 

            // verify the existance of the table in the data set
            DataTable dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes];
            if (dataTypesTable == null){ 
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataTypes);
            } 
 
            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            dataTypesTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataTypes, null); 

            DataTable providerTypesTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Provider_Types,null);

 
            DataColumn[] targetColumns = new DataColumn[] {
                dataTypesTable.Columns[DbMetaDataColumnNames.TypeName], 
                dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize], 
                dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable], 
                dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsLong], 
                dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned], 
                dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale], 
                dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale],
                dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix], 
                dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix],
                dataTypesTable.Columns[OleDbMetaDataColumnNames.NativeDataType]};

            DataColumn[] sourceColumns = new DataColumn[] { 
                providerTypesTable.Columns["TYPE_NAME"],
                providerTypesTable.Columns["COLUMN_SIZE"], 
                providerTypesTable.Columns["CREATE_PARAMS"], 
                providerTypesTable.Columns["AUTO_UNIQUE_VALUE"],
                providerTypesTable.Columns["CASE_SENSITIVE"], 
                providerTypesTable.Columns["IS_FIXEDLENGTH"],
                providerTypesTable.Columns["FIXED_PREC_SCALE"],
                providerTypesTable.Columns["IS_LONG"],
                providerTypesTable.Columns["IS_NULLABLE"], 
                providerTypesTable.Columns["UNSIGNED_ATTRIBUTE"],
                providerTypesTable.Columns["MAXIMUM_SCALE"], 
                providerTypesTable.Columns["MINIMUM_SCALE"], 
                providerTypesTable.Columns["LITERAL_PREFIX"],
                providerTypesTable.Columns["LITERAL_SUFFIX"], 
                providerTypesTable.Columns["DATA_TYPE"]};

            Debug.Assert(sourceColumns.Length == targetColumns.Length);
 
            DataColumn isSearchable = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable];
            DataColumn isSearchableWithLike = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]; 
            DataColumn providerDbType = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]; 
            DataColumn clrType = dataTypesTable.Columns[DbMetaDataColumnNames.DataType];
            DataColumn isLong = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]; 
            DataColumn isFixed = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength];
            DataColumn sourceOleDbType = providerTypesTable.Columns["DATA_TYPE"];

            DataColumn searchable = providerTypesTable.Columns["SEARCHABLE"]; 

 
            foreach (DataRow sourceRow in providerTypesTable.Rows) { 
                DataRow newRow = dataTypesTable.NewRow();
                for (int i = 0; i < sourceColumns.Length; i++) { 
                    if ((sourceColumns[i] != null) && (targetColumns[i] != null)){
                        newRow[targetColumns[i]] = sourceRow[sourceColumns[i]];
                    }
                } 

 
                short nativeDataType = (short) Convert.ChangeType(sourceRow[sourceOleDbType],typeof(short), CultureInfo.InvariantCulture); 
                NativeDBType nativeType = NativeDBType.FromDBType(nativeDataType,(bool)newRow[isLong], (bool)newRow[isFixed]);
 
                newRow[clrType] = nativeType.dataType.FullName;
                newRow[providerDbType] = nativeType.enumOleDbType;

                // searchable has to be special cased becasue it is not an eaxct mapping 
                if ((isSearchable != null) && (isSearchableWithLike != null) && (searchable != null)) {
 
                    newRow[isSearchable] = DBNull.Value; 
                    newRow[isSearchableWithLike] = DBNull.Value;
                    if ( DBNull.Value != sourceRow[searchable]){ 

                        Int64 searchableValue = (Int64)(sourceRow[searchable]);
                        switch (searchableValue){
 
                            case ODB.DB_UNSEARCHABLE:
                                newRow[isSearchable] = false; 
                                newRow[isSearchableWithLike] = false; 
                                break;
 
                            case ODB.DB_LIKE_ONLY:
                                newRow[isSearchable] = false;
                                newRow[isSearchableWithLike] = true;
                                break; 

                            case ODB.DB_ALL_EXCEPT_LIKE: 
                                newRow[isSearchable] = true; 
                                newRow[isSearchableWithLike] = false;
                                break; 

                            case ODB.DB_SEARCHABLE:
                                newRow[isSearchable] = true;
                                newRow[isSearchableWithLike] = true; 
                                break;
                        } 
                    } 
                }
 
                dataTypesTable.Rows.Add(newRow);
            }

 
            dataTypesTable.AcceptChanges();
 
            return  dataTypesTable; 

        } 


        private DataTable GetReservedWordsTable(OleDbConnectionInternal internalConnection){
 
            // verify the existance of the table in the data set
            DataTable reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; 
            if (null == reservedWordsTable){ 
                    throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords);
            } 

            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            reservedWordsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.ReservedWords, null);
 
            DataColumn reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord];
            if (null == reservedWordColumn){ 
                    throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); 
            }
 
            if (!internalConnection.AddInfoKeywordsToTable(reservedWordsTable, reservedWordColumn)){
                    throw ODB.IDBInfoNotSupported();
            }
 
            return  reservedWordsTable;
        } 
 

 
        protected override DataTable PrepareCollection(String collectionName, String[] restrictions, DbConnection connection){

            OleDbConnection oleDbConnection = (OleDbConnection) connection;
            OleDbConnectionInternal oleDbInternalConnection = (OleDbConnectionInternal) (oleDbConnection.InnerConnection); 
            DataTable resultTable = null;
            if (collectionName == DbMetaDataCollectionNames.DataSourceInformation){ 
                if (ADP.IsEmptyArray(restrictions) == false){ 
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.DataSourceInformation);
                } 
                resultTable = GetDataSourceInformationTable(oleDbConnection, oleDbInternalConnection);
            }
            else if (collectionName == DbMetaDataCollectionNames.DataTypes){
                if (ADP.IsEmptyArray(restrictions) == false){ 
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.DataTypes);
                } 
                resultTable = GetDataTypesTable(oleDbConnection); 
            }
            else if (collectionName == DbMetaDataCollectionNames.ReservedWords){ 
                if (ADP.IsEmptyArray(restrictions) == false){
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.ReservedWords);
                }
                resultTable = GetReservedWordsTable(oleDbInternalConnection); 
            }
            else { 
                for (int i=0; i < _schemaMapping.Length; i++){ 
                    if (_schemaMapping[i]._schemaName== collectionName) {
 
                        // need to special case the oledb schema rowset restrictions on columns that are not
                        // string tpyes
                        object[] mungedRestrictions = restrictions;;
                        if (restrictions != null){ 
                            //verify that there are not too many restrictions
                            DataTable   metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; 
                            int numberOfSupportedRestictions = -1; 
                            // prepare colletion is called with the exact collection name so
                            // we can do an exact string comparision here 
                            foreach (DataRow row in metaDataCollectionsTable.Rows){
                                string candidateCollectionName = ((string)row[DbMetaDataColumnNames.CollectionName,DataRowVersion.Current]);

                                if (collectionName == candidateCollectionName) { 
                                    numberOfSupportedRestictions = (int)row[DbMetaDataColumnNames.NumberOfRestrictions];
                                    if (numberOfSupportedRestictions < restrictions.Length){ 
                                        throw ADP.TooManyRestrictions(collectionName); 
                                    }
                                    break; 
                                }
                            }

                            Debug.Assert(numberOfSupportedRestictions != -1, "PrepareCollection was called for an collection that is not supported."); 

                            // the 4th restrictionon the indexes schema rowset(type) is an I2 - enum 
                            const int indexRestrictionTypeSlot = 3; 

                            if ((collectionName == OleDbMetaDataCollectionNames.Indexes) && 
                                (restrictions.Length >= indexRestrictionTypeSlot+1) &&
                                (restrictions[indexRestrictionTypeSlot] != null)){

                                mungedRestrictions = new object[restrictions.Length]; 
                                for (int j = 0; j = procedureRestrictionTypeSlot+1) &&
                                (restrictions[procedureRestrictionTypeSlot] != null)){ 

                                mungedRestrictions = new object[restrictions.Length]; 
                                for (int j = 0; j 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// [....]
// Mugunm 
// 
//-----------------------------------------------------------------------------
 
namespace System.Data.OleDb{

    using System;
    using System.Data; 
    using System.IO;
    using System.Collections; 
    using System.Data.ProviderBase; 
    using System.Data.Common;
    using System.Diagnostics; 
    using System.Globalization;
    using System.Text;
    using System.Xml;
    using System.Xml.Schema; 

    internal sealed class OleDbMetaDataFactory : DbMetaDataFactory{ // V1.2.3300 
 
        private struct SchemaRowsetName {
            internal SchemaRowsetName(string schemaName, Guid schemaRowset) { 
                _schemaName = schemaName;
                _schemaRowset = schemaRowset;
            }
            internal readonly string  _schemaName; 
            internal readonly Guid    _schemaRowset;
        } 
 

 
        private const string _collectionName = "CollectionName";
        private const string _populationMechanism = "PopulationMechanism";
        private const string _prepareCollection = "PrepareCollection";
 
        private readonly SchemaRowsetName[] _schemaMapping;
 
        internal OleDbMetaDataFactory(Stream XMLStream, 
                                    string serverVersion,
                                    string serverVersionNormalized, 
                                    SchemaSupport[] schemaSupport):
            base(XMLStream, serverVersion, serverVersionNormalized) {

            // set up the colletion mane schema rowset guid mapping 
           _schemaMapping = new SchemaRowsetName[] {
 
                 new SchemaRowsetName(DbMetaDataCollectionNames.DataTypes,OleDbSchemaGuid.Provider_Types), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Catalogs,OleDbSchemaGuid.Catalogs),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Collations,OleDbSchemaGuid.Collations), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Columns,OleDbSchemaGuid.Columns),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Indexes,OleDbSchemaGuid.Indexes),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Procedures,OleDbSchemaGuid.Procedures),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.ProcedureColumns,OleDbSchemaGuid.Procedure_Columns), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.ProcedureParameters,OleDbSchemaGuid.Procedure_Parameters),
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Tables,OleDbSchemaGuid.Tables), 
                 new SchemaRowsetName(OleDbMetaDataCollectionNames.Views,OleDbSchemaGuid.Views)}; 

            // verify the existance of the table in the data set 
            DataTable metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections];
            if (metaDataCollectionsTable == null){
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.MetaDataCollections);
            } 

            // copy the table filtering out any rows that don't apply to the current version of the provider 
            metaDataCollectionsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.MetaDataCollections, null); 

            // verify the existance of the table in the data set 
            DataTable restrictionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions];
            if (restrictionsTable != null){
                // copy the table filtering out any rows that don't apply to the current version of the provider
                restrictionsTable= CloneAndFilterCollection(DbMetaDataCollectionNames.Restrictions, null); 
            }
 
            // need to filter out any of the collections where 
            // 1) it is populated using prepare collection
            // 2) it is in the collection to schema rowset mapping above 
            // 3) the provider does not support the necessary schema rowset


 
            DataColumn populationMechanism = metaDataCollectionsTable.Columns[_populationMechanism];
            if ((null == populationMechanism) || (typeof(System.String) != populationMechanism.DataType)) { 
                throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections,_populationMechanism); 
            }
            DataColumn collectionName = metaDataCollectionsTable.Columns[_collectionName]; 
            if ((null == collectionName) || (typeof(System.String) != collectionName.DataType)) {
                 throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections,_collectionName);
            }
            DataColumn restrictionCollectionName = null; 
            if (restrictionsTable != null){
                restrictionCollectionName = restrictionsTable.Columns[_collectionName]; 
                if ((null == restrictionCollectionName) || (typeof(System.String) != restrictionCollectionName.DataType)) { 
                    throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.Restrictions,_collectionName);
                } 
            }

            foreach (DataRow collection in metaDataCollectionsTable.Rows){
 
                string populationMechanismValue = collection[populationMechanism] as string;
                if (ADP.IsEmpty(populationMechanismValue )) { 
                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections,_populationMechanism); 
                }
                string collectionNameValue = collection[collectionName] as string; 
                if (ADP.IsEmpty(collectionNameValue)) {
                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections,_collectionName);
                }
 
                if (populationMechanismValue == _prepareCollection) {
                    // is the collection in the mapping 
                    int mapping = -1; 
                    for (int i = 0; i < _schemaMapping.Length; i++){
                        if (_schemaMapping[i]._schemaName == collectionNameValue){ 
                            mapping = i;
                            break;
                        }
                    } 
                    // no go on to the next collection
                    if (mapping == -1) { 
                        continue; 
                    }
 
                    // does the provider support the necessary schema rowset
                    bool isSchemaRowsetSupported = false;
                    if (schemaSupport != null){
                        for (int i = 0; i < schemaSupport.Length; i++){ 
                            if (_schemaMapping[mapping]._schemaRowset == schemaSupport[i]._schemaRowset){
                                isSchemaRowsetSupported = true; 
                                break; 
                            }
                        } 
                    }
                    // if not delete the row from the table
                    if (isSchemaRowsetSupported == false){
                        // but first delete any related restrictions 
                        if (restrictionsTable != null) {
                            foreach (DataRow restriction in restrictionsTable.Rows) { 
                                string restrictionCollectionNameValue = restriction[restrictionCollectionName] as string; 
                                if (ADP.IsEmpty(restrictionCollectionNameValue)) {
                                    throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.Restrictions,_collectionName); 
                                }
                                if (collectionNameValue == restrictionCollectionNameValue) {
                                    restriction.Delete();
                                } 
                            }
                            restrictionsTable.AcceptChanges(); 
                        } 
                        collection.Delete();
                    } 

                }
            }
 
            // replace the original table with the updated one
            metaDataCollectionsTable.AcceptChanges(); 
            CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]); 
            CollectionDataSet.Tables.Add(metaDataCollectionsTable);
 
            if (restrictionsTable != null) {
                CollectionDataSet.Tables.Remove(CollectionDataSet.Tables[DbMetaDataCollectionNames.Restrictions]);
                CollectionDataSet.Tables.Add(restrictionsTable);
            } 

        } 
 
        private String BuildRegularExpression(string invalidChars, string invalidStartingChars){
 
            StringBuilder regularExpression = new StringBuilder("[^");
            ADP.EscapeSpecialCharacters(invalidStartingChars,regularExpression);
            regularExpression.Append("][^");
            ADP.EscapeSpecialCharacters(invalidChars,regularExpression); 
            regularExpression.Append("]*");
 
            return regularExpression.ToString(); 
        }
 


        private DataTable GetDataSourceInformationTable(OleDbConnection connection, OleDbConnectionInternal internalConnection){
 
            // verify that the data source information table is in the data set
            DataTable dataSourceInformationTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataSourceInformation]; 
            if (dataSourceInformationTable == null){ 
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataSourceInformation);
            } 

            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            dataSourceInformationTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataSourceInformation, null);
 
            // after filtering there better be just one row
            if (dataSourceInformationTable.Rows.Count != 1){ 
                throw ADP.IncorrectNumberOfDataSourceInformationRows(); 
            }
            DataRow dataSourceInformation = dataSourceInformationTable.Rows[0]; 

            // update the identifier separator
            string catalogSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_CATALOG_SEPARATOR);
            string schemaSeparatorPattern = internalConnection.GetLiteralInfo(ODB.DBLITERAL_SCHEMA_SEPARATOR); 

            if (catalogSeparatorPattern != null) { 
                StringBuilder compositeSeparatorPattern = new StringBuilder(); 
                StringBuilder patternEscaped = new StringBuilder();
                ADP.EscapeSpecialCharacters(catalogSeparatorPattern,patternEscaped); 
                compositeSeparatorPattern.Append(patternEscaped.ToString());
                if ((schemaSeparatorPattern != null) && (schemaSeparatorPattern != catalogSeparatorPattern)) {
                    compositeSeparatorPattern.Append("|");
                    patternEscaped.Length = 0; 
                    ADP.EscapeSpecialCharacters(schemaSeparatorPattern,patternEscaped);
                    compositeSeparatorPattern.Append(patternEscaped.ToString()); 
                } 
                    dataSourceInformation[DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern] = compositeSeparatorPattern.ToString();
            } 
            else if (schemaSeparatorPattern != null){
                StringBuilder patternEscaped = new StringBuilder();
                ADP.EscapeSpecialCharacters(schemaSeparatorPattern, patternEscaped);
                dataSourceInformation[DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern] = patternEscaped.ToString();; 
            }
 
            // update the DataSourceProductName 
            object property;
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_DBMSNAME); 
            if (property != null) {
                dataSourceInformation[DbMetaDataColumnNames.DataSourceProductName] = (string) property;
            }
 
            // update the server version strings
            dataSourceInformation[DbMetaDataColumnNames.DataSourceProductVersion] = ServerVersion; 
            dataSourceInformation[DbMetaDataColumnNames.DataSourceProductVersionNormalized] = ServerVersionNormalized; 

 
                // values that are the same for all OLE DB Providers. See SQLBU 308529
                dataSourceInformation[DbMetaDataColumnNames.ParameterMarkerFormat] =  "?";
                dataSourceInformation[DbMetaDataColumnNames.ParameterMarkerPattern] =  "\\?";
                dataSourceInformation[DbMetaDataColumnNames.ParameterNameMaxLength] = 0; 

 
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_GROUPBY); 
            GroupByBehavior groupByBehavior = GroupByBehavior.Unknown;
            if (property != null) { 
                switch ((int)property) {

                    case ODB.DBPROPVAL_GB_CONTAINS_SELECT:
                        groupByBehavior = GroupByBehavior.MustContainAll; 
                        break;
 
                    case ODB.DBPROPVAL_GB_EQUALS_SELECT: 
                        groupByBehavior = GroupByBehavior.ExactMatch;
                        break; 

                    case ODB.DBPROPVAL_GB_NO_RELATION:
                        groupByBehavior = GroupByBehavior.Unrelated;
                        break; 

                    case ODB.DBPROPVAL_GB_NOT_SUPPORTED: 
                        groupByBehavior = GroupByBehavior.NotSupported; 
                        break;
                } 
            }
            dataSourceInformation[DbMetaDataColumnNames.GroupByBehavior] = groupByBehavior;

            SetIdentifierCase(DbMetaDataColumnNames.IdentifierCase,ODB.DBPROP_IDENTIFIERCASE,dataSourceInformation, connection); 
            SetIdentifierCase(DbMetaDataColumnNames.QuotedIdentifierCase,ODB.DBPROP_QUOTEDIDENTIFIERCASE,dataSourceInformation, connection);
 
            property = connection.GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo,ODB.DBPROP_ORDERBYCOLUNSINSELECT); 
            if (property != null) {
                dataSourceInformation[DbMetaDataColumnNames.OrderByColumnsInSelect] = (bool) property; 
            }

            DataTable infoLiterals = internalConnection.BuildInfoLiterals();
            if (infoLiterals != null){ 
                DataRow[] tableNameRow = infoLiterals.Select("Literal = " + ODB.DBLITERAL_TABLE_NAME.ToString(CultureInfo.InvariantCulture));
                if (tableNameRow != null) { 
                    object invalidCharsObject = tableNameRow[0]["InvalidChars"]; 
                    if (invalidCharsObject.GetType() == typeof(string)) {
                        string invalidChars = (string)invalidCharsObject; 
                        object invalidStartingCharsObject = tableNameRow[0]["InvalidStartingChars"];
                        string invalidStartingChars;
                        if (invalidStartingCharsObject.GetType() == typeof(string)) {
                            invalidStartingChars = (string)invalidStartingCharsObject; 
                        }
                        else { 
                            invalidStartingChars = invalidChars; 
                        }
                        dataSourceInformation[DbMetaDataColumnNames.IdentifierPattern] = 
                                                    BuildRegularExpression(invalidChars,invalidStartingChars);
                    }
                }
            } 

            // build the QuotedIdentifierPattern using the quote prefix and suffix from the provider and 
            // assuming that the quote suffix is escaped via repetion (i.e " becomes "") 
            string quotePrefix;
            string quoteSuffix; 
            connection.GetLiteralQuotes(ADP.GetSchema, out quotePrefix, out quoteSuffix);

            if (quotePrefix != null){
 
                // if the quote suffix is null assume that it is the same as the prefix (See OLEDB spec
                // IDBInfo::GetLiteralInfo DBLITERAL_QUOTE_SUFFIX.) 
                if (quoteSuffix == null) { 
                    quoteSuffix = quotePrefix;
                } 

                // only know how to build the parttern if the suffix is 1 character
                // in all other cases just leave the field null
                if (quoteSuffix.Length == 1) { 
                    StringBuilder scratchStringBuilder = new StringBuilder();
                    ADP.EscapeSpecialCharacters(quoteSuffix,scratchStringBuilder ); 
                    string escapedQuoteSuffixString = scratchStringBuilder.ToString(); 
                    scratchStringBuilder.Length = 0;
 
                    ADP.EscapeSpecialCharacters(quotePrefix, scratchStringBuilder);
                    scratchStringBuilder.Append("(([^");
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    scratchStringBuilder.Append("]|"); 
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    scratchStringBuilder.Append(escapedQuoteSuffixString); 
                    scratchStringBuilder.Append(")*)"); 
                    scratchStringBuilder.Append(escapedQuoteSuffixString);
                    dataSourceInformation[DbMetaDataColumnNames.QuotedIdentifierPattern] = scratchStringBuilder.ToString(); 
                }
            }

            dataSourceInformationTable.AcceptChanges(); 

            return dataSourceInformationTable; 
        } 

        private DataTable GetDataTypesTable(OleDbConnection connection){ 

            // verify the existance of the table in the data set
            DataTable dataTypesTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.DataTypes];
            if (dataTypesTable == null){ 
                throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.DataTypes);
            } 
 
            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            dataTypesTable = CloneAndFilterCollection(DbMetaDataCollectionNames.DataTypes, null); 

            DataTable providerTypesTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Provider_Types,null);

 
            DataColumn[] targetColumns = new DataColumn[] {
                dataTypesTable.Columns[DbMetaDataColumnNames.TypeName], 
                dataTypesTable.Columns[DbMetaDataColumnNames.ColumnSize], 
                dataTypesTable.Columns[DbMetaDataColumnNames.CreateParameters],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsAutoIncrementable], 
                dataTypesTable.Columns[DbMetaDataColumnNames.IsCaseSensitive],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedPrecisionScale],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsLong], 
                dataTypesTable.Columns[DbMetaDataColumnNames.IsNullable],
                dataTypesTable.Columns[DbMetaDataColumnNames.IsUnsigned], 
                dataTypesTable.Columns[DbMetaDataColumnNames.MaximumScale], 
                dataTypesTable.Columns[DbMetaDataColumnNames.MinimumScale],
                dataTypesTable.Columns[DbMetaDataColumnNames.LiteralPrefix], 
                dataTypesTable.Columns[DbMetaDataColumnNames.LiteralSuffix],
                dataTypesTable.Columns[OleDbMetaDataColumnNames.NativeDataType]};

            DataColumn[] sourceColumns = new DataColumn[] { 
                providerTypesTable.Columns["TYPE_NAME"],
                providerTypesTable.Columns["COLUMN_SIZE"], 
                providerTypesTable.Columns["CREATE_PARAMS"], 
                providerTypesTable.Columns["AUTO_UNIQUE_VALUE"],
                providerTypesTable.Columns["CASE_SENSITIVE"], 
                providerTypesTable.Columns["IS_FIXEDLENGTH"],
                providerTypesTable.Columns["FIXED_PREC_SCALE"],
                providerTypesTable.Columns["IS_LONG"],
                providerTypesTable.Columns["IS_NULLABLE"], 
                providerTypesTable.Columns["UNSIGNED_ATTRIBUTE"],
                providerTypesTable.Columns["MAXIMUM_SCALE"], 
                providerTypesTable.Columns["MINIMUM_SCALE"], 
                providerTypesTable.Columns["LITERAL_PREFIX"],
                providerTypesTable.Columns["LITERAL_SUFFIX"], 
                providerTypesTable.Columns["DATA_TYPE"]};

            Debug.Assert(sourceColumns.Length == targetColumns.Length);
 
            DataColumn isSearchable = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchable];
            DataColumn isSearchableWithLike = dataTypesTable.Columns[DbMetaDataColumnNames.IsSearchableWithLike]; 
            DataColumn providerDbType = dataTypesTable.Columns[DbMetaDataColumnNames.ProviderDbType]; 
            DataColumn clrType = dataTypesTable.Columns[DbMetaDataColumnNames.DataType];
            DataColumn isLong = dataTypesTable.Columns[DbMetaDataColumnNames.IsLong]; 
            DataColumn isFixed = dataTypesTable.Columns[DbMetaDataColumnNames.IsFixedLength];
            DataColumn sourceOleDbType = providerTypesTable.Columns["DATA_TYPE"];

            DataColumn searchable = providerTypesTable.Columns["SEARCHABLE"]; 

 
            foreach (DataRow sourceRow in providerTypesTable.Rows) { 
                DataRow newRow = dataTypesTable.NewRow();
                for (int i = 0; i < sourceColumns.Length; i++) { 
                    if ((sourceColumns[i] != null) && (targetColumns[i] != null)){
                        newRow[targetColumns[i]] = sourceRow[sourceColumns[i]];
                    }
                } 

 
                short nativeDataType = (short) Convert.ChangeType(sourceRow[sourceOleDbType],typeof(short), CultureInfo.InvariantCulture); 
                NativeDBType nativeType = NativeDBType.FromDBType(nativeDataType,(bool)newRow[isLong], (bool)newRow[isFixed]);
 
                newRow[clrType] = nativeType.dataType.FullName;
                newRow[providerDbType] = nativeType.enumOleDbType;

                // searchable has to be special cased becasue it is not an eaxct mapping 
                if ((isSearchable != null) && (isSearchableWithLike != null) && (searchable != null)) {
 
                    newRow[isSearchable] = DBNull.Value; 
                    newRow[isSearchableWithLike] = DBNull.Value;
                    if ( DBNull.Value != sourceRow[searchable]){ 

                        Int64 searchableValue = (Int64)(sourceRow[searchable]);
                        switch (searchableValue){
 
                            case ODB.DB_UNSEARCHABLE:
                                newRow[isSearchable] = false; 
                                newRow[isSearchableWithLike] = false; 
                                break;
 
                            case ODB.DB_LIKE_ONLY:
                                newRow[isSearchable] = false;
                                newRow[isSearchableWithLike] = true;
                                break; 

                            case ODB.DB_ALL_EXCEPT_LIKE: 
                                newRow[isSearchable] = true; 
                                newRow[isSearchableWithLike] = false;
                                break; 

                            case ODB.DB_SEARCHABLE:
                                newRow[isSearchable] = true;
                                newRow[isSearchableWithLike] = true; 
                                break;
                        } 
                    } 
                }
 
                dataTypesTable.Rows.Add(newRow);
            }

 
            dataTypesTable.AcceptChanges();
 
            return  dataTypesTable; 

        } 


        private DataTable GetReservedWordsTable(OleDbConnectionInternal internalConnection){
 
            // verify the existance of the table in the data set
            DataTable reservedWordsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.ReservedWords]; 
            if (null == reservedWordsTable){ 
                    throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords);
            } 

            // copy the table filtering out any rows that don't apply to tho current version of the prrovider
            reservedWordsTable = CloneAndFilterCollection(DbMetaDataCollectionNames.ReservedWords, null);
 
            DataColumn reservedWordColumn = reservedWordsTable.Columns[DbMetaDataColumnNames.ReservedWord];
            if (null == reservedWordColumn){ 
                    throw ADP.UnableToBuildCollection(DbMetaDataCollectionNames.ReservedWords); 
            }
 
            if (!internalConnection.AddInfoKeywordsToTable(reservedWordsTable, reservedWordColumn)){
                    throw ODB.IDBInfoNotSupported();
            }
 
            return  reservedWordsTable;
        } 
 

 
        protected override DataTable PrepareCollection(String collectionName, String[] restrictions, DbConnection connection){

            OleDbConnection oleDbConnection = (OleDbConnection) connection;
            OleDbConnectionInternal oleDbInternalConnection = (OleDbConnectionInternal) (oleDbConnection.InnerConnection); 
            DataTable resultTable = null;
            if (collectionName == DbMetaDataCollectionNames.DataSourceInformation){ 
                if (ADP.IsEmptyArray(restrictions) == false){ 
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.DataSourceInformation);
                } 
                resultTable = GetDataSourceInformationTable(oleDbConnection, oleDbInternalConnection);
            }
            else if (collectionName == DbMetaDataCollectionNames.DataTypes){
                if (ADP.IsEmptyArray(restrictions) == false){ 
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.DataTypes);
                } 
                resultTable = GetDataTypesTable(oleDbConnection); 
            }
            else if (collectionName == DbMetaDataCollectionNames.ReservedWords){ 
                if (ADP.IsEmptyArray(restrictions) == false){
                    throw ADP.TooManyRestrictions(DbMetaDataCollectionNames.ReservedWords);
                }
                resultTable = GetReservedWordsTable(oleDbInternalConnection); 
            }
            else { 
                for (int i=0; i < _schemaMapping.Length; i++){ 
                    if (_schemaMapping[i]._schemaName== collectionName) {
 
                        // need to special case the oledb schema rowset restrictions on columns that are not
                        // string tpyes
                        object[] mungedRestrictions = restrictions;;
                        if (restrictions != null){ 
                            //verify that there are not too many restrictions
                            DataTable   metaDataCollectionsTable = CollectionDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; 
                            int numberOfSupportedRestictions = -1; 
                            // prepare colletion is called with the exact collection name so
                            // we can do an exact string comparision here 
                            foreach (DataRow row in metaDataCollectionsTable.Rows){
                                string candidateCollectionName = ((string)row[DbMetaDataColumnNames.CollectionName,DataRowVersion.Current]);

                                if (collectionName == candidateCollectionName) { 
                                    numberOfSupportedRestictions = (int)row[DbMetaDataColumnNames.NumberOfRestrictions];
                                    if (numberOfSupportedRestictions < restrictions.Length){ 
                                        throw ADP.TooManyRestrictions(collectionName); 
                                    }
                                    break; 
                                }
                            }

                            Debug.Assert(numberOfSupportedRestictions != -1, "PrepareCollection was called for an collection that is not supported."); 

                            // the 4th restrictionon the indexes schema rowset(type) is an I2 - enum 
                            const int indexRestrictionTypeSlot = 3; 

                            if ((collectionName == OleDbMetaDataCollectionNames.Indexes) && 
                                (restrictions.Length >= indexRestrictionTypeSlot+1) &&
                                (restrictions[indexRestrictionTypeSlot] != null)){

                                mungedRestrictions = new object[restrictions.Length]; 
                                for (int j = 0; j = procedureRestrictionTypeSlot+1) &&
                                (restrictions[procedureRestrictionTypeSlot] != null)){ 

                                mungedRestrictions = new object[restrictions.Length]; 
                                for (int j = 0; j 

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK