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
- Visitors.cs
- SynthesizerStateChangedEventArgs.cs
- DataBindingValueUIHandler.cs
- FaultDesigner.cs
- ColorMatrix.cs
- EntityProviderFactory.cs
- ContainerControl.cs
- Geometry.cs
- FixedSOMGroup.cs
- ObjectComplexPropertyMapping.cs
- XmlSignatureProperties.cs
- ReliabilityContractAttribute.cs
- FloaterBaseParaClient.cs
- Transaction.cs
- HtmlToClrEventProxy.cs
- RowToFieldTransformer.cs
- ParserHooks.cs
- HtmlEncodedRawTextWriter.cs
- XmlDocumentType.cs
- ByteStreamGeometryContext.cs
- DataServiceKeyAttribute.cs
- translator.cs
- ControlBindingsCollection.cs
- VerificationAttribute.cs
- HwndSource.cs
- InvalidContentTypeException.cs
- ContextItem.cs
- CFStream.cs
- Keywords.cs
- WindowsScrollBar.cs
- ButtonBaseAdapter.cs
- SystemEvents.cs
- Package.cs
- TopClause.cs
- ImageListStreamer.cs
- ProtectedConfigurationSection.cs
- WebEventTraceProvider.cs
- EntityContainer.cs
- FrameworkRichTextComposition.cs
- SystemDiagnosticsSection.cs
- IPEndPointCollection.cs
- GenericNameHandler.cs
- MatrixTransform.cs
- WorkflowApplicationIdleEventArgs.cs
- RadioButtonList.cs
- TrustManagerPromptUI.cs
- SmiGettersStream.cs
- TreeIterator.cs
- NetworkInformationException.cs
- WebPartActionVerb.cs
- CaseCqlBlock.cs
- DbBuffer.cs
- HttpRequestCacheValidator.cs
- BrowserTree.cs
- DoubleAnimationClockResource.cs
- IntSecurity.cs
- SystemResources.cs
- PingOptions.cs
- SHA512.cs
- MetadataItemCollectionFactory.cs
- TextEffect.cs
- CacheForPrimitiveTypes.cs
- TextTreeUndo.cs
- StrongBox.cs
- EDesignUtil.cs
- Mapping.cs
- HelpKeywordAttribute.cs
- ArrayElementGridEntry.cs
- LoginView.cs
- DesignBindingPicker.cs
- CompilationSection.cs
- HttpContext.cs
- CalendarDesigner.cs
- StatusBarItemAutomationPeer.cs
- StrokeIntersection.cs
- XPathQueryGenerator.cs
- WmfPlaceableFileHeader.cs
- FileDialog.cs
- ProcessHostServerConfig.cs
- ellipse.cs
- BigInt.cs
- HtmlTernaryTree.cs
- XpsPackagingPolicy.cs
- SqlDataSourceRefreshSchemaForm.cs
- UriExt.cs
- OracleNumber.cs
- BufferModesCollection.cs
- Application.cs
- PropertyGridEditorPart.cs
- WindowsSspiNegotiation.cs
- CompilerCollection.cs
- DataGridColumnHeadersPresenterAutomationPeer.cs
- FtpCachePolicyElement.cs
- EntityViewContainer.cs
- Style.cs
- PerfService.cs
- StickyNote.cs
- DesignTimeValidationFeature.cs
- IntSecurity.cs
- ResourceDefaultValueAttribute.cs