Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / XMLDiffLoader.cs / 3 / XMLDiffLoader.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Runtime.Serialization.Formatters; using System.Configuration.Assemblies; using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using System.Collections; using System.Globalization; using Microsoft.Win32; using System.ComponentModel; using System.Xml; using System.Xml.Serialization; internal sealed class XMLDiffLoader { ArrayList tables; DataSet dataSet = null; DataTable dataTable = null; internal void LoadDiffGram(DataSet ds, XmlReader dataTextReader) { XmlReader reader = DataTextReader.CreateReader(dataTextReader); dataSet = ds; while (reader.LocalName == Keywords.SQL_BEFORE && reader.NamespaceURI==Keywords.DFFNS) { ProcessDiffs(ds, reader); reader.Read(); // now the reader points to the error section } while (reader.LocalName == Keywords.MSD_ERRORS && reader.NamespaceURI==Keywords.DFFNS) { ProcessErrors(ds, reader); Debug.Assert(reader.LocalName == Keywords.MSD_ERRORS && reader.NamespaceURI==Keywords.DFFNS, "something fishy"); reader.Read(); // pass the end of errors tag } } private void CreateTablesHierarchy(DataTable dt) { foreach( DataRelation r in dt.ChildRelations ) { if (! tables.Contains((DataTable)r.ChildTable)) { tables.Add((DataTable)r.ChildTable); CreateTablesHierarchy(r.ChildTable) ; } } } internal void LoadDiffGram(DataTable dt, XmlReader dataTextReader) { XmlReader reader = DataTextReader.CreateReader(dataTextReader); dataTable = dt; tables = new ArrayList(); tables.Add(dt); CreateTablesHierarchy(dt); while (reader.LocalName == Keywords.SQL_BEFORE && reader.NamespaceURI==Keywords.DFFNS) { ProcessDiffs(tables, reader); reader.Read(); // now the reader points to the error section } while (reader.LocalName == Keywords.MSD_ERRORS && reader.NamespaceURI==Keywords.DFFNS) { ProcessErrors(tables, reader); Debug.Assert(reader.LocalName == Keywords.MSD_ERRORS && reader.NamespaceURI==Keywords.DFFNS, "something fishy"); reader.Read(); // pass the end of errors tag } } internal void ProcessDiffs(DataSet ds, XmlReader ssync) { DataTable tableBefore; DataRow row; int oldRowRecord; int pos = -1; int iSsyncDepth = ssync.Depth; ssync.Read(); // pass the before node. SkipWhitespaces(ssync); while (iSsyncDepth < ssync.Depth) { tableBefore = null; string diffId = null; oldRowRecord = -1; // the diffgramm always contains sql:before and sql:after pairs int iTempDepth = ssync.Depth; diffId = ssync.GetAttribute(Keywords.DIFFID, Keywords.DFFNS); bool hasErrors = (bool) (ssync.GetAttribute(Keywords.HASERRORS, Keywords.DFFNS) == Keywords.TRUE); oldRowRecord = ReadOldRowData(ds, ref tableBefore, ref pos, ssync); if (oldRowRecord == -1) continue; if (tableBefore == null) throw ExceptionBuilder.DiffgramMissingSQL(); row = (DataRow)tableBefore.RowDiffId[diffId]; if (row != null) { row.oldRecord = oldRowRecord ; tableBefore.recordManager[oldRowRecord] = row; } else { row = tableBefore.NewEmptyRow(); tableBefore.recordManager[oldRowRecord] = row; row.oldRecord = oldRowRecord; row.newRecord = oldRowRecord; tableBefore.Rows.DiffInsertAt(row, pos); row.Delete(); if (hasErrors) tableBefore.RowDiffId[diffId] = row; } } return; } internal void ProcessDiffs(ArrayList tableList, XmlReader ssync) { DataTable tableBefore; DataRow row; int oldRowRecord; int pos = -1; int iSsyncDepth = ssync.Depth; ssync.Read(); // pass the before node. //SkipWhitespaces(ssync); for given scenario does not require this change, but in fact we should do it. while (iSsyncDepth < ssync.Depth) { tableBefore = null; string diffId = null; oldRowRecord = -1; // the diffgramm always contains sql:before and sql:after pairs int iTempDepth = ssync.Depth; diffId = ssync.GetAttribute(Keywords.DIFFID, Keywords.DFFNS); bool hasErrors = (bool) (ssync.GetAttribute(Keywords.HASERRORS, Keywords.DFFNS) == Keywords.TRUE); oldRowRecord = ReadOldRowData(dataSet, ref tableBefore, ref pos, ssync); if (oldRowRecord == -1) continue; if (tableBefore == null) throw ExceptionBuilder.DiffgramMissingSQL(); row = (DataRow)tableBefore.RowDiffId[diffId]; if (row != null) { row.oldRecord = oldRowRecord ; tableBefore.recordManager[oldRowRecord] = row; } else { row = tableBefore.NewEmptyRow(); tableBefore.recordManager[oldRowRecord] = row; row.oldRecord = oldRowRecord; row.newRecord = oldRowRecord; tableBefore.Rows.DiffInsertAt(row, pos); row.Delete(); if (hasErrors) tableBefore.RowDiffId[diffId] = row; } } return; } internal void ProcessErrors(DataSet ds, XmlReader ssync) { DataTable table; int iSsyncDepth = ssync.Depth; ssync.Read(); // pass the before node. while (iSsyncDepth < ssync.Depth) { table = ds.Tables.GetTable(XmlConvert.DecodeName(ssync.LocalName), ssync.NamespaceURI); if (table == null) throw ExceptionBuilder.DiffgramMissingSQL(); string diffId = ssync.GetAttribute(Keywords.DIFFID, Keywords.DFFNS); DataRow row = (DataRow)table.RowDiffId[diffId]; string rowError = ssync.GetAttribute(Keywords.MSD_ERROR, Keywords.DFFNS); if (rowError != null) row.RowError = rowError; int iRowDepth = ssync.Depth; ssync.Read(); // we may be inside a column while (iRowDepth < ssync.Depth) { DataColumn col = table.Columns[XmlConvert.DecodeName(ssync.LocalName), ssync.NamespaceURI]; //if (col == null) // throw exception here string colError = ssync.GetAttribute(Keywords.MSD_ERROR, Keywords.DFFNS); row.SetColumnError(col, colError); ssync.Read(); } while ((ssync.NodeType == XmlNodeType.EndElement) && (iSsyncDepth < ssync.Depth) ) ssync.Read(); } return; } internal void ProcessErrors(ArrayList dt, XmlReader ssync) { DataTable table; int iSsyncDepth = ssync.Depth; ssync.Read(); // pass the before node. while (iSsyncDepth < ssync.Depth) { table = GetTable(XmlConvert.DecodeName(ssync.LocalName), ssync.NamespaceURI); if (table == null) throw ExceptionBuilder.DiffgramMissingSQL(); string diffId = ssync.GetAttribute(Keywords.DIFFID, Keywords.DFFNS); DataRow row = (DataRow)table.RowDiffId[diffId]; if (row == null) { for(int i = 0; i < dt.Count; i++) { row = (DataRow)((DataTable)dt[i]).RowDiffId[diffId]; if (row != null) { table = row.Table; break; } } } string rowError = ssync.GetAttribute(Keywords.MSD_ERROR, Keywords.DFFNS); if (rowError != null) row.RowError = rowError; int iRowDepth = ssync.Depth; ssync.Read(); // we may be inside a column while (iRowDepth < ssync.Depth) { DataColumn col = table.Columns[XmlConvert.DecodeName(ssync.LocalName), ssync.NamespaceURI]; //if (col == null) // throw exception here string colError = ssync.GetAttribute(Keywords.MSD_ERROR, Keywords.DFFNS); row.SetColumnError(col, colError); ssync.Read(); } while ((ssync.NodeType == XmlNodeType.EndElement) && (iSsyncDepth < ssync.Depth) ) ssync.Read(); } return; } private DataTable GetTable(string tableName, string ns) { if (tables == null) return dataSet.Tables.GetTable(tableName, ns); if (tables.Count == 0) return (DataTable)tables[0]; for(int i = 0; i < tables.Count; i++) { DataTable dt = (DataTable)tables[i]; if ((string.Compare(dt.TableName, tableName, StringComparison.Ordinal) == 0) && (string.Compare(dt.Namespace, ns, StringComparison.Ordinal) == 0)) return dt; } return null; } private int ReadOldRowData(DataSet ds, ref DataTable table, ref int pos, XmlReader row) { // read table information if (ds != null) { table = ds.Tables.GetTable(XmlConvert.DecodeName(row.LocalName), row.NamespaceURI); } else { table = GetTable(XmlConvert.DecodeName(row.LocalName), row.NamespaceURI); } if (table == null) { row.Skip(); // need to skip this element if we dont know about it, before returning -1 return -1; } int iRowDepth = row.Depth; string value = null; if (table == null) throw ExceptionBuilder.DiffgramMissingTable(XmlConvert.DecodeName(row.LocalName)); value = row.GetAttribute(Keywords.ROWORDER, Keywords.MSDNS); if (!Common.ADP.IsEmpty(value)) { pos = (Int32) Convert.ChangeType(value, typeof(Int32), null); } int record = table.NewRecord(); foreach (DataColumn col in table.Columns) { col[record] = DBNull.Value; } foreach (DataColumn col in table.Columns) { if ((col.ColumnMapping == MappingType.Element) || (col.ColumnMapping == MappingType.SimpleContent)) continue; if (col.ColumnMapping == MappingType.Hidden) { value = row.GetAttribute("hidden"+col.EncodedColumnName, Keywords.MSDNS); } else { value = row.GetAttribute(col.EncodedColumnName, col.Namespace); } if (value == null) { continue; } col[record] = col.ConvertXmlToObject(value); } row.Read(); SkipWhitespaces(row); if (row.Depth <= iRowDepth) { // the node is empty return record; } if (table.XmlText != null) { DataColumn col = table.XmlText; col[record] = col.ConvertXmlToObject(row.ReadString()); } else { while (row.Depth > iRowDepth) { String ln =XmlConvert.DecodeName( row.LocalName) ; String ns = row.NamespaceURI; DataColumn column = table.Columns[ln, ns]; if (column == null) { while((row.NodeType != XmlNodeType.EndElement) && (row.LocalName!=ln) && (row.NamespaceURI!=ns)) row.Read(); // consume the current node row.Read(); // now points to the next column //SkipWhitespaces(row); seems no need, just in case if we see other issue , this will be here as hint continue;// add a read here! } if (column.IsCustomType) { // if column's type is object or column type does not implement IXmlSerializable bool isPolymorphism = (column.DataType == typeof(Object)|| (row.GetAttribute(Keywords.MSD_INSTANCETYPE, Keywords.MSDNS) != null) || (row.GetAttribute(Keywords.TYPE, Keywords.XSINS) != null)) ; bool skipped = false; if (column.Table.DataSet != null && column.Table.DataSet.UdtIsWrapped) { row.Read(); // if UDT is wrapped, skip the wrapper skipped = true; } XmlRootAttribute xmlAttrib = null; if (!isPolymorphism && !column.ImplementsIXMLSerializable) { // THIS // if does not implement IXLSerializable, need to go with XmlSerializer: pass XmlRootAttribute if (skipped) { xmlAttrib = new XmlRootAttribute(row.LocalName); xmlAttrib.Namespace = row.NamespaceURI ; } else { xmlAttrib = new XmlRootAttribute(column.EncodedColumnName); xmlAttrib.Namespace = column.Namespace; } } // for else case xmlAttrib MUST be null column[record] = column.ConvertXmlToObject(row, xmlAttrib); // you need to pass null XmlAttib here if (skipped) { row.Read(); // if Wrapper is skipped, skip its end tag } } else { int iColumnDepth = row.Depth; row.Read(); // SkipWhitespaces(row);seems no need, just in case if we see other issue , this will be here as hint if (row.Depth > iColumnDepth) { //we are inside the column if (row.NodeType == XmlNodeType.Text || row.NodeType == XmlNodeType.Whitespace || row.NodeType == XmlNodeType.SignificantWhitespace) { String text = row.ReadString(); column[record] = column.ConvertXmlToObject(text); row.Read(); // now points to the next column } } else { //case if (column.DataType == typeof(string)) column[record] = string.Empty; } } } } row.Read(); //now it should point to next row SkipWhitespaces(row); return record; } internal void SkipWhitespaces(XmlReader reader) { while (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.SignificantWhitespace) { reader.Read(); } } } } // 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
- RequestTimeoutManager.cs
- DataBinding.cs
- PropertyInformationCollection.cs
- CodeValidator.cs
- DelegatingMessage.cs
- ContentPresenter.cs
- NetSectionGroup.cs
- DataGridBoolColumn.cs
- SchemaObjectWriter.cs
- ZoneButton.cs
- SelectedPathEditor.cs
- PermissionSetEnumerator.cs
- SystemIcons.cs
- NetSectionGroup.cs
- DataConnectionHelper.cs
- SourceLocationProvider.cs
- XmlSchemaSimpleTypeUnion.cs
- IQueryable.cs
- SqlUDTStorage.cs
- UnitySerializationHolder.cs
- Rijndael.cs
- DoubleAnimation.cs
- Clipboard.cs
- AccessDataSourceView.cs
- PolygonHotSpot.cs
- CodeBlockBuilder.cs
- StrokeNodeEnumerator.cs
- DbConnectionPool.cs
- XmlDesigner.cs
- LogWriteRestartAreaState.cs
- ConnectionModeReader.cs
- DataGridParentRows.cs
- FormatSettings.cs
- CodeDirectionExpression.cs
- IntellisenseTextBox.designer.cs
- XmlReflectionMember.cs
- LinqDataSourceHelper.cs
- FileUpload.cs
- ScheduleChanges.cs
- XmlReaderSettings.cs
- WsiProfilesElementCollection.cs
- DBSqlParserColumn.cs
- DoubleLinkListEnumerator.cs
- ChannelServices.cs
- RayHitTestParameters.cs
- Wildcard.cs
- Window.cs
- RightsManagementPermission.cs
- XmlStringTable.cs
- XmlUtf8RawTextWriter.cs
- ScopelessEnumAttribute.cs
- ValidationResults.cs
- AccessorTable.cs
- Int16AnimationUsingKeyFrames.cs
- XamlSerializerUtil.cs
- BinaryReader.cs
- DataSourceHelper.cs
- DBSqlParser.cs
- EraserBehavior.cs
- ServiceThrottlingBehavior.cs
- DBParameter.cs
- ReferenceSchema.cs
- NumberFunctions.cs
- QueueProcessor.cs
- serverconfig.cs
- PerformanceCounterManager.cs
- TableItemPatternIdentifiers.cs
- TextRangeSerialization.cs
- StrongNamePublicKeyBlob.cs
- TextViewElement.cs
- Span.cs
- IDictionary.cs
- BufferedReceiveElement.cs
- ByteStack.cs
- DPCustomTypeDescriptor.cs
- XhtmlBasicLinkAdapter.cs
- GetPageCompletedEventArgs.cs
- ClassicBorderDecorator.cs
- HttpStreamXmlDictionaryWriter.cs
- ImageInfo.cs
- ToolStripHighContrastRenderer.cs
- BamlMapTable.cs
- ClientSettingsSection.cs
- WindowsRichEdit.cs
- RectConverter.cs
- PropertyManager.cs
- ToolZone.cs
- TransformerInfo.cs
- ValueHandle.cs
- Crc32Helper.cs
- _HeaderInfoTable.cs
- AuthenticationConfig.cs
- DeclarationUpdate.cs
- X509KeyIdentifierClauseType.cs
- EventSchemaTraceListener.cs
- ValueTable.cs
- PropertyCollection.cs
- CompilerCollection.cs
- Behavior.cs
- DataGridRowHeaderAutomationPeer.cs