+2006-10-18 Nagappan A <anagappan@novell.com>
+
+ * ForeignKeyConstraint.cs (_validateColumns): Parent and child
+ columns can't be the same column - Exception, bug # 79689
+
2006-10-13 Nagappan A <anagappan@novell.com>
* DataTable.cs (DeserializeConstraints): Fine tuned the
#79233. DuplicateNameException when two relations for different
DataTables in DataSet are defined
+2006-10-06 Patrick Earl <mono@patearl.net>
+
+ * DataTable.cs, XmlTableWriter.cs, XmlSchemaWriter.cs, DataSet.cs:
+ Implemented DataTable.WriteXml
+
2006-09-26 Nagappan A <anagappan@novell.com>
* DataTable.cs, DataSet.cs, DataColumn.cs, Constraint.cs,
using System.Threading;\r
using System.IO;\r
using System.Runtime.Serialization;\r
+#if NET_2_0\r
using System.Runtime.Serialization.Formatters.Binary;\r
+#endif\r
using System.Xml;\r
using System.Xml.Schema;\r
using System.Xml.Serialization;\r
WriteTable ( writer, table, mode, version);\r
}\r
\r
- private void WriteTable (XmlWriter writer, DataTable table, XmlWriteMode mode, DataRowVersion version)\r
+ internal static void WriteTable (XmlWriter writer, DataTable table, XmlWriteMode mode, DataRowVersion version)\r
{\r
DataRow[] rows = table.NewRowArray(table.Rows.Count);\r
table.Rows.CopyTo (rows, 0);\r
WriteTable (writer, rows, mode, version, true);\r
}\r
\r
- private void WriteTable (XmlWriter writer,\r
+ internal static void WriteTable (XmlWriter writer,\r
DataRow [] rows,\r
XmlWriteMode mode,\r
DataRowVersion version, bool skipIfNested)\r
{\r
+ if (rows.Length == 0) return;\r
+ DataTable table = rows[0].Table;\r
+\r
+ if (table.TableName == null || table.TableName == "")\r
+ throw new InvalidOperationException("Cannot serialize the DataTable. DataTable name is not set.");\r
+\r
//The columns can be attributes, hidden, elements, or simple content\r
//There can be 0-1 simple content cols or 0-* elements\r
System.Collections.ArrayList atts;\r
System.Collections.ArrayList elements;\r
DataColumn simple = null;\r
\r
- if (rows.Length == 0) return;\r
- DataTable table = rows[0].Table;\r
SplitColumns (table, out atts, out elements, out simple);\r
//sort out the namespacing\r
- string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;\r
+ string nspc = (table.Namespace.Length > 0 || table.DataSet == null) ? table.Namespace : table.DataSet.Namespace;\r
int relationCount = table.ParentRelations.Count;\r
DataRelation oneRel = relationCount == 1 ? table.ParentRelations [0] : null;\r
\r
\r
}\r
\r
- private void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)\r
+ internal static void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)\r
{\r
string colnspc = null;\r
object rowObject = row [col, version];\r
writer.WriteEndElement ();\r
}\r
\r
- private void WriteColumnAsAttribute (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)\r
+ internal static void WriteColumnAsAttribute (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)\r
{\r
if (!row.IsNull (col))\r
WriteAttributeString (writer, mode, col.Namespace, col.Prefix, XmlHelper.Encode (col.ColumnName), WriteObjectXml (row[col, version]));\r
}\r
\r
- private void WriteTableElement (XmlWriter writer, XmlWriteMode mode, DataTable table, DataRow row, DataRowVersion version)\r
+ internal static void WriteTableElement (XmlWriter writer, XmlWriteMode mode, DataTable table, DataRow row, DataRowVersion version)\r
{\r
//sort out the namespacing\r
- string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;\r
+ string nspc = (table.Namespace.Length > 0 || table.DataSet == null) ? table.Namespace : table.DataSet.Namespace;\r
\r
WriteStartElement (writer, mode, nspc, table.Prefix, XmlHelper.Encode (table.TableName));\r
\r
}\r
}\r
\r
- private void WriteStartElement (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name)\r
+ internal static void WriteStartElement (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name)\r
{\r
writer.WriteStartElement (prefix, name, nspc);\r
}\r
\r
- private void WriteAttributeString (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue)\r
+ internal static void WriteAttributeString (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue)\r
{\r
switch ( mode) {\r
case XmlWriteMode.WriteSchema:\r
internal void WriteIndividualTableContent (XmlWriter writer, DataTable table, XmlWriteMode mode)\r
{\r
if (mode == XmlWriteMode.DiffGram) {\r
- SetTableRowsID (table);\r
+ table.SetRowsID ();\r
WriteDiffGramElement (writer);\r
}\r
\r
}\r
}\r
\r
- private void WriteDiffGramElement(XmlWriter writer)\r
+ internal static void WriteDiffGramElement(XmlWriter writer)\r
{\r
WriteStartElement (writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "diffgram");\r
WriteAttributeString(writer, XmlWriteMode.DiffGram, null, "xmlns", XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);\r
\r
private void SetRowsID()\r
{\r
- foreach (DataTable Table in Tables)\r
- SetTableRowsID (Table);\r
+ foreach (DataTable table in Tables)\r
+ table.SetRowsID();\r
}\r
\r
- private void SetTableRowsID (DataTable Table)\r
- {\r
- int dataRowID = 0;\r
- foreach (DataRow Row in Table.Rows) {\r
- Row.XmlRowID = dataRowID;\r
- dataRowID++;\r
- }\r
- }\r
#endregion //Private Xml Serialisation\r
}\r
}\r
using System;\r
using System.Data.Common;\r
using System.Collections;\r
+#if NET_2_0\r
+using System.Collections.Generic;\r
+#endif\r
using System.ComponentModel;\r
using System.Globalization;\r
using System.IO;\r
}\r
\r
#if NET_2_0\r
- [MonoTODO]\r
- XmlReadMode ReadXml (Stream stream)\r
+ public XmlReadMode ReadXml (Stream stream)\r
+ {\r
+ return ReadXml (new XmlTextReader(stream, null));\r
+ }\r
+\r
+ public XmlReadMode ReadXml (string fileName)\r
+ {\r
+ XmlReader reader = new XmlTextReader(fileName);\r
+ try {\r
+ return ReadXml (reader);\r
+ } finally {\r
+ reader.Close();\r
+ }\r
+ }\r
+\r
+ public XmlReadMode ReadXml (TextReader reader)\r
{\r
- throw new NotImplementedException ();\r
+ return ReadXml (new XmlTextReader(reader));\r
+ }\r
+\r
+ [MonoTODO]\r
+ public XmlReadMode ReadXml (XmlReader reader)\r
+ {\r
+ // The documentation from MS for this method is rather\r
+ // poor. The following cases have been observed\r
+ // during testing:\r
+ //\r
+ // Reading a table from XML may create a DataSet to\r
+ // store child tables.\r
+ //\r
+ // If the table has at least one column present,\r
+ // we do not require the schema to be present in\r
+ // the xml. If the table has no columns, neither\r
+ // regular data nor diffgrams will be read, but\r
+ // will throw an error indicating that schema\r
+ // will not be inferred.\r
+ //\r
+ // We will likely need to take advantage of the\r
+ // msdata:MainDataTable attribute added to the\r
+ // schema info to load into the appropriate\r
+ // locations.\r
+\r
+ throw new NotImplementedException();\r
}\r
\r
public void ReadXmlSchema (Stream stream)\r
{\r
XmlWriterSettings s = new XmlWriterSettings ();\r
s.Indent = true;\r
+ s.OmitXmlDeclaration = true;\r
return s;\r
}\r
\r
public void WriteXml (Stream stream)\r
{\r
- WriteXml (stream, XmlWriteMode.IgnoreSchema);\r
+ WriteXml (stream, XmlWriteMode.IgnoreSchema, false);\r
}\r
\r
public void WriteXml (TextWriter writer)\r
{\r
- WriteXml (writer, XmlWriteMode.IgnoreSchema);\r
+ WriteXml (writer, XmlWriteMode.IgnoreSchema, false);\r
}\r
\r
public void WriteXml (XmlWriter writer)\r
{\r
- WriteXml (writer, XmlWriteMode.IgnoreSchema);\r
+ WriteXml (writer, XmlWriteMode.IgnoreSchema, false);\r
}\r
\r
public void WriteXml (string fileName)\r
{\r
- WriteXml (fileName, XmlWriteMode.IgnoreSchema);\r
+ WriteXml (fileName, XmlWriteMode.IgnoreSchema, false);\r
}\r
\r
public void WriteXml (Stream stream, XmlWriteMode mode)\r
{\r
- WriteXml (XmlWriter.Create (stream, GetWriterSettings ()), mode);\r
+ WriteXml (stream, mode, false);\r
}\r
\r
public void WriteXml (TextWriter writer, XmlWriteMode mode)\r
{\r
- WriteXml (XmlWriter.Create (writer, GetWriterSettings ()), mode);\r
+ WriteXml (writer, mode, false);\r
}\r
\r
- [MonoTODO]\r
public void WriteXml (XmlWriter writer, XmlWriteMode mode)\r
{\r
- throw new NotImplementedException ();\r
+ WriteXml (writer, mode, false);\r
}\r
\r
public void WriteXml (string fileName, XmlWriteMode mode)\r
+ {\r
+ WriteXml (fileName, mode, false);\r
+ }\r
+\r
+ public void WriteXml (Stream stream, bool writeHierarchy)\r
+ {\r
+ WriteXml (stream, XmlWriteMode.IgnoreSchema, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (string fileName, bool writeHierarchy)\r
+ {\r
+ WriteXml (fileName, XmlWriteMode.IgnoreSchema, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (TextWriter writer, bool writeHierarchy)\r
+ {\r
+ WriteXml (writer, XmlWriteMode.IgnoreSchema, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (XmlWriter writer, bool writeHierarchy)\r
+ {\r
+ WriteXml (writer, XmlWriteMode.IgnoreSchema, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (Stream stream, XmlWriteMode mode, bool writeHierarchy)\r
+ {\r
+ WriteXml (XmlWriter.Create (stream, GetWriterSettings ()), mode, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (string fileName, XmlWriteMode mode, bool writeHierarchy)\r
{\r
XmlWriter xw = null;\r
try {\r
xw = XmlWriter.Create (fileName, GetWriterSettings ());\r
- WriteXml (xw, mode);\r
+ WriteXml (xw, mode, writeHierarchy);\r
} finally {\r
if (xw != null)\r
xw.Close ();\r
}\r
}\r
\r
+ public void WriteXml (TextWriter writer, XmlWriteMode mode, bool writeHierarchy)\r
+ {\r
+ WriteXml (XmlWriter.Create (writer, GetWriterSettings ()), mode, writeHierarchy);\r
+ }\r
+\r
+ public void WriteXml (XmlWriter writer, XmlWriteMode mode, bool writeHierarchy)\r
+ {\r
+ // If we're in mode XmlWriteMode.WriteSchema, we need to output an extra\r
+ // msdata:MainDataTable attribute that wouldn't normally be part of the\r
+ // DataSet WriteXml output.\r
+ //\r
+ // For the writeHierarchy == true case, we write what would be output by\r
+ // a DataSet write, but we limit ourselves to our table and its descendants.\r
+ //\r
+ // For the writeHierarchy == false case, we write what would be output by\r
+ // a DataSet write, but we limit ourselves to this table.\r
+ //\r
+ // If the table is not in a DataSet, we follow the following behaviour:\r
+ // For WriteSchema cases, we do a write as if there is a wrapper\r
+ // dataset called NewDataSet.\r
+ // For IgnoreSchema or DiffGram cases, we do a write as if there\r
+ // is a wrapper dataset called DocumentElement.\r
+ \r
+ // Generate a list of tables to write.\r
+ List<DataTable> tables = new List<DataTable>(); \r
+ if (writeHierarchy == false)\r
+ tables.Add(this);\r
+ else\r
+ FindAllChildren(tables, this);\r
+\r
+ // If we're in a DataSet, generate a list of relations to write.\r
+ List<DataRelation> relations = new List<DataRelation>();\r
+ if (DataSet != null)\r
+ {\r
+ foreach(DataRelation relation in DataSet.Relations)\r
+ {\r
+ if(tables.Contains(relation.ParentTable) &&\r
+ tables.Contains(relation.ChildTable))\r
+ relations.Add(relation);\r
+ }\r
+ }\r
+\r
+ // Add the msdata:MainDataTable info if we're writing schema data.\r
+ string mainDataTable = null;\r
+ if (mode == XmlWriteMode.WriteSchema)\r
+ mainDataTable = this.TableName;\r
+\r
+ // Figure out the DataSet name.\r
+ string dataSetName = null;\r
+ if (DataSet != null)\r
+ dataSetName = DataSet.DataSetName;\r
+ else if (DataSet == null && mode == XmlWriteMode.WriteSchema)\r
+ dataSetName = "NewDataSet";\r
+ else\r
+ dataSetName = "DocumentElement";\r
+ \r
+ XmlTableWriter.WriteTables(writer, mode, tables, relations, mainDataTable, dataSetName);\r
+ }\r
+\r
+ private void FindAllChildren(List<DataTable> list, DataTable root)\r
+ {\r
+ if (!list.Contains(root))\r
+ {\r
+ list.Add(root);\r
+ foreach (DataRelation relation in root.ChildRelations)\r
+ {\r
+ FindAllChildren(list, relation.ChildTable);\r
+ }\r
+ }\r
+ }\r
+\r
public void WriteXmlSchema (Stream stream)\r
{\r
WriteXmlSchema (XmlWriter.Create (stream, GetWriterSettings ()));\r
internal void ResetPropertyDescriptorsCache() {\r
_propertyDescriptorsCache = null;\r
}\r
+\r
+ internal void SetRowsID()\r
+ {\r
+ int dataRowID = 0;\r
+ foreach (DataRow row in Rows) {\r
+ row.XmlRowID = dataRowID;\r
+ dataRowID++;\r
+ }\r
+ }\r
}\r
}\r
}
+ int identicalCols = 0;
for (int i = 0; i < parentColumns.Length; i++)
{
DataColumn pc = parentColumns[i];
DataColumn cc = childColumns[i];
- //Can't be the same column
- if (pc == cc)
- throw new InvalidOperationException("Parent and child columns can't be the same column.");
+ if (pc == cc) {
+ identicalCols++;
+ continue;
+ }
if (!pc.DataTypeMatches (cc)) {
//LAMESPEC: spec says throw InvalidConstraintException
+ " column.");
}
}
+ if (identicalCols == parentColumns.Length)
+ throw new InvalidOperationException ("Property not accessible because 'ParentKey and ChildKey are identical.'.");
}
XmlWriter writer, DataTableCollection tables,
DataRelationCollection relations)
{
- ds = dataset;
+ dataSetName = dataset.DataSetName;
+ dataSetNamespace = dataset.Namespace;
+ dataSetLocale = dataset.Locale;
+ dataSetProperties = dataset.ExtendedProperties;
+ w = writer;
+ if (tables != null) {
+ this.tables = new DataTable[tables.Count];
+ for(int i=0;i<tables.Count;i++) this.tables[i] = tables[i];
+ }
+ if (relations != null) {
+ this.relations = new DataRelation[relations.Count];
+ for(int i=0;i<relations.Count;i++) this.relations[i] = relations[i];
+ }
+ }
+
+ public XmlSchemaWriter (XmlWriter writer,
+ DataTable[] tables,
+ DataRelation[] relations,
+ string mainDataTable,
+ string dataSetName)
+ {
w = writer;
this.tables = tables;
this.relations = relations;
+ this.mainDataTable = mainDataTable;
+ this.dataSetName = dataSetName;
+ this.dataSetProperties = new PropertyCollection();
+ if (tables[0].DataSet != null) {
+ dataSetNamespace = tables[0].DataSet.Namespace;
+ dataSetLocale = tables[0].DataSet.Locale;
+ } else {
+ dataSetNamespace = tables[0].Namespace;
+ dataSetLocale = tables[0].Locale;
+ }
}
- DataSet ds;
XmlWriter w;
- DataTableCollection tables;
- DataRelationCollection relations;
+ DataTable[] tables;
+ DataRelation[] relations;
+ string mainDataTable;
+ string dataSetName;
+ string dataSetNamespace;
+ PropertyCollection dataSetProperties;
+ CultureInfo dataSetLocale;
ArrayList globalTypeTables = new ArrayList ();
Hashtable additionalNamespaces = new Hashtable ();
ArrayList annotation = new ArrayList ();
public string ConstraintPrefix {
- get { return ds.Namespace != String.Empty ? XmlConstants.TnsPrefix + ':' : String.Empty; }
+ get { return dataSetNamespace != String.Empty ? XmlConstants.TnsPrefix + ':' : String.Empty; }
}
// the whole DataSet
}
w.WriteStartElement ("xs", "schema", xmlnsxs);
- w.WriteAttributeString ("id", XmlHelper.Encode (ds.DataSetName));
+ w.WriteAttributeString ("id", XmlHelper.Encode (dataSetName));
- if (ds.Namespace != String.Empty) {
+ if (dataSetNamespace != String.Empty) {
w.WriteAttributeString ("targetNamespace",
- ds.Namespace);
+ dataSetNamespace);
w.WriteAttributeString (
"xmlns",
XmlConstants.TnsPrefix,
XmlConstants.XmlnsNS,
- ds.Namespace);
+ dataSetNamespace);
}
- w.WriteAttributeString ("xmlns", ds.Namespace);
+ w.WriteAttributeString ("xmlns", dataSetNamespace);
w.WriteAttributeString ("xmlns", "xs",
XmlConstants.XmlnsNS, xmlnsxs);
XmlConstants.XmlnsNS,
XmlConstants.MspropNamespace);
- if (ds.Namespace != String.Empty) {
+ if (dataSetNamespace != String.Empty) {
w.WriteAttributeString ("attributeFormDefault", "qualified");
w.WriteAttributeString ("elementFormDefault", "qualified");
}
private void WriteDataSetElement ()
{
w.WriteStartElement ("xs", "element", xmlnsxs);
- w.WriteAttributeString ("name", XmlHelper.Encode (ds.DataSetName));
+ w.WriteAttributeString ("name", XmlHelper.Encode (dataSetName));
w.WriteAttributeString (XmlConstants.MsdataPrefix,
"IsDataSet", XmlConstants.MsdataNamespace,
"true");
+
+ if(mainDataTable != null && mainDataTable != "")
+ w.WriteAttributeString (
+ XmlConstants.MsdataPrefix,
+ "MainDataTable",
+ XmlConstants.MsdataNamespace,
+ mainDataTable);
#if NET_2_0
- if (ds.Locale == CultureInfo.CurrentCulture) {
+ if (dataSetLocale == CultureInfo.CurrentCulture) {
w.WriteAttributeString (
XmlConstants.MsdataPrefix,
"UseCurrentCulture",
XmlConstants.MsdataPrefix,
"Locale",
XmlConstants.MsdataNamespace,
- ds.Locale.Name);
+ dataSetLocale.Name);
}
- AddExtendedPropertyAttributes (ds.ExtendedProperties);
+ AddExtendedPropertyAttributes (dataSetProperties);
w.WriteStartElement ("xs", "complexType", xmlnsxs);
w.WriteStartElement ("xs", "choice", xmlnsxs);
}
if (isTopLevel) {
- if (ds.Namespace != table.Namespace) {
+ if (dataSetNamespace != table.Namespace) {
// <xs:element ref="X:y" />
w.WriteStartElement ("xs",
"element",
}
ForeignKeyConstraint fk = c as ForeignKeyConstraint;
- if (fk != null && (relations == null || !(relations.Contains (fk.ConstraintName)))) {
+ bool haveConstraint = false;
+ if (relations != null)
+ foreach (DataRelation r in relations)
+ if(r.RelationName == fk.ConstraintName)
+ haveConstraint = true;
+ if (fk != null && !haveConstraint) {
DataRelation rel = new DataRelation (fk.ConstraintName,
fk.RelatedColumns, fk.Columns);
AddForeignKeys (rel, names, true);
// first try to find the concatenated name. If we didn't find it - use constraint name.
if (names.Contains (concatName)) {
w.WriteStartAttribute ("refer", String.Empty);
- w.WriteQualifiedName (concatName, ds.Namespace);
+ w.WriteQualifiedName (concatName, dataSetNamespace);
w.WriteEndAttribute ();
}
else {
w.WriteStartAttribute ("refer", String.Empty);
- w.WriteQualifiedName (XmlHelper.Encode (uqConst.ConstraintName), ds.Namespace);
+ w.WriteQualifiedName (XmlHelper.Encode (uqConst.ConstraintName), dataSetNamespace);
w.WriteEndAttribute ();
}
// ExtendedProperties
private bool CheckExtendedPropertyExists (
- DataTableCollection tables,
- DataRelationCollection relations)
+ DataTable[] tables,
+ DataRelation[] relations)
{
- if (ds.ExtendedProperties.Count > 0)
+ if (dataSetProperties.Count > 0)
return true;
foreach (DataTable dt in tables) {
if (dt.ExtendedProperties.Count > 0)
private void WriteChildRelations (DataRelation rel)
{
- if (rel.ChildTable.Namespace != ds.Namespace) {
+ if (rel.ChildTable.Namespace != dataSetNamespace) {
w.WriteStartElement ("xs", "element", xmlnsxs);
w.WriteStartAttribute ("ref", String.Empty);
w.WriteQualifiedName (
{
if (ns == String.Empty)
return;
- if (ds.Namespace != ns) {
- if (names [prefix] != ns) {
+ if (dataSetNamespace != ns) {
+ if ((string)names [prefix] != ns) {
for (int i = 1; i < int.MaxValue; i++) {
string p = "app" + i;
if (names [p] == null) {
--- /dev/null
+//
+// System.Data/XmlTableWriter.cs
+//
+// Author:
+// Patrick Earl <mono@patearl.net>
+//
+// Copyright (c) 2006, Patrick Earl
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#if NET_2_0
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Xml;
+
+internal class XmlTableWriter {
+ // This method is modelled after the DataSet's WriteXml functionality.
+ internal static void WriteTables(XmlWriter writer,
+ XmlWriteMode mode,
+ List<DataTable> tables,
+ List<DataRelation> relations,
+ string mainDataTable,
+ string dataSetName)
+ {
+ if (mode == XmlWriteMode.DiffGram) {
+ foreach (DataTable table in tables)
+ table.SetRowsID();
+ DataSet.WriteDiffGramElement(writer);
+ }
+
+ bool shouldOutputContent = (mode != XmlWriteMode.DiffGram);
+ for (int n = 0; n < tables.Count && !shouldOutputContent; n++)
+ shouldOutputContent = tables[n].Rows.Count > 0;
+
+ if (shouldOutputContent) {
+ // We assume that tables[0] is the main table being written.
+ // We happen to know that the code above us does things that way.
+ DataSet.WriteStartElement(writer, mode, tables[0].Namespace, tables[0].Prefix, XmlHelper.Encode(dataSetName));
+
+ if (mode == XmlWriteMode.WriteSchema) {
+ new XmlSchemaWriter(writer,
+ tables.ToArray(),
+ relations.ToArray(),
+ mainDataTable,
+ dataSetName
+ ).WriteSchema();
+ }
+
+ WriteTableList (writer, mode, tables, DataRowVersion.Default);
+
+ writer.WriteEndElement();
+ }
+
+ if (mode == XmlWriteMode.DiffGram) {
+ List<DataTable> changedTables = new List<DataTable>();
+ foreach (DataTable table in tables) {
+ DataTable changed = table.GetChanges(DataRowState.Modified | DataRowState.Deleted);
+ if (changed != null && changed.Rows.Count > 0)
+ changedTables.Add(changed);
+ }
+ if (changedTables.Count > 0) {
+ DataSet.WriteStartElement(writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "before");
+ WriteTableList (writer, mode, changedTables, DataRowVersion.Original);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement(); // diffgr:diffgram
+ }
+
+ writer.Flush();
+ }
+
+ internal static void WriteTableList(XmlWriter writer, XmlWriteMode mode, List<DataTable> tables, DataRowVersion version)
+ {
+ foreach (DataTable table in tables)
+ DataSet.WriteTable(writer, table, mode, version);
+ }
+}
+#endif