Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / ProviderBase / DbMetaDataFactory.cs / 1 / DbMetaDataFactory.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data.ProviderBase { using System; using System.Collections; using System.Data; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.IO; using System.Xml; using System.Xml.Schema; internal class DbMetaDataFactory{ // V1.2.3300 private DataSet _metaDataCollectionsDataSet; private string _normalizedServerVersion; private string _serverVersionString; // well known column names private const string _collectionName = "CollectionName"; private const string _populationMechanism = "PopulationMechanism"; private const string _populationString = "PopulationString"; private const string _maximumVersion = "MaximumVersion"; private const string _minimumVersion = "MinimumVersion"; private const string _dataSourceProductVersionNormalized = "DataSourceProductVersionNormalized"; private const string _dataSourceProductVersion = "DataSourceProductVersion"; private const string _restrictionDefault = "RestrictionDefault"; private const string _restrictionNumber = "RestrictionNumber"; private const string _numberOfRestrictions = "NumberOfRestrictions"; private const string _restrictionName = "RestrictionName"; private const string _parameterName = "ParameterName"; // population mechanisms private const string _dataTable = "DataTable"; private const string _sqlCommand = "SQLCommand"; private const string _prepareCollection = "PrepareCollection"; public DbMetaDataFactory(Stream xmlStream, string serverVersion, string normalizedServerVersion) { ADP.CheckArgumentNull(xmlStream, "xmlStream"); ADP.CheckArgumentNull(serverVersion, "serverVersion"); ADP.CheckArgumentNull(normalizedServerVersion, "normalizedServerVersion"); LoadDataSetFromXml(xmlStream); _serverVersionString = serverVersion; _normalizedServerVersion = normalizedServerVersion; } #if !ORACLE protected DataSet CollectionDataSet { get { return _metaDataCollectionsDataSet; } } protected string ServerVersion { get { return _serverVersionString; } } protected string ServerVersionNormalized { get { return _normalizedServerVersion; } } #endif protected DataTable CloneAndFilterCollection(string collectionName, string[] hiddenColumnNames) { DataTable sourceTable; DataTable destinationTable; DataColumn[] filteredSourceColumns; DataColumnCollection destinationColumns; DataRow newRow; sourceTable = _metaDataCollectionsDataSet.Tables[collectionName]; if ((sourceTable == null) || (collectionName != sourceTable.TableName)) { throw ADP.DataTableDoesNotExist(collectionName); } destinationTable = new DataTable(collectionName); destinationTable.Locale = CultureInfo.InvariantCulture; destinationColumns = destinationTable.Columns; filteredSourceColumns = FilterColumns(sourceTable,hiddenColumnNames,destinationColumns); foreach (DataRow row in sourceTable.Rows) { if (SupportedByCurrentVersion(row) == true) { newRow = destinationTable.NewRow(); for(int i = 0; i < destinationColumns.Count; i++) { newRow[destinationColumns[i]] = row[filteredSourceColumns[i],DataRowVersion.Current]; } destinationTable.Rows.Add(newRow); newRow.AcceptChanges(); } } return destinationTable; } public void Dispose() { Dispose(true); } virtual protected void Dispose(bool disposing) { if (disposing) { _normalizedServerVersion = null; _serverVersionString = null; _metaDataCollectionsDataSet.Dispose(); } } private DataTable ExecuteCommand(DataRow requestedCollectionRow, String[] restrictions, DbConnection connection){ DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; DataColumn populationStringColumn = metaDataCollectionsTable.Columns[_populationString]; DataColumn numberOfRestrictionsColumn = metaDataCollectionsTable.Columns[_numberOfRestrictions]; DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[_collectionName]; //DataColumn restrictionNameColumn = metaDataCollectionsTable.Columns[_restrictionName]; DataTable resultTable = null; DbCommand command = null; DataTable schemaTable = null; Debug.Assert(requestedCollectionRow != null); String sqlCommand = requestedCollectionRow[populationStringColumn,DataRowVersion.Current] as string; int numberOfRestrictions = (int)requestedCollectionRow[numberOfRestrictionsColumn,DataRowVersion.Current] ; String collectionName = requestedCollectionRow[collectionNameColumn,DataRowVersion.Current] as string; if ((restrictions != null) && (restrictions.Length > numberOfRestrictions)) { throw ADP.TooManyRestrictions(collectionName); } command = connection.CreateCommand(); command.CommandText = sqlCommand; command.CommandTimeout = System.Math.Max(command.CommandTimeout,180); for (int i = 0; i < numberOfRestrictions; i++) { DbParameter restrictionParameter = command.CreateParameter(); if ((restrictions != null) && (restrictions.Length > i ) && (restrictions[i] != null)) { restrictionParameter.Value = restrictions[i]; } else { // This is where we have to assign null to the value of the parameter. restrictionParameter.Value = DBNull.Value; } restrictionParameter.ParameterName = GetParameterName(collectionName, i+1); restrictionParameter.Direction = ParameterDirection.Input; command.Parameters.Add(restrictionParameter); } DbDataReader reader = null; try { try { reader = command.ExecuteReader(); } catch (Exception e) { if (!ADP.IsCatchableExceptionType(e)) { throw; } throw ADP.QueryFailed(collectionName,e); } // // Build a DataTable from the reader resultTable = new DataTable(collectionName); resultTable.Locale = CultureInfo.InvariantCulture; schemaTable = reader.GetSchemaTable(); foreach (DataRow row in schemaTable.Rows){ resultTable.Columns.Add(row["ColumnName"] as string, (Type)row["DataType"] as Type); } object[] values = new object[resultTable.Columns.Count]; while (reader.Read()) { reader.GetValues(values); resultTable.Rows.Add(values); } } finally { if (reader != null) { reader.Dispose(); reader = null; } } return resultTable; } private DataColumn[] FilterColumns(DataTable sourceTable, string[] hiddenColumnNames, DataColumnCollection destinationColumns) { DataColumn newDestinationColumn; int currentColumn; DataColumn[] filteredSourceColumns = null; int columnCount = 0; foreach (DataColumn sourceColumn in sourceTable.Columns){ if (IncludeThisColumn(sourceColumn,hiddenColumnNames) == true) { columnCount++; } } if (columnCount == 0) { throw ADP.NoColumns(); } currentColumn= 0; filteredSourceColumns = new DataColumn[columnCount]; foreach(DataColumn sourceColumn in sourceTable.Columns){ if (IncludeThisColumn(sourceColumn,hiddenColumnNames) == true) { newDestinationColumn = new DataColumn(sourceColumn.ColumnName,sourceColumn.DataType); destinationColumns.Add(newDestinationColumn); filteredSourceColumns[currentColumn] = sourceColumn; currentColumn++; } } return filteredSourceColumns; } internal DataRow FindMetaDataCollectionRow(string collectionName) { bool versionFailure; bool haveExactMatch; bool haveMultipleInexactMatches; string candidateCollectionName; DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; if (metaDataCollectionsTable == null) { throw ADP.InvalidXml(); } DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; if ((null == collectionNameColumn) || (typeof(System.String) != collectionNameColumn.DataType)) { throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, DbMetaDataColumnNames.CollectionName); } DataRow requestedCollectionRow = null; String exactCollectionName = null; // find the requested collection versionFailure = false; haveExactMatch = false; haveMultipleInexactMatches = false; foreach (DataRow row in metaDataCollectionsTable.Rows){ candidateCollectionName = row[collectionNameColumn,DataRowVersion.Current] as string; if (ADP.IsEmpty(candidateCollectionName)) { throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections,DbMetaDataColumnNames.CollectionName); } if (ADP.CompareInsensitiveInvariant(candidateCollectionName, collectionName)){ if (SupportedByCurrentVersion(row) == false) { versionFailure = true; } else{ if (collectionName == candidateCollectionName) { if (haveExactMatch == true) { throw ADP.CollectionNameIsNotUnique(collectionName); } requestedCollectionRow = row; exactCollectionName = candidateCollectionName; haveExactMatch = true; } else { // have an inexact match - ok only if it is the only one if (exactCollectionName != null) { // can't fail here becasue we may still find an exact match haveMultipleInexactMatches = true; } requestedCollectionRow = row; exactCollectionName = candidateCollectionName; } } } } if (requestedCollectionRow == null){ if (versionFailure == false) { throw ADP.UndefinedCollection(collectionName); } else { throw ADP.UnsupportedVersion(collectionName); } } if ((haveExactMatch == false) && (haveMultipleInexactMatches == true)) { throw ADP.AmbigousCollectionName(collectionName); } return requestedCollectionRow; } private void FixUpVersion(DataTable dataSourceInfoTable){ Debug.Assert(dataSourceInfoTable.TableName == DbMetaDataCollectionNames.DataSourceInformation); DataColumn versionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersion]; DataColumn normalizedVersionColumn = dataSourceInfoTable.Columns[_dataSourceProductVersionNormalized]; if ((versionColumn == null) || (normalizedVersionColumn == null)) { throw ADP.MissingDataSourceInformationColumn(); } if (dataSourceInfoTable.Rows.Count != 1) { throw ADP.IncorrectNumberOfDataSourceInformationRows(); } DataRow dataSourceInfoRow = dataSourceInfoTable.Rows[0]; dataSourceInfoRow[versionColumn] = _serverVersionString; dataSourceInfoRow[normalizedVersionColumn] = _normalizedServerVersion; dataSourceInfoRow.AcceptChanges(); } private string GetParameterName(string neededCollectionName, int neededRestrictionNumber) { DataTable restrictionsTable = null; DataColumnCollection restrictionColumns = null; DataColumn collectionName = null; DataColumn parameterName = null; DataColumn restrictionName = null; DataColumn restrictionNumber = null;; string result = null; restrictionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.Restrictions]; if (restrictionsTable != null) { restrictionColumns = restrictionsTable.Columns; if (restrictionColumns != null) { collectionName = restrictionColumns[_collectionName]; parameterName = restrictionColumns[_parameterName]; restrictionName = restrictionColumns[_restrictionName]; restrictionNumber = restrictionColumns[_restrictionNumber]; } } if ((parameterName == null) ||(collectionName == null) || (restrictionName == null) || (restrictionNumber == null)) { throw ADP.MissingRestrictionColumn(); } foreach (DataRow restriction in restrictionsTable.Rows) { if (((string)restriction[collectionName] == neededCollectionName) && ((int)restriction[restrictionNumber] == neededRestrictionNumber) && (SupportedByCurrentVersion(restriction))) { result = (string)restriction[parameterName]; break; } } if (result == null) { throw ADP.MissingRestrictionRow(); } return result; } virtual public DataTable GetSchema(DbConnection connection, string collectionName, string[] restrictions) { Debug.Assert (_metaDataCollectionsDataSet != null); // DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; DataColumn populationMechanismColumn = metaDataCollectionsTable.Columns[_populationMechanism]; DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; DataRow requestedCollectionRow = null; DataTable requestedSchema = null; string[] hiddenColumns; string exactCollectionName = null; requestedCollectionRow = FindMetaDataCollectionRow(collectionName); exactCollectionName = requestedCollectionRow[collectionNameColumn,DataRowVersion.Current] as string; if (ADP.IsEmptyArray(restrictions) == false){ for (int i = 0; i < restrictions.Length; i++) { if ((restrictions[i] != null) && (restrictions[i].Length > 4096)) { // new error messages are not allowed for beta 2 // will add a more descriptive error in RTM throw ADP.NotSupported(); } } } string populationMechanism = requestedCollectionRow[populationMechanismColumn,DataRowVersion.Current] as string; switch (populationMechanism) { case _dataTable: if (exactCollectionName == DbMetaDataCollectionNames.MetaDataCollections) { hiddenColumns = new string[2]; hiddenColumns[0] = _populationMechanism; hiddenColumns[1] = _populationString; } else { hiddenColumns = null; } // none of the datatable collections support restrictions if (ADP.IsEmptyArray(restrictions) == false){ throw ADP.TooManyRestrictions(exactCollectionName); } requestedSchema = CloneAndFilterCollection(exactCollectionName,hiddenColumns); // // for the data source infomation table we need to fix up the version columns at run time // since the version is determined at run time if (exactCollectionName == DbMetaDataCollectionNames.DataSourceInformation) { FixUpVersion(requestedSchema); } break; case _sqlCommand: requestedSchema = ExecuteCommand(requestedCollectionRow,restrictions,connection); break; case _prepareCollection: requestedSchema = PrepareCollection(exactCollectionName,restrictions, connection); break; default: throw ADP.UndefinedPopulationMechanism(populationMechanism); } return requestedSchema; } private bool IncludeThisColumn(DataColumn sourceColumn, string[] hiddenColumnNames) { bool result = true; string sourceColumnName = sourceColumn.ColumnName; switch (sourceColumnName) { case _minimumVersion: case _maximumVersion: result = false; break; default: if (hiddenColumnNames == null) { break; } for (int i = 0 ; i < hiddenColumnNames.Length; i++) { if (hiddenColumnNames[i] == sourceColumnName){ result = false; break; } } break; } return result; } private void LoadDataSetFromXml(Stream XmlStream){ _metaDataCollectionsDataSet = new DataSet(); _metaDataCollectionsDataSet.Locale = System.Globalization.CultureInfo.InvariantCulture; _metaDataCollectionsDataSet.ReadXml(XmlStream); } virtual protected DataTable PrepareCollection(String collectionName, String[] restrictions,DbConnection connection){ throw ADP.NotSupported(); } private bool SupportedByCurrentVersion(DataRow requestedCollectionRow){ bool result = true; DataColumnCollection tableColumns = requestedCollectionRow.Table.Columns; DataColumn versionColumn; Object version; // check the minimum version first versionColumn = tableColumns[_minimumVersion]; if (versionColumn != null) { version = requestedCollectionRow[versionColumn]; if (version != null) { if (version != DBNull.Value) { if (0 > string.Compare( _normalizedServerVersion,(string)version, StringComparison.OrdinalIgnoreCase)){ result = false; } } } } // if the minmum version was ok what about the maximum version if (result == true) { versionColumn = tableColumns[_maximumVersion]; if (versionColumn != null) { version = requestedCollectionRow[versionColumn]; if (version != null) { if (version != DBNull.Value) { if (0 < string.Compare( _normalizedServerVersion,(string)version, StringComparison.OrdinalIgnoreCase)){ result = false; } } } } } return result; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TogglePattern.cs
- NonParentingControl.cs
- Compiler.cs
- TextOnlyOutput.cs
- SoapSchemaMember.cs
- ChtmlFormAdapter.cs
- TextRange.cs
- ActiveXHost.cs
- MessagingActivityHelper.cs
- CodeSnippetExpression.cs
- FixedStringLookup.cs
- WebServicesSection.cs
- WebMessageEncodingBindingElement.cs
- SignedPkcs7.cs
- HtmlWindowCollection.cs
- DesignerUtility.cs
- WsatProxy.cs
- TabItem.cs
- COSERVERINFO.cs
- DiagnosticTrace.cs
- DrawingAttributes.cs
- ComMethodElementCollection.cs
- CompositeDataBoundControl.cs
- EditorZoneBase.cs
- Opcode.cs
- QuotedPrintableStream.cs
- MembershipSection.cs
- CriticalHandle.cs
- PolicyChain.cs
- BuilderInfo.cs
- DefaultAutoFieldGenerator.cs
- XmlAttributeCollection.cs
- SettingsAttributeDictionary.cs
- DataStreamFromComStream.cs
- ChangesetResponse.cs
- DataGridHeaderBorder.cs
- EntityRecordInfo.cs
- JsonServiceDocumentSerializer.cs
- OleDbReferenceCollection.cs
- GraphicsPathIterator.cs
- ResourceDescriptionAttribute.cs
- ListBindingConverter.cs
- TableLayoutSettingsTypeConverter.cs
- LocalServiceSecuritySettingsElement.cs
- EntityDataSourceDesigner.cs
- Icon.cs
- MatrixConverter.cs
- XmlDictionaryWriter.cs
- FrameworkPropertyMetadata.cs
- Automation.cs
- OutOfProcStateClientManager.cs
- CSharpCodeProvider.cs
- SettingsPropertyWrongTypeException.cs
- PreProcessor.cs
- GradientBrush.cs
- TextBoxLine.cs
- Line.cs
- ISAPIRuntime.cs
- URL.cs
- WebMessageFormatHelper.cs
- ConfigurationManagerInternalFactory.cs
- LocalValueEnumerator.cs
- Slider.cs
- XPathNodeInfoAtom.cs
- DesignerLoader.cs
- DelayedRegex.cs
- SafeNativeMethods.cs
- ParenthesizePropertyNameAttribute.cs
- DateTimeOffset.cs
- DesignerToolStripControlHost.cs
- TypeGenericEnumerableViewSchema.cs
- SqlRewriteScalarSubqueries.cs
- FunctionDefinition.cs
- ContentFileHelper.cs
- DataSourceView.cs
- VirtualizingStackPanel.cs
- VSWCFServiceContractGenerator.cs
- XPathScanner.cs
- TextControl.cs
- ManifestResourceInfo.cs
- CodeStatementCollection.cs
- DecoderExceptionFallback.cs
- ConvertersCollection.cs
- ProxyHelper.cs
- ParseChildrenAsPropertiesAttribute.cs
- ToolboxItem.cs
- CodeMethodMap.cs
- WebPartAddingEventArgs.cs
- DataRecordInternal.cs
- RedistVersionInfo.cs
- BamlLocalizationDictionary.cs
- EntityDataSourceWrapper.cs
- TextEmbeddedObject.cs
- Trace.cs
- GridViewRowEventArgs.cs
- DataGridViewSelectedColumnCollection.cs
- SpecialFolderEnumConverter.cs
- ResourceManagerWrapper.cs
- IBuiltInEvidence.cs
- XamlReader.cs