Code:
/ DotNET / DotNET / 8.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
- PersistNameAttribute.cs
- PropertyAccessVisitor.cs
- HealthMonitoringSection.cs
- PartitionedStream.cs
- XPathPatternParser.cs
- XmlWriterTraceListener.cs
- BulletedListEventArgs.cs
- RSAPKCS1KeyExchangeFormatter.cs
- ColorConverter.cs
- DistributedTransactionPermission.cs
- MgmtResManager.cs
- ExtendLockAsyncResult.cs
- documentation.cs
- RotateTransform.cs
- RbTree.cs
- CompositeFontParser.cs
- GeometryCombineModeValidation.cs
- MD5.cs
- ListDesigner.cs
- BigInt.cs
- BoundingRectTracker.cs
- Stack.cs
- LayoutInformation.cs
- SqlGenerator.cs
- SequentialUshortCollection.cs
- X509UI.cs
- MaterialCollection.cs
- MediaTimeline.cs
- DataRecord.cs
- DetailsViewPageEventArgs.cs
- EnumMemberAttribute.cs
- RegionData.cs
- CompressedStack.cs
- DataGrid.cs
- Win32SafeHandles.cs
- DataGridPageChangedEventArgs.cs
- WebPartEditVerb.cs
- CollaborationHelperFunctions.cs
- VectorValueSerializer.cs
- NavigationProperty.cs
- ClientRolePrincipal.cs
- DataTableMappingCollection.cs
- CodeMemberEvent.cs
- ToolStripDropDown.cs
- TransactedBatchingBehavior.cs
- CharacterBuffer.cs
- CorrelationTokenInvalidatedHandler.cs
- BufferedGraphicsManager.cs
- ReflectPropertyDescriptor.cs
- ErrorFormatter.cs
- EmptyEnumerator.cs
- ListControlDesigner.cs
- Bind.cs
- PropertySegmentSerializationProvider.cs
- XmlSchemaAll.cs
- TransformConverter.cs
- MouseOverProperty.cs
- FileLevelControlBuilderAttribute.cs
- Brushes.cs
- MergeLocalizationDirectives.cs
- ArrayTypeMismatchException.cs
- Line.cs
- TreeViewAutomationPeer.cs
- CqlBlock.cs
- ConditionalExpression.cs
- PtsHelper.cs
- ProfilePropertySettings.cs
- UseAttributeSetsAction.cs
- ConnectionStringsExpressionEditor.cs
- CellPartitioner.cs
- Schema.cs
- RsaSecurityTokenAuthenticator.cs
- WrappedIUnknown.cs
- LayeredChannelFactory.cs
- KeyboardEventArgs.cs
- AccessDataSourceView.cs
- CookieHandler.cs
- CodeAccessPermission.cs
- KeyValueInternalCollection.cs
- DataContractJsonSerializerOperationBehavior.cs
- ProgressiveCrcCalculatingStream.cs
- InstanceDataCollection.cs
- AsymmetricAlgorithm.cs
- ButtonFlatAdapter.cs
- DmlSqlGenerator.cs
- graph.cs
- HeaderCollection.cs
- TaskHelper.cs
- WindowPattern.cs
- ValueType.cs
- Vector3dCollection.cs
- TokenCreationParameter.cs
- CaretElement.cs
- WebPartManager.cs
- CapabilitiesPattern.cs
- LogArchiveSnapshot.cs
- AnnouncementEndpointElement.cs
- ScriptManager.cs
- SynchronizationFilter.cs
- GridViewRowCollection.cs