2006-10-18 Nagappan A <anagappan@novell.com>
authorNagappan Alagappan <nagappan@gmail.com>
Fri, 20 Oct 2006 15:14:29 +0000 (15:14 -0000)
committerNagappan Alagappan <nagappan@gmail.com>
Fri, 20 Oct 2006 15:14:29 +0000 (15:14 -0000)
* ForeignKeyConstraint.cs (_validateColumns): Parent and child
columns can't be the same column - Exception, bug # 79689

2006-10-06  Patrick Earl <mono@patearl.net>

* DataTable.cs, XmlTableWriter.cs, XmlSchemaWriter.cs, DataSet.cs:
Implemented DataTable.WriteXml

svn path=/trunk/mcs/; revision=66830

mcs/class/System.Data/System.Data/ChangeLog
mcs/class/System.Data/System.Data/DataSet.cs
mcs/class/System.Data/System.Data/DataTable.cs
mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs
mcs/class/System.Data/System.Data/XmlSchemaWriter.cs
mcs/class/System.Data/System.Data/XmlTableWriter.cs [new file with mode: 0644]

index f3e2623d230b96f01756f6da6e815225e4846b50..cfa3fd738517e5b19ce4f58075c2459c982b6ceb 100644 (file)
@@ -1,3 +1,8 @@
+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
@@ -7,6 +12,11 @@
        #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,
index 4679c0f87cca2134ae5725840be83177dcd390a7..f01dda5aec2a0aef72bc7a5d9eec5351a04874bd 100644 (file)
@@ -45,7 +45,9 @@ using System.Globalization;
 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
@@ -1538,29 +1540,33 @@ namespace System.Data {
                                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
@@ -1628,7 +1634,7 @@ namespace System.Data {
 \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
@@ -1645,16 +1651,16 @@ namespace System.Data {
                        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
@@ -1672,12 +1678,12 @@ namespace System.Data {
                        }\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
@@ -1695,7 +1701,7 @@ namespace System.Data {
                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
@@ -1760,7 +1766,7 @@ namespace System.Data {
                        }\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
@@ -1768,18 +1774,10 @@ namespace System.Data {
 \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
index 4060ddd988d09c6cf257f29a82a7aa07cd370a2c..423b110099231115fc800968c18bd5b7453d2606 100644 (file)
@@ -43,6 +43,9 @@
 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
@@ -1920,10 +1923,49 @@ namespace System.Data {
                }\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
@@ -2235,57 +2277,158 @@ namespace System.Data {
                {\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
@@ -2572,5 +2715,14 @@ namespace System.Data {
                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
index 0e2dede6246ef7777d111902bc3dfff1016b885f..a01e55ce5bb487c6079a2eb8b754edae656657c3 100644 (file)
@@ -248,14 +248,16 @@ namespace System.Data {
                        }       
 
 
+                       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
@@ -264,6 +266,8 @@ namespace System.Data {
                                                + " column.");
                                }
                        }
+                       if (identicalCols == parentColumns.Length)
+                               throw new InvalidOperationException ("Property not accessible because 'ParentKey and ChildKey are identical.'.");
                        
                }
                
index 6b4a3cd6a655bd4ef235fdf1694fa22d9ed49b0e..ee67b434bed544ba6ffec14279ce8f71cdf31782 100644 (file)
@@ -64,16 +64,50 @@ namespace System.Data
                        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 ();
@@ -81,7 +115,7 @@ namespace System.Data
                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
@@ -99,18 +133,18 @@ namespace System.Data
                        }
 
                        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);
@@ -125,7 +159,7 @@ namespace System.Data
                                        XmlConstants.XmlnsNS,
                                        XmlConstants.MspropNamespace);
 
-                       if (ds.Namespace != String.Empty) {
+                       if (dataSetNamespace != String.Empty) {
                                w.WriteAttributeString ("attributeFormDefault", "qualified");
                                w.WriteAttributeString ("elementFormDefault", "qualified");
                        }
@@ -156,12 +190,19 @@ namespace System.Data
                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",
@@ -175,10 +216,10 @@ namespace System.Data
                                        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);
@@ -194,7 +235,7 @@ namespace System.Data
                                }
                                
                                if (isTopLevel) {
-                                       if (ds.Namespace != table.Namespace) {
+                                       if (dataSetNamespace != table.Namespace) {
                                                // <xs:element ref="X:y" />
                                                w.WriteStartElement ("xs",
                                                        "element",
@@ -286,7 +327,12 @@ namespace System.Data
                                        }
 
                                        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);
@@ -399,12 +445,12 @@ namespace System.Data
                        // 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 ();
                        }
 
@@ -445,10 +491,10 @@ namespace System.Data
                // 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)
@@ -640,7 +686,7 @@ namespace System.Data
 
                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 (
@@ -734,8 +780,8 @@ namespace System.Data
                {
                        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) {
diff --git a/mcs/class/System.Data/System.Data/XmlTableWriter.cs b/mcs/class/System.Data/System.Data/XmlTableWriter.cs
new file mode 100644 (file)
index 0000000..ab9902f
--- /dev/null
@@ -0,0 +1,97 @@
+// 
+// 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