// No impact on AutoIncrementCurrent if over written internal int CopyRecord(DataTable src, int record, int copy) { if (record == -1) { return(copy); } Debug.Assert(src != null, "Can not Merge record without a table"); int newRecord = copy; if (copy == -1) { newRecord = table.NewUninitializedRecord(); } for (int i = 0; i < table.Columns.Count; ++i) { DataColumn objColumn = table.Columns[i]; int iSrc = src.Columns.IndexOf(objColumn.ColumnName); if (iSrc >= 0) { SetValue(newRecord, i, src.Columns[iSrc][record, false]); } else { if (copy == -1) { objColumn.Init(newRecord); } } } return(newRecord); }
// No impact on AutoIncrementCurrent if over written internal int CopyRecord(DataTable src, int record, int copy) { Debug.Assert(src != null, "Can not Merge record without a table"); if (record == -1) { return(copy); } int newRecord = -1; try { if (copy == -1) { newRecord = table.NewUninitializedRecord(); } else { newRecord = copy; } int count = table.Columns.Count; for (int i = 0; i < count; ++i) { DataColumn dstColumn = table.Columns[i]; DataColumn srcColumn = src.Columns[dstColumn.ColumnName]; if (null != srcColumn) { object value = srcColumn[record]; ICloneable cloneableObject = value as ICloneable; if (null != cloneableObject) { dstColumn[newRecord] = cloneableObject.Clone(); } else { dstColumn[newRecord] = value; } } else if (-1 == copy) { dstColumn.Init(newRecord); } } } catch (Exception e) { // if (Common.ADP.IsCatchableOrSecurityExceptionType(e)) { if (-1 == copy) { FreeRecord(ref newRecord); } } throw; } return(newRecord); }
// Loads a table. // Yes, I know it's a big method. This is done to avoid performance penalty of calling methods // with many arguments and to keep recursion within one method only. To make code readable, // this method divided into 3 parts: attribute processing (including diffgram), // nested elements processing and loading data. Please keep it this way. private void LoadTable(DataTable table, bool isNested ) { // <DataSet> /--------------------------- We are here on entrance // <Table> // <Column>Value</Column> // <AnotherColumn>Value</AnotherColumn> // </Table> /-------------------------- We are here on exit // <AnotherTable> // ... // </AnotherTable> // ... // </DataSet> Debug.Assert (table != null, "Table to be loaded is null on LoadTable() entry"); DataRow row = null; // Data row we're going to add to this table int entryDepth = dataReader.Depth; // Store current reader depth so we know when to stop reading int entryChild = childRowsStack.Count; // Memorize child stack level on entry DataColumn c; // Hold column here DataColumnCollection collection = table.Columns; // Hold column collectio here object[] foundColumns = new object[collection.Count]; // This is the columns data we found // This is used to process diffgramms int rowOrder = -1; // Row to insert data to string diffId = String.Empty; // Diffgram ID string string hasChanges = null; // Changes string bool hasErrors = false; // Set this in case of problem string textNodeValue; // Value of a text node we might have // Process attributes first for ( int i = dataReader.AttributeCount -1; i >= 0; --i) { // Check all attributes one by one dataReader.MoveToAttribute(i); // Get this attribute c = nodeToSchemaMap.GetColumnSchema(table, dataReader, FIgnoreNamespace(dataReader)) as DataColumn; // Try to get column for this attribute if ((c != null) && (c.ColumnMapping == MappingType.Attribute)) { // Yep, it is a column mapped as attribute // Get value from XML and store it in the object array foundColumns[c.Ordinal] = c.ConvertXmlToObject(dataReader.Value); } // Oops. No column for this element // // else if (table.XmlText != null && // dataReader.NamespaceURI == Keywords.XSINS && // dataReader.LocalName == Keywords.XSI_NIL ) { // // Got XMLText column and it's a NIL attribute? // if (XmlConvert.ToBoolean(dataReader.Value)) { // // If NIL attribute set to true... // // Assign DBNull to XmlText column // foundColumns[table.XmlText.Ordinal] = DBNull.Value; // } // } if ( isDiffgram ) { // Now handle some diffgram attributes if ( dataReader.NamespaceURI == Keywords.DFFNS ) { switch (dataReader.LocalName) { case Keywords.DIFFID: // Is it a diffgeam ID ? diffId = dataReader.Value; // Store ID break; case Keywords.HASCHANGES: // Has chages attribute ? hasChanges = dataReader.Value; // Store value break; case Keywords.HASERRORS: // Has errors attribute ? hasErrors = (bool)Convert.ChangeType(dataReader.Value, typeof(bool), CultureInfo.InvariantCulture); // Store value break; } } else if ( dataReader.NamespaceURI == Keywords.MSDNS ) { if ( dataReader.LocalName == Keywords.ROWORDER ) { // Is it a row order attribute ? rowOrder = (Int32)Convert.ChangeType(dataReader.Value, typeof(Int32), CultureInfo.InvariantCulture); // Store it } else if (dataReader.LocalName.StartsWith("hidden", StringComparison.Ordinal)) { // Hidden column ? c = collection[XmlConvert.DecodeName(dataReader.LocalName.Substring(6))]; // Let's see if we have one. // We have to decode name before we look it up // We could not use XmlToDataSet map as it contains // no hidden columns if (( c != null) && (c.ColumnMapping == MappingType.Hidden)) { // Got column and it is hidden ? foundColumns[c.Ordinal] = c.ConvertXmlToObject(dataReader.Value); } } } } } // Done with attributes // Now handle elements. This could be columns or nested tables. // <DataSet> /------------------- We are here after dealing with attributes // <Table foo="FooValue" bar="BarValue"> // <Column>Value</Column> // <AnotherColumn>Value</AnotherColumn> // </Table> // </DataSet> if ( dataReader.Read() && entryDepth < dataReader.Depth) { // Read to the next element and see if we're inside while ( entryDepth < dataReader.Depth ) { // Get out as soon as we've processed all nested nodes. switch (dataReader.NodeType) { // Process nodes based on type case XmlNodeType.Element: // It's an element object o = nodeToSchemaMap.GetColumnSchema(table, dataReader, FIgnoreNamespace(dataReader)); // Get dataset element for this XML element c = o as DataColumn; // Perhaps, it's a column? if ( c != null ) { // Do we have matched column in this table? // Let's load column data if (foundColumns[c.Ordinal] == null) { // If this column was not found before LoadColumn (c, foundColumns); // Get column value } else { dataReader.Read(); // Advance to next element. } } else { DataTable nestedTable = o as DataTable; // Perhaps, it's a nested table ? if ( nestedTable != null ) { // Do we have matched nested table in DataSet ? LoadTable (nestedTable, true /* isNested */); // Yes. Load nested table (recursive) } // Not a table nor column? Check if it's schema. else if (ProcessXsdSchema()) { // Check for schema. Skip or load if found. continue; // Schema has been found. Process the next element // we're already at (done by schema processing). } else { // We've got element which is not supposed to he here according to the schema. // That might be a table which was misplaced. We should've thrown on that, // but we'll try to load it so we could keep compatibility. // We won't try to match to columns as we have no idea // which table this potential column might belong to. DataTable misplacedTable = nodeToSchemaMap.GetTableForNode(dataReader, FIgnoreNamespace(dataReader)); // Try to get table for node if (misplacedTable != null) { // Got some matching table? LoadTable (misplacedTable, false /* isNested */); // While table's XML element is nested, // the table itself is not. Load it this way. } else { dataReader.Read(); // Not a table? Try next element. } } } break; case XmlNodeType.EntityReference: // Oops. No support for Entity Reference throw ExceptionBuilder.FoundEntity(); case XmlNodeType.Text: // It looks like a text. case XmlNodeType.Whitespace: // This actually could be case XmlNodeType.CDATA: // if we have XmlText in our table case XmlNodeType.SignificantWhitespace: textNodeValue = dataReader.ReadString(); // Get text node value. c = table.xmlText; // Get XML Text column from our table if (c != null && foundColumns[c.Ordinal] == null) { // If XmlText Column is set // and we do not have data already foundColumns[c.Ordinal] = c.ConvertXmlToObject(textNodeValue); // Read and store the data } break; default: dataReader.Read(); // We don't process that, skip to the next element. break; } } dataReader.Read(); // We're done here, proceed to the next element. } // It's the time to populate row with loaded data and add it to the table we'we just read to the table if (isDiffgram) { // In case of diffgram row = table.NewRow(table.NewUninitializedRecord()); // just create an empty row row.BeginEdit(); // and allow it's population with data for ( int i = foundColumns.Length - 1; i >= 0 ; --i) { // Check all columns c = collection[i]; // Get column for this index c[row.tempRecord] = null != foundColumns[i] ? foundColumns[i] : DBNull.Value; // Set column to loaded value of to // DBNull if value is missing. } row.EndEdit(); // Done with this row table.Rows.DiffInsertAt(row, rowOrder); // insert data to specific location // And do some diff processing if (hasChanges == null) { // No changes ? row.oldRecord = row.newRecord; // Restore old record } if ((hasChanges == Keywords.MODIFIED) || hasErrors) { table.RowDiffId[diffId] = row; } } else { for ( int i = foundColumns.Length -1; i >= 0 ; --i) { // Check all columns if (null == foundColumns[i]) { // Got data for this column ? c = collection[i]; // No. Get column for this index if (c.AllowDBNull && c.ColumnMapping != MappingType.Hidden && !c.AutoIncrement) { foundColumns[i] = DBNull.Value; // Assign DBNull if possible // table.Rows.Add() below will deal // with default values and autoincrement } } } row = table.Rows.AddWithColumnEvents(foundColumns); // Create, populate and add row } // Data is loaded into the row and row is added to the table at this point while (entryChild < childRowsStack.Count) { // Process child rows we might have DataRow childRow = (DataRow) childRowsStack.Pop(); // Get row from the stack bool unchanged = (childRow.RowState == DataRowState.Unchanged); // Is data the same as before? childRow.SetNestedParentRow(row, /*setNonNested*/ false); // Set parent row if (unchanged) // Restore record if child row's unchanged childRow.oldRecord = childRow.newRecord; } if (isNested) // Got parent ? childRowsStack.Push(row); // Push row to the stack }
private void LoadTable(DataTable table, bool isNested) { DataColumn xmlText; DataRow row = null; int depth = this.dataReader.Depth; int count = this.childRowsStack.Count; DataColumnCollection columns = table.Columns; object[] foundColumns = new object[columns.Count]; int pos = -1; string str3 = string.Empty; string str2 = null; bool flag = false; for (int i = this.dataReader.AttributeCount - 1; i >= 0; i--) { this.dataReader.MoveToAttribute(i); xmlText = this.nodeToSchemaMap.GetColumnSchema(table, this.dataReader, this.FIgnoreNamespace(this.dataReader)) as DataColumn; if ((xmlText != null) && (xmlText.ColumnMapping == MappingType.Attribute)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(this.dataReader.Value); } if (this.isDiffgram) { if (!(this.dataReader.NamespaceURI == "urn:schemas-microsoft-com:xml-diffgram-v1")) { goto Label_0161; } string localName = this.dataReader.LocalName; if (localName != null) { if (!(localName == "id")) { if (localName == "hasChanges") { goto Label_0124; } if (localName == "hasErrors") { goto Label_0136; } } else { str3 = this.dataReader.Value; } } } continue; Label_0124: str2 = this.dataReader.Value; continue; Label_0136: flag = (bool)Convert.ChangeType(this.dataReader.Value, typeof(bool), CultureInfo.InvariantCulture); continue; Label_0161: if (this.dataReader.NamespaceURI == "urn:schemas-microsoft-com:xml-msdata") { if (this.dataReader.LocalName == "rowOrder") { pos = (int)Convert.ChangeType(this.dataReader.Value, typeof(int), CultureInfo.InvariantCulture); } else if (this.dataReader.LocalName.StartsWith("hidden", StringComparison.Ordinal)) { xmlText = columns[XmlConvert.DecodeName(this.dataReader.LocalName.Substring(6))]; if ((xmlText != null) && (xmlText.ColumnMapping == MappingType.Hidden)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(this.dataReader.Value); } } } } if (this.dataReader.Read() && (depth < this.dataReader.Depth)) { while (depth < this.dataReader.Depth) { DataTable table3; object obj2; switch (this.dataReader.NodeType) { case XmlNodeType.Element: { obj2 = this.nodeToSchemaMap.GetColumnSchema(table, this.dataReader, this.FIgnoreNamespace(this.dataReader)); xmlText = obj2 as DataColumn; if (xmlText == null) { goto Label_02DE; } if (foundColumns[xmlText.Ordinal] != null) { break; } this.LoadColumn(xmlText, foundColumns); continue; } case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: { string s = this.dataReader.ReadString(); xmlText = table.xmlText; if ((xmlText != null) && (foundColumns[xmlText.Ordinal] == null)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(s); } continue; } case XmlNodeType.EntityReference: throw ExceptionBuilder.FoundEntity(); default: goto Label_0379; } this.dataReader.Read(); continue; Label_02DE: table3 = obj2 as DataTable; if (table3 != null) { this.LoadTable(table3, true); } else if (!this.ProcessXsdSchema()) { DataTable tableForNode = this.nodeToSchemaMap.GetTableForNode(this.dataReader, this.FIgnoreNamespace(this.dataReader)); if (tableForNode != null) { this.LoadTable(tableForNode, false); } else { this.dataReader.Read(); } } continue; Label_0379: this.dataReader.Read(); } this.dataReader.Read(); } if (this.isDiffgram) { row = table.NewRow(table.NewUninitializedRecord()); row.BeginEdit(); for (int j = foundColumns.Length - 1; j >= 0; j--) { xmlText = columns[j]; xmlText[row.tempRecord] = (foundColumns[j] != null) ? foundColumns[j] : DBNull.Value; } row.EndEdit(); table.Rows.DiffInsertAt(row, pos); if (str2 == null) { row.oldRecord = row.newRecord; } if ((str2 == "modified") || flag) { table.RowDiffId[str3] = row; } } else { for (int k = foundColumns.Length - 1; k >= 0; k--) { if (foundColumns[k] == null) { xmlText = columns[k]; if ((xmlText.AllowDBNull && (xmlText.ColumnMapping != MappingType.Hidden)) && !xmlText.AutoIncrement) { foundColumns[k] = DBNull.Value; } } } row = table.Rows.AddWithColumnEvents(foundColumns); } while (count < this.childRowsStack.Count) { DataRow row2 = (DataRow)this.childRowsStack.Pop(); bool flag2 = row2.RowState == DataRowState.Unchanged; row2.SetNestedParentRow(row, false); if (flag2) { row2.oldRecord = row2.newRecord; } } if (isNested) { this.childRowsStack.Push(row); } }
private void LoadTable(DataTable table, bool isNested) { DataColumn xmlText; DataRow row = null; int depth = this.dataReader.Depth; int count = this.childRowsStack.Count; DataColumnCollection columns = table.Columns; object[] foundColumns = new object[columns.Count]; int pos = -1; string str3 = string.Empty; string str2 = null; bool flag = false; for (int i = this.dataReader.AttributeCount - 1; i >= 0; i--) { this.dataReader.MoveToAttribute(i); xmlText = this.nodeToSchemaMap.GetColumnSchema(table, this.dataReader, this.FIgnoreNamespace(this.dataReader)) as DataColumn; if ((xmlText != null) && (xmlText.ColumnMapping == MappingType.Attribute)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(this.dataReader.Value); } if (this.isDiffgram) { if (!(this.dataReader.NamespaceURI == "urn:schemas-microsoft-com:xml-diffgram-v1")) { goto Label_0161; } string localName = this.dataReader.LocalName; if (localName != null) { if (!(localName == "id")) { if (localName == "hasChanges") { goto Label_0124; } if (localName == "hasErrors") { goto Label_0136; } } else { str3 = this.dataReader.Value; } } } continue; Label_0124: str2 = this.dataReader.Value; continue; Label_0136: flag = (bool) Convert.ChangeType(this.dataReader.Value, typeof(bool), CultureInfo.InvariantCulture); continue; Label_0161: if (this.dataReader.NamespaceURI == "urn:schemas-microsoft-com:xml-msdata") { if (this.dataReader.LocalName == "rowOrder") { pos = (int) Convert.ChangeType(this.dataReader.Value, typeof(int), CultureInfo.InvariantCulture); } else if (this.dataReader.LocalName.StartsWith("hidden", StringComparison.Ordinal)) { xmlText = columns[XmlConvert.DecodeName(this.dataReader.LocalName.Substring(6))]; if ((xmlText != null) && (xmlText.ColumnMapping == MappingType.Hidden)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(this.dataReader.Value); } } } } if (this.dataReader.Read() && (depth < this.dataReader.Depth)) { while (depth < this.dataReader.Depth) { DataTable table3; object obj2; switch (this.dataReader.NodeType) { case XmlNodeType.Element: { obj2 = this.nodeToSchemaMap.GetColumnSchema(table, this.dataReader, this.FIgnoreNamespace(this.dataReader)); xmlText = obj2 as DataColumn; if (xmlText == null) { goto Label_02DE; } if (foundColumns[xmlText.Ordinal] != null) { break; } this.LoadColumn(xmlText, foundColumns); continue; } case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: { string s = this.dataReader.ReadString(); xmlText = table.xmlText; if ((xmlText != null) && (foundColumns[xmlText.Ordinal] == null)) { foundColumns[xmlText.Ordinal] = xmlText.ConvertXmlToObject(s); } continue; } case XmlNodeType.EntityReference: throw ExceptionBuilder.FoundEntity(); default: goto Label_0379; } this.dataReader.Read(); continue; Label_02DE: table3 = obj2 as DataTable; if (table3 != null) { this.LoadTable(table3, true); } else if (!this.ProcessXsdSchema()) { DataTable tableForNode = this.nodeToSchemaMap.GetTableForNode(this.dataReader, this.FIgnoreNamespace(this.dataReader)); if (tableForNode != null) { this.LoadTable(tableForNode, false); } else { this.dataReader.Read(); } } continue; Label_0379: this.dataReader.Read(); } this.dataReader.Read(); } if (this.isDiffgram) { row = table.NewRow(table.NewUninitializedRecord()); row.BeginEdit(); for (int j = foundColumns.Length - 1; j >= 0; j--) { xmlText = columns[j]; xmlText[row.tempRecord] = (foundColumns[j] != null) ? foundColumns[j] : DBNull.Value; } row.EndEdit(); table.Rows.DiffInsertAt(row, pos); if (str2 == null) { row.oldRecord = row.newRecord; } if ((str2 == "modified") || flag) { table.RowDiffId[str3] = row; } } else { for (int k = foundColumns.Length - 1; k >= 0; k--) { if (foundColumns[k] == null) { xmlText = columns[k]; if ((xmlText.AllowDBNull && (xmlText.ColumnMapping != MappingType.Hidden)) && !xmlText.AutoIncrement) { foundColumns[k] = DBNull.Value; } } } row = table.Rows.AddWithColumnEvents(foundColumns); } while (count < this.childRowsStack.Count) { DataRow row2 = (DataRow) this.childRowsStack.Pop(); bool flag2 = row2.RowState == DataRowState.Unchanged; row2.SetNestedParentRow(row, false); if (flag2) { row2.oldRecord = row2.newRecord; } } if (isNested) { this.childRowsStack.Push(row); } }