private void AssertNonLiveRows(XmlNode node) { bool wasFoliationEnabled = IsFoliationEnabled; IsFoliationEnabled = false; try { XmlBoundElement rowElement = node as XmlBoundElement; if (rowElement != null && rowElement.Row != null) Debug.Assert(!IsRowLive(rowElement.Row)); TreeIterator iter = new TreeIterator(node); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRowElement()) { rowElement = iter.CurrentNode as XmlBoundElement; Debug.Assert(rowElement.Row != null); Debug.Assert(!IsRowLive(rowElement.Row)); } } finally { IsFoliationEnabled = wasFoliationEnabled; } }
// A non-row-elem was inserted into the connected tree (connected) from oldParent==null state private void OnNonRowElementInsertedInTree(XmlNode node, XmlBoundElement rowElement, ArrayList rowElemList) { // non-row-elem is beeing inserted DataRow row = rowElement.Row; // Region should already have an associated data row (otherwise how was the original row-elem inserted ?) Debug.Assert(row != null); SynchronizeRowFromRowElement(rowElement); if (rowElemList != null) { TreeIterator iter = new TreeIterator(node); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement()) rowElemList.Add(iter.CurrentNode); } }
// A node (node) was inserted into the main tree (connected) from oldParent==null state private void OnNodeInsertedInTree(XmlNode node) { XmlBoundElement be; ArrayList rowElemList = new ArrayList(); if (_mapper.GetRegion(node, out be)) { if (be == node) { OnRowElementInsertedInTree(be, rowElemList); } else { OnNonRowElementInsertedInTree(node, be, rowElemList); } } else { // We only need to sync the embedded sub-regions TreeIterator iter = new TreeIterator(node); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement()) rowElemList.Add(iter.CurrentNode); } // Process subregions, so they make transition from disconnected to connected tree while (rowElemList.Count > 0) { Debug.Assert(rowElemList[0] != null && rowElemList[0] is XmlBoundElement); XmlBoundElement subRowElem = (XmlBoundElement)(rowElemList[0]); rowElemList.RemoveAt(0); // Expect rowElem to have a DataTable schema, since it is a sub-region Debug.Assert(subRowElem != null); OnRowElementInsertedInTree(subRowElem, rowElemList); } // Assert that all sub-regions are assoc w/ "live" rows AssertLiveRows(node); }
// Promote child regions under parent as next siblings of parent private void PromoteInnerRegions(XmlNode parent) { Debug.Assert(parent != null); Debug.Assert(parent.NodeType != XmlNodeType.Attribute); // We need to get get the grand-parent region Debug.Assert(parent != DocumentElement); // We cannot promote children of the DocumentElement XmlNode prevSibling = parent; XmlBoundElement parentRegionRowElem; _mapper.GetRegion(parent.ParentNode, out parentRegionRowElem); TreeIterator iter = new TreeIterator(parent); bool fMore = iter.NextRowElement(); while (fMore) { Debug.Assert(iter.CurrentNode is XmlBoundElement && ((XmlBoundElement)(iter.CurrentNode)).Row != null); XmlBoundElement rowElemChild = (XmlBoundElement)(iter.CurrentNode); fMore = iter.NextRightRowElement(); PromoteChild(rowElemChild, prevSibling); SetNestedParentRegion(rowElemChild, parentRegionRowElem); } }
// Node was removed from the disconnected tree to disconnected tree private void OnNodeRemovedFromFragment(XmlNode node, XmlNode oldParent) { XmlBoundElement oldRowElem; if (_mapper.GetRegion(oldParent, out oldRowElem)) { // Sync the old region if it is not deleted DataRow row = oldRowElem.Row; // Since the old old region was disconnected, then the row can be only Deleted or Detached Debug.Assert(!IsRowLive(row)); if (oldRowElem.Row.RowState == DataRowState.Detached) SynchronizeRowFromRowElement(oldRowElem); } // Need to set nested for the sub-regions (if node is a row-elem, we need to set it just for itself) XmlBoundElement be = node as XmlBoundElement; if (be != null && be.Row != null) { Debug.Assert(!IsRowLive(be.Row)); SetNestedParentRegion(be, null); } else { // Set nested parent to null for all child regions TreeIterator iter = new TreeIterator(node); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement()) { XmlBoundElement rowElemChild = (XmlBoundElement)(iter.CurrentNode); SetNestedParentRegion(rowElemChild, null); } } // Assert that all sub-regions are disconnected AssertNonLiveRows(node); }
// Node was removed from connected tree to disconnected tree private void OnNodeRemovedFromTree(XmlNode node, XmlNode oldParent) { XmlBoundElement oldRowElem; // Synchronize values from old region if (_mapper.GetRegion(oldParent, out oldRowElem)) SynchronizeRowFromRowElement(oldRowElem); // Disconnect all regions, starting w/ node (if it is a row-elem) XmlBoundElement rowElem = node as XmlBoundElement; if (rowElem != null && rowElem.Row != null) EnsureDisconnectedDataRow(rowElem); TreeIterator iter = new TreeIterator(node); for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRowElement()) { rowElem = (XmlBoundElement)(iter.CurrentNode); EnsureDisconnectedDataRow(rowElem); } // Assert that all sub-regions are disconnected AssertNonLiveRows(node); }