DataSet.cs : Adding support for WriteXml with diffgram. Code style changes.
authorEran Domb <eran@mono-cvs.ximian.com>
Tue, 6 Jan 2004 11:09:32 +0000 (11:09 -0000)
committerEran Domb <eran@mono-cvs.ximian.com>
Tue, 6 Jan 2004 11:09:32 +0000 (11:09 -0000)
XmlDataLoader.cs : Set the DataSet.enforceConstraints to false before loading the tables.
XmlDiffLoader.cs : Reading nested tables.
XmlSchemaMapper.cs : Reading the relation.
XmlConstants.cs : Adding some constants.

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

mcs/class/System.Data/System.Data/DataSet.cs
mcs/class/System.Data/System.Data/XmlConstants.cs
mcs/class/System.Data/System.Data/XmlDataLoader.cs
mcs/class/System.Data/System.Data/XmlDiffLoader.cs
mcs/class/System.Data/System.Data/XmlSchemaMapper.cs

index 756a4bafec2e7d3e417cc7bf8f2a168319c4afbc..57c7ad65114789ccfcb2c5420885d9b0242610f8 100644 (file)
@@ -31,7 +31,8 @@ namespace System.Data {
        [DefaultProperty ("DataSetName")]
        [Serializable]
        public class DataSet : MarshalByValueComponent, IListSource, 
-               ISupportInitialize, ISerializable, IXmlSerializable {
+               ISupportInitialize, ISerializable, IXmlSerializable 
+       {
                private string dataSetName;
                private string _namespace = "";
                private string prefix;
@@ -43,9 +44,10 @@ namespace System.Data {
                private DataViewManager defaultView;
                private CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
                
-#region Constructors
+               #region Constructors
 
-               public DataSet () : this ("NewDataSet") {               
+               public DataSet () : this ("NewDataSet") 
+               {               
                }
                
                public DataSet (string name)
@@ -60,7 +62,8 @@ namespace System.Data {
                }
 
                [MonoTODO]
-               protected DataSet (SerializationInfo info, StreamingContext context) : this () {
+               protected DataSet (SerializationInfo info, StreamingContext context) : this ()
+               {
                        throw new NotImplementedException ();
                }
 
@@ -138,8 +141,7 @@ namespace System.Data {
                public bool HasErrors {
                        [MonoTODO]
                        get {
-                               for (int i = 0; i < Tables.Count; i++)
-                               {
+                               for (int i = 0; i < Tables.Count; i++) {
                                        if (Tables[i].HasErrors)
                                                return true;
                                }
@@ -364,8 +366,7 @@ namespace System.Data {
                        //demands these values. instead changing the DataRelation constructor and behaviour the
                        //parameters are pre-configured and sent to the most general constructor
 
-                       foreach (DataRelation MyRelation in this.Relations)
-                       {
+                       foreach (DataRelation MyRelation in this.Relations) {
                                string pTable = MyRelation.ParentTable.TableName;
                                string cTable = MyRelation.ChildTable.TableName;
                                DataColumn[] P_DC = new DataColumn[MyRelation.ParentColumns.Length]; 
@@ -421,8 +422,7 @@ namespace System.Data {
                                IEnumerator rowEnumerator = origTable.Rows.GetEnumerator ();
                                while (rowEnumerator.MoveNext ()) {
                                        DataRow row = (DataRow)rowEnumerator.Current;
-                                       if (row.IsRowChanged (rowStates))
-                                       {
+                                       if (row.IsRowChanged (rowStates)) {
                                                DataRow newRow = copyTable.NewRow ();
                                                copyTable.Rows.Add (newRow);
                                                row.CopyValuesToRow (newRow);
@@ -618,14 +618,14 @@ namespace System.Data {
                        WriteXml (writer, mode, true);
                }
                
-               internal void WriteXml (Stream stream, XmlWriteMode mode, bool writePI)
+               public void WriteXml (Stream stream, XmlWriteMode mode, bool writePI)
                {
                        XmlWriter writer = new XmlTextWriter (stream, null);
                        
                        WriteXml (writer, mode, writePI);
                }
 
-               internal void WriteXml (string fileName, XmlWriteMode mode, bool writePI)
+               public void WriteXml (string fileName, XmlWriteMode mode, bool writePI)
                {
                        XmlWriter writer = new XmlTextWriter (fileName, null);
                        
@@ -634,47 +634,43 @@ namespace System.Data {
                        writer.Close ();
                }
 
-               internal void WriteXml (TextWriter writer, XmlWriteMode mode, bool writePI)
+               public void WriteXml (TextWriter writer, XmlWriteMode mode, bool writePI)
                {
                        XmlWriter xwriter = new XmlTextWriter (writer);
                        
                        WriteXml (xwriter, mode, writePI);
                }
 
-               internal void WriteXml (XmlWriter writer, XmlWriteMode mode, bool writePI)
+               public void WriteXml (XmlWriter writer, XmlWriteMode mode, bool writePI)
                {
                        if (writePI && (writer.WriteState == WriteState.Start))
                                writer.WriteStartDocument (true);
 
-                        ((XmlTextWriter)writer).Formatting = Formatting.Indented;
+                       ((XmlTextWriter)writer).Formatting = Formatting.Indented;
+
+                       if (mode == XmlWriteMode.DiffGram) {
+                               SetRowsID();
+                               WriteDiffGramElement(writer);
+                       }
+
                        WriteStartElement (writer, mode, Namespace, Prefix, XmlConvert.EncodeName (DataSetName));
                        
-                       if (mode == XmlWriteMode.WriteSchema)
-                       {
+                       if (mode == XmlWriteMode.WriteSchema) {
                                DoWriteXmlSchema (writer);
                        }
                        
-                       //Write out each table in order, providing it is not
-                       //part of another table structure via a nested parent relationship
-                       foreach (DataTable table in Tables)
-                       {
-                               bool isTopLevel = true;
-                               foreach (DataRelation rel in table.ParentRelations)
-                               {
-                                       if (rel.Nested)
-                                       {
-                                               isTopLevel = false;
-                                               break;
-                                       }
-                               }
-                               
-                               if (isTopLevel)
-                               {
-                                       WriteTable ( writer, table, mode);
+                       WriteTables (writer, mode, Tables, DataRowVersion.Default);
+                       if (mode == XmlWriteMode.DiffGram) {
+                               writer.WriteEndElement (); //DataSet name
+                               if (HasChanges(DataRowState.Modified | DataRowState.Deleted)) {
+
+                                       DataSet beforeDS = GetChanges (DataRowState.Modified | DataRowState.Deleted);   
+                                       WriteStartElement (writer, XmlWriteMode.DiffGram, Namespace, Prefix, "diffgr:before");
+                                       WriteTables (writer, mode, beforeDS.Tables, DataRowVersion.Original);
+                                       writer.WriteEndElement ();
                                }
                        }
-                       
-                       writer.WriteEndElement ();                      
+                       writer.WriteEndElement (); // DataSet name or diffgr:diffgram
                }
 
                public void WriteXmlSchema (Stream stream)
@@ -700,7 +696,7 @@ namespace System.Data {
 
                public void WriteXmlSchema (XmlWriter writer)
                {
-                        ((XmlTextWriter)writer).Formatting = Formatting.Indented;
+                       ((XmlTextWriter)writer).Formatting = Formatting.Indented;
                        //Create a skeleton doc and then write the schema 
                        //proper which is common to the WriteXml method in schema mode
                        writer.WriteStartDocument ();
@@ -765,7 +761,7 @@ namespace System.Data {
                        /*\
                         *  If we already have a schema, or the document 
                         *  contains an in-line schema, sets XmlReadMode to ReadSchema.
-                       \*/
+                       \*/
 
                        // FIXME: is this always true: "if we have tables we have to have schema also"
                        if (Tables.Count > 0)                           
@@ -801,6 +797,15 @@ namespace System.Data {
                        XmlReadMode Result = XmlReadMode.Auto;
 
                        if (mode == XmlReadMode.DiffGram) {
+                               if (reader.LocalName != "diffgram"){
+                                       reader.MoveToContent ();
+                                       reader.ReadStartElement ();     // <DataSet>
+
+                                       reader.MoveToContent ();
+                                       ReadXmlSchema (reader);
+
+                                       reader.MoveToContent ();
+                               }
                                XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
                                DiffLoader.Load (reader);
                                Result =  XmlReadMode.DiffGram;
@@ -881,14 +886,8 @@ namespace System.Data {
 
                void IXmlSerializable.ReadXml (XmlReader reader)
                {
-                       reader.MoveToContent ();
-                       reader.ReadStartElement ();     // <DataSet>
 
-                       reader.MoveToContent ();
-                       ReadXmlSchema (reader);
-
-                       reader.MoveToContent ();
-                       ReadXml (reader, XmlReadMode.IgnoreSchema);
+                       ReadXml (reader, XmlReadMode.DiffGram);
                        
                        // the XmlSerializationReader does this lines!!!
                        //reader.MoveToContent ();
@@ -898,7 +897,7 @@ namespace System.Data {
                void IXmlSerializable.WriteXml (XmlWriter writer)
                {
                        DoWriteXmlSchema (writer);
-                       WriteXml (writer, XmlWriteMode.IgnoreSchema, true);
+                       WriteXml (writer, XmlWriteMode.DiffGram, true);
                }
 
                protected virtual bool ShouldSerializeRelations ()
@@ -940,50 +939,70 @@ namespace System.Data {
 
                #region Private Xml Serialisation
 
-               private string WriteObjectXml (object o) {
+               private string WriteObjectXml (object o)
+               {
                        switch (Type.GetTypeCode (o.GetType ())) {
-                       case TypeCode.Boolean:
-                               return XmlConvert.ToString ((Boolean) o);
-                       case TypeCode.Byte:
-                               return XmlConvert.ToString ((Byte) o);
-                       case TypeCode.Char:
-                               return XmlConvert.ToString ((Char) o);
-                       case TypeCode.DateTime:
-                               return XmlConvert.ToString ((DateTime) o);
-                       case TypeCode.Decimal:
-                               return XmlConvert.ToString ((Decimal) o);
-                       case TypeCode.Double:
-                               return XmlConvert.ToString ((Double) o);
-                       case TypeCode.Int16:
-                               return XmlConvert.ToString ((Int16) o);
-                       case TypeCode.Int32:
-                               return XmlConvert.ToString ((Int32) o);
-                       case TypeCode.Int64:
-                               return XmlConvert.ToString ((Int64) o);
-                       case TypeCode.SByte:
-                               return XmlConvert.ToString ((SByte) o);
-                       case TypeCode.Single:
-                               return XmlConvert.ToString ((Single) o);
-                       case TypeCode.UInt16:
-                               return XmlConvert.ToString ((UInt16) o);
-                       case TypeCode.UInt32:
-                               return XmlConvert.ToString ((UInt32) o);
-                       case TypeCode.UInt64:
-                               return XmlConvert.ToString ((UInt64) o);
+                               case TypeCode.Boolean:
+                                       return XmlConvert.ToString ((Boolean) o);
+                               case TypeCode.Byte:
+                                       return XmlConvert.ToString ((Byte) o);
+                               case TypeCode.Char:
+                                       return XmlConvert.ToString ((Char) o);
+                               case TypeCode.DateTime:
+                                       return XmlConvert.ToString ((DateTime) o);
+                               case TypeCode.Decimal:
+                                       return XmlConvert.ToString ((Decimal) o);
+                               case TypeCode.Double:
+                                       return XmlConvert.ToString ((Double) o);
+                               case TypeCode.Int16:
+                                       return XmlConvert.ToString ((Int16) o);
+                               case TypeCode.Int32:
+                                       return XmlConvert.ToString ((Int32) o);
+                               case TypeCode.Int64:
+                                       return XmlConvert.ToString ((Int64) o);
+                               case TypeCode.SByte:
+                                       return XmlConvert.ToString ((SByte) o);
+                               case TypeCode.Single:
+                                       return XmlConvert.ToString ((Single) o);
+                               case TypeCode.UInt16:
+                                       return XmlConvert.ToString ((UInt16) o);
+                               case TypeCode.UInt32:
+                                       return XmlConvert.ToString ((UInt32) o);
+                               case TypeCode.UInt64:
+                                       return XmlConvert.ToString ((UInt64) o);
                        }
                        if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
                        if (o is Guid) return XmlConvert.ToString ((Guid) o);
                        return o.ToString ();
                }
-       
-               private void WriteTable (XmlWriter writer, DataTable table, XmlWriteMode mode)
+               
+               private void WriteTables (XmlWriter writer, XmlWriteMode mode, DataTableCollection tableCollection, DataRowVersion version)
+               {
+                       //Write out each table in order, providing it is not
+                       //part of another table structure via a nested parent relationship
+                       foreach (DataTable table in tableCollection) {
+                               bool isTopLevel = true;
+                               foreach (DataRelation rel in table.ParentRelations) {
+                                       if (rel.Nested) {
+                                               isTopLevel = false;
+                                               break;
+                                       }
+                               }
+                               
+                               if (isTopLevel) {
+                                       WriteTable ( writer, table, mode, version);
+                               }
+                       }
+               }
+
+               private void WriteTable (XmlWriter writer, DataTable table, XmlWriteMode mode, DataRowVersion version)
                {
                        DataRow[] rows = new DataRow [table.Rows.Count];
                        table.Rows.CopyTo (rows, 0);
-                       WriteTable (writer, rows, mode);
+                       WriteTable (writer, rows, mode, version);
                }
 
-               private void WriteTable (XmlWriter writer, DataRow[] rows, XmlWriteMode mode)
+               private void WriteTable (XmlWriter writer, DataRow[] rows, XmlWriteMode mode, DataRowVersion version)
                {
                        //The columns can be attributes, hidden, elements, or simple content
                        //There can be 0-1 simple content cols or 0-* elements
@@ -994,17 +1013,18 @@ namespace System.Data {
                        if (rows.Length == 0) return;
                        DataTable table = rows[0].Table;
                        SplitColumns (table, out atts, out elements, out simple);
+                       //sort out the namespacing
+                       string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
 
-                       foreach (DataRow row in rows)
-                       {
-                               //sort out the namespacing
-                               string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
-
+                       foreach (DataRow row in rows) {
+                               if (!row.HasVersion(version))
+                                       continue;
+                               
                                // First check are all the rows null. If they are we just write empty element
                                bool AllNulls = true;
                                foreach (DataColumn dc in table.Columns) {
                                
-                                       if (row [dc.ColumnName] != DBNull.Value) {
+                                       if (row [dc.ColumnName, version] != DBNull.Value) {
                                                AllNulls = false;
                                                break;
                                        } 
@@ -1015,43 +1035,25 @@ namespace System.Data {
                                        writer.WriteElementString (table.TableName, "");
                                        continue;
                                }
-
-                               WriteStartElement (writer, mode, nspc, table.Prefix, table.TableName);
                                
-                               foreach (DataColumn col in atts)
-                               {                                       
-                                       WriteAttributeString (writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col].ToString ());
-                               }
+                               WriteTableElement (writer, mode, table, row, version);
                                
-                               if (simple != null)
-                               {
-                                       writer.WriteString (WriteObjectXml (row[simple]));
+                               foreach (DataColumn col in atts) {                                      
+                                       WriteColumnAsAttribute (writer, mode, col, row, version);
                                }
-                               else
-                               {                                       
-                                       foreach (DataColumn col in elements)
-                                       {
-                                               string colnspc = nspc;
-                                               object rowObject = row [col];
-                                                                                               
-                                               if (rowObject == null || rowObject == DBNull.Value)
-                                                       continue;
-
-                                               if (col.Namespace != null)
-                                               {
-                                                       colnspc = col.Namespace;
-                                               }
                                
-                                               //TODO check if I can get away with write element string
-                                               WriteStartElement (writer, mode, colnspc, col.Prefix, col.ColumnName);
-                                               writer.WriteString (WriteObjectXml (rowObject));
-                                               writer.WriteEndElement ();
+                               if (simple != null) {
+                                       writer.WriteString (WriteObjectXml (row[simple, version]));
+                               }
+                               else {                                  
+                                       foreach (DataColumn col in elements) {
+                                               WriteColumnAsElement (writer, mode, nspc, col, row, version);
                                        }
                                }
                                
                                foreach (DataRelation relation in table.ChildRelations) {
                                        if (relation.Nested) {
-                                               WriteTable (writer, row.GetChildRows (relation), mode);
+                                               WriteTable (writer, row.GetChildRows (relation), mode, version);
                                        }
                                }
                                
@@ -1059,46 +1061,82 @@ namespace System.Data {
                        }
 
                }
+
+               private void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, string nspc, DataColumn col, DataRow row, DataRowVersion version)
+               {
+                       string colnspc = nspc;
+                       object rowObject = row [col, version];
+                                                                       
+                       if (rowObject == null || rowObject == DBNull.Value)
+                               return;
+
+                       if (col.Namespace != null) {
+                               colnspc = col.Namespace;
+                       }
+       
+                       //TODO check if I can get away with write element string
+                       WriteStartElement (writer, mode, colnspc, col.Prefix, col.ColumnName);
+                       writer.WriteString (WriteObjectXml (rowObject));
+                       writer.WriteEndElement ();
+               }
+
+               private void WriteColumnAsAttribute (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)
+               {
+                       WriteAttributeString (writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col, version].ToString ());
+               }
+
+               private void WriteTableElement (XmlWriter writer, XmlWriteMode mode, DataTable table, DataRow row, DataRowVersion version)
+               {
+                       //sort out the namespacing
+                       string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
+
+                       WriteStartElement (writer, mode, nspc, table.Prefix, table.TableName);
+
+                       if (mode == XmlWriteMode.DiffGram) {
+                               WriteAttributeString (writer, mode, "", "diffgr", "id", table.TableName + (row.XmlRowID + 1));
+                               WriteAttributeString (writer, mode, "", "msdata", "rowOrder", row.XmlRowID.ToString());
+                               if (row.RowState == DataRowState.Modified && version != DataRowVersion.Original){
+                                       WriteAttributeString (writer, mode, "", "diffgr", "hasChanges", "modified");
+                               }
+                       }
+               }
                    
                private void WriteStartElement (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name)
                {                       
-                       switch ( mode)
-                               {
-                                       case XmlWriteMode.WriteSchema:
-                                               if (nspc == null || nspc == "")
-                                               {
-                                                       writer.WriteStartElement (name);
-                                               }
-                                               else if (prefix != null)
-                                               {                                                       
-                                                       writer.WriteStartElement (prefix, name, nspc);
-                                               }                                               
-                                               else
-                                               {                                       
-                                                       writer.WriteStartElement (writer.LookupPrefix (nspc), name, nspc);
-                                               }
-                                               break;
-                                       case XmlWriteMode.DiffGram:
-                                               throw new NotImplementedException ();
-                                       default:                                               
+                       switch ( mode) {
+                               case XmlWriteMode.WriteSchema:
+                                       if (nspc == null || nspc == "") {
                                                writer.WriteStartElement (name);
-                                               break;                                  
-                               };
+                                       }
+                                       else if (prefix != null) {                                                      
+                                               writer.WriteStartElement (prefix, name, nspc);
+                                       }                                               
+                                       else {                                  
+                                               writer.WriteStartElement (writer.LookupPrefix (nspc), name, nspc);
+                                       }
+                                       break;
+                               case XmlWriteMode.DiffGram:
+                                       writer.WriteStartElement (name);
+                                       break;  
+                               default:                                               
+                                       writer.WriteStartElement (name);
+                                       break;                                  
+                       };
                }
                
                private void WriteAttributeString (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue)
                {
-                       switch ( mode)
-                               {
-                                       case XmlWriteMode.WriteSchema:
-                                               writer.WriteAttributeString (prefix, name, nspc);
-                                               break;
-                                       case XmlWriteMode.DiffGram:
-                                               throw new NotImplementedException ();                           
-                                       default:
-                                               writer.WriteAttributeString (name, stringValue);
-                                               break;                                  
-                               };
+                       switch ( mode) {
+                               case XmlWriteMode.WriteSchema:
+                                       writer.WriteAttributeString (prefix, name, nspc);
+                                       break;
+                               case XmlWriteMode.DiffGram:
+                                       writer.WriteAttributeString (prefix, name, nspc, stringValue);
+                                       break;
+                               default:
+                                       writer.WriteAttributeString (name, stringValue);
+                                       break;                                  
+                       };
                }
 
                XmlSchema IXmlSerializable.GetSchema ()
@@ -1246,11 +1284,9 @@ namespace System.Data {
                        elem.SchemaType = complex;
 
                        //TODO - what about the simple content?
-                       if (elements.Count == 0) 
-                       {                               
+                       if (elements.Count == 0) {                              
                        }
-                       else 
-                       {
+                       else {
                                //A sequence of element types or a simple content node
                                //<xs:sequence>
                                XmlSchemaSequence seq = new XmlSchemaSequence ();
@@ -1306,6 +1342,7 @@ namespace System.Data {
                                att.SchemaTypeName = MapType (col.DataType);
                                complex.Attributes.Add (att);
                        }
+
                        return elem;
                }
 
@@ -1336,9 +1373,9 @@ namespace System.Data {
                /// content
                /// </summary>
                private void SplitColumns (DataTable table, 
-                                          out ArrayList atts, 
-                                          out ArrayList elements, 
-                                          out DataColumn simple)
+                       out ArrayList atts, 
+                       out ArrayList elements, 
+                       out DataColumn simple)
                {
                        //The columns can be attributes, hidden, elements, or simple content
                        //There can be 0-1 simple content cols or 0-* elements
@@ -1348,8 +1385,7 @@ namespace System.Data {
                        
                        //Sort out the columns
                        foreach (DataColumn col in table.Columns) {
-                               switch (col.ColumnMapping)
-                               {
+                               switch (col.ColumnMapping) {
                                        case MappingType.Attribute:
                                                atts.Add (col);
                                                break;
@@ -1357,8 +1393,7 @@ namespace System.Data {
                                                elements.Add (col);
                                                break;
                                        case MappingType.SimpleContent:
-                                               if (simple != null)
-                                               {
+                                               if (simple != null) {
                                                        throw new System.InvalidOperationException ("There may only be one simple content element");
                                                }
                                                simple = col;
@@ -1369,11 +1404,29 @@ namespace System.Data {
                                }
                        }
                }
+
+               private void WriteDiffGramElement(XmlWriter writer)
+               {
+                       WriteStartElement (writer, XmlWriteMode.DiffGram, Namespace, Prefix, "diffgr:diffgram");
+                       WriteAttributeString(writer, XmlWriteMode.DiffGram, null, "xmlns", XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);
+                       WriteAttributeString(writer, XmlWriteMode.DiffGram, null, "xmlns", XmlConstants.DiffgrPrefix, XmlConstants.DiffgrNamespace);
+               }
+
+               private void SetRowsID()
+               {
+                       foreach (DataTable Table in Tables) {
+                               int dataRowID = 0;
+                               foreach (DataRow Row in Table.Rows) {
+                                       Row.XmlRowID = dataRowID;
+                                       dataRowID++;
+                               }
+                       }
+               }
+
                
                private XmlQualifiedName MapType (Type type)
                {
-                       switch (Type.GetTypeCode (type))
-                       {
+                       switch (Type.GetTypeCode (type)) {
                                case TypeCode.String: return XmlConstants.QnString;
                                case TypeCode.Int16: return XmlConstants.QnShort;
                                case TypeCode.Int32: return XmlConstants.QnInt;
index 52dc134410d25568aedbf0da3f9950baaf34a9e1..91976e7a4f33fb9bb997dc4acce8459e071e1ec8 100755 (executable)
@@ -57,6 +57,8 @@ internal class XmlConstants
        //ms schema objects     
        public const string MsdataPrefix = "msdata";    
        public const string MsdataNamespace = "urn:schemas-microsoft-com:xml-msdata";
+       public const string DiffgrPrefix = "diffgr";
+       public const string DiffgrNamespace = "urn:schemas-microsoft-com:xml-diffgram-v1";
        public const string TnsPrefix = "mstns";
        public const string IsDataSet = "IsDataSet";
        public const string Locale = "Locale";
index dd2ca2cbbc3e64337955799a286ac4b9ef75ea0d..543318c3253da5340b02a9e3da9f7a65c489383f 100644 (file)
@@ -22,7 +22,7 @@ using System.Xml.XPath;
 using System.Collections;
 using System.Globalization;
 
-namespace System.Data \r
+namespace System.Data 
 {
 
        internal class XmlDataLoader
@@ -40,7 +40,7 @@ namespace System.Data
                {
                        XmlReadMode Result = XmlReadMode.Auto;
 
-                       switch (mode) \r
+                       switch (mode) 
                        {
 
                                case XmlReadMode.Fragment:
@@ -71,7 +71,7 @@ namespace System.Data
                private void ReadModeInferSchema (XmlReader reader)
                {
                        // first load an XmlDocument from the reader.
-                       XmlDocument doc = new XmlDocument();
+                       XmlDocument doc = buildXmlDocument(reader);
                        doc.Load(reader);
 
                        // set EnforceConstraint to false - we do not want any validation during 
@@ -107,24 +107,28 @@ namespace System.Data
                         *  Reads any inline schema, but an exception is thrown 
                         *  if any tables in the inline schema already exist in the DataSet.
                        \*/
+                       // set EnforceConstraint to false - we do not want any validation during 
+                       // load time.
+                       bool origEnforceConstraint = DSet.EnforceConstraints;
+                       DSet.EnforceConstraints = false;
 
                        reader.MoveToContent ();
                        reader.ReadStartElement ();
                        reader.MoveToContent ();
 
-                       while (reader.NodeType != XmlNodeType.EndElement) \r
+                       while (reader.NodeType != XmlNodeType.EndElement) 
                        {
-                               if (reader.NodeType == XmlNodeType.Element)\r
+                               if (reader.NodeType == XmlNodeType.Element)
                                {
                                        // FIXME: possible inline-schema should be readed here
-                                       if (String.Compare (reader.LocalName, "schema", true) == 0) \r
+                                       if (String.Compare (reader.LocalName, "schema", true) == 0) 
                                        {
                                                if (!IgnoreSchema)
                                                        DSet.ReadXmlSchema (reader);
                                        }
 
                                        // find table
-                                       if (DSet.Tables.Contains (reader.LocalName)) \r
+                                       if (DSet.Tables.Contains (reader.LocalName)) 
                                        {
                                                DataTable table = DSet.Tables [reader.LocalName];
                                                DataRow row = table.NewRow ();
@@ -138,6 +142,8 @@ namespace System.Data
                                }
                                reader.MoveToContent ();
                        }
+                       // set the EnforceConstraints to original value;
+                       DSet.EnforceConstraints = origEnforceConstraint;
                }
 
                #endregion // reading
@@ -146,18 +152,18 @@ namespace System.Data
                
                private void ReadColumns (XmlReader reader, DataRow row, DataTable table, string TableName)
                {
-                       do \r
+                       do 
                        {
-                               if (reader.NodeType == XmlNodeType.Element) \r
+                               if (reader.NodeType == XmlNodeType.Element) 
                                {
                                        DataColumn col = table.Columns [reader.LocalName];
-                                       if (col != null) \r
+                                       if (col != null) 
                                        {
                                                reader.Read ();
                                                row [col] = StringToObject (col.DataType, reader.Value);
                                        }
                                }
-                               else \r
+                               else 
                                {
                                        reader.Read ();
                                }
@@ -170,7 +176,7 @@ namespace System.Data
                {
                        if (type == null) return value;
 
-                       switch (Type.GetTypeCode (type))\r
+                       switch (Type.GetTypeCode (type))
                        {
                                case TypeCode.Boolean: return XmlConvert.ToBoolean (value);
                                case TypeCode.Byte: return XmlConvert.ToByte (value);
@@ -186,10 +192,10 @@ namespace System.Data
                                case TypeCode.UInt16: return XmlConvert.ToUInt16 (value);
                                case TypeCode.UInt32: return XmlConvert.ToUInt32 (value);
                                case TypeCode.UInt64: return XmlConvert.ToUInt64 (value);
-                       }\r
-\r
-                       if (type == typeof (TimeSpan)) return XmlConvert.ToTimeSpan (value);\r
-                       if (type == typeof (byte[])) return Convert.FromBase64String (value);\r
+                       }
+
+                       if (type == typeof (TimeSpan)) return XmlConvert.ToTimeSpan (value);
+                       if (type == typeof (byte[])) return Convert.FromBase64String (value);
 
                        return Convert.ChangeType (value, type);
                }
@@ -279,7 +285,7 @@ namespace System.Data
                        DataRow row = table.NewRow ();
                                        
                        IDictionaryEnumerator enumerator = rowValue.GetEnumerator ();
-                       while (enumerator.MoveNext ()) \r
+                       while (enumerator.MoveNext ()) 
                        {
                                row [enumerator.Key.ToString ()] = enumerator.Value.ToString ();
                        }
@@ -290,6 +296,23 @@ namespace System.Data
 
                #endregion // Private helper methods
 
+               internal static XmlDocument buildXmlDocument(XmlReader reader)
+               {
+                       string endinglocalName = reader.LocalName;
+
+                       XmlDocument doc = new XmlDocument();
+
+                       // create all contents with use of ReadNode()
+                       do 
+                       {
+                               XmlNode n = doc.ReadNode (reader);
+                               if(n == null) break;
+                               doc.AppendChild (n);
+                       } while (reader.LocalName == endinglocalName);
+
+                       return doc;
+               }
+
                
        }
 
index dc25262b65ed5813fd968536117ea2cc764920a8..76ed679defd1230bc212d93efebc3529023d3cf4 100644 (file)
@@ -21,12 +21,12 @@ using System.Globalization;
 
 namespace System.Data {
 
-        internal class XmlDiffLoader
+       internal class XmlDiffLoader 
        {
 
-               #region Fields
-
-               private DataSet DSet;
+               #region Fields
+               enum LoadType {CURRENT, BEFORE, ERROR};
+               private DataSet DSet;
                private Hashtable DiffGrRows = new Hashtable ();
                private Hashtable ErrorRows = new Hashtable ();
 
@@ -34,7 +34,7 @@ namespace System.Data {
 
                #region ctors
 
-               public XmlDiffLoader (DataSet DSet)
+               public XmlDiffLoader (DataSet DSet) 
                {
                        this.DSet = DSet;
                }
@@ -43,24 +43,25 @@ namespace System.Data {
 
                #region Public methods
 
-               public void Load (XmlReader Reader)
+               public void Load (XmlReader Reader) 
                {
-                       XmlTextReader TextReader = new XmlTextReader (Reader.BaseURI);
-                       XmlDocument Document = new XmlDocument ();
-                       Document.Load (TextReader);
-                       TextReader.Close ();
 
+                       XmlDocument Document = XmlDataLoader.buildXmlDocument(Reader);
+                       
                        XPathNavigator Navigator = Document.CreateNavigator ();
+                       bool origEnforceConstraint = DSet.EnforceConstraints;
+                       DSet.EnforceConstraints = false;
                        LoadBefore (Navigator);
                        LoadCurrent (Navigator);
                        LoadErrors (Navigator);
+                       DSet.EnforceConstraints = origEnforceConstraint;
                }
 
                #endregion // Public methods
 
                #region Private methods
 
-               private void LoadCurrent (XPathNavigator Navigator)
+               private void LoadCurrent (XPathNavigator Navigator) 
                {                       
                        Navigator.MoveToRoot ();
 
@@ -71,51 +72,19 @@ namespace System.Data {
                                        if (Navigator.MoveToFirstChild ()) {
 
                                                if (Navigator.MoveToFirstChild ()) {
-
-                                                       if (DSet.Tables.Contains (Navigator.LocalName)) {
-
-                                                               DataTable Table = DSet.Tables [Navigator.LocalName];
-                                                               DataRow Row = null;
-                                                               bool NewRow = false;
-                                                               bool HasErrors = false;
-                                                               string id = "";
-                                                               
-                                                               if (Navigator.MoveToFirstAttribute ()) {
-                                                                       
-                                                                       do {
-                                                                               // Find out was there same row in 'before' section
-                                                                               if (Navigator.LocalName == "id") {
-                                                                                       id = Navigator.Value;
-                                                                                       if (DiffGrRows.Contains (id))
-                                                                                               Row = (DataRow)DiffGrRows [id];
-
-                                                                               }
-                                                                               else if (Navigator.LocalName == "hasErrors" && String.Compare (Navigator.Value, "true", true) == 0)
-                                                                                  HasErrors = true;
-                                                                       } while (Navigator.MoveToNextAttribute ());
-
-                                                                       // back to business
-                                                                       Navigator.MoveToParent ();
-                                                               }
-
-                                                               if (Row == null) {
-                                                                       
-                                                                       Row = Table.NewRow ();
-                                                                       NewRow = true;
-                                                               }
-                                                                                                                               
-                                                               LoadColumns (Table, Row, Navigator, NewRow);
-
-                                                               if (HasErrors) // If row had errors add row to hashtable for later use
-                                                                       ErrorRows.Add (id, Row);
-                                                       }
+                                                       do {
+                                                               if (DSet.Tables.Contains (Navigator.LocalName))
+                                                                       LoadCurrentTable(Navigator);
+                                                               else 
+                                                                       throw new DataException (Locale.GetText ("Cannot load diffGram. Table '" + Navigator.LocalName + "' is missing in the destination dataset"));   
+                                                       }while (Navigator.MoveToNext());
                                                }
                                        }
                                }
                        }
                }
 
-               private void LoadBefore (XPathNavigator Navigator)
+               private void LoadBefore (XPathNavigator Navigator) 
                {
                        Navigator.MoveToRoot ();
 
@@ -136,37 +105,17 @@ namespace System.Data {
                                if (Navigator.MoveToFirstChild ()) {
 
                                        do {
-                                               if (DSet.Tables.Contains (Navigator.LocalName)) {
-
-                                                       String id = null;
-                                                       DataTable Table = DSet.Tables [Navigator.LocalName];
-                                                       DataRow Row = Table.NewRow ();
-                                                       
-                                                       if (Navigator.MoveToFirstAttribute ()) {
-                                                               
-                                                               do {
-                                                                       if (Navigator.Name == "diffgr:id")
-                                                                               id = Navigator.Value;
-                                                                      
-                                                               } while (Navigator.MoveToNextAttribute ());
-                                                               
-                                                               Navigator.MoveToParent ();
-                                                       }
-                                                                                                               
-                                                       LoadColumns (Table, Row, Navigator, true);
-                                                       DiffGrRows.Add (id, Row); // for later use
-                                                       Row.AcceptChanges ();
-                                               } 
-                                               else {
+                                               if (DSet.Tables.Contains (Navigator.LocalName))
+                                                       LoadBeforeTable(Navigator);
+                                               else
                                                        throw new DataException (Locale.GetText ("Cannot load diffGram. Table '" + Navigator.LocalName + "' is missing in the destination dataset"));
-                                               }
                                        } while (Navigator.MoveToNext ());
                                }
                        }
                }                                
                                
                                           
-               private void LoadErrors (XPathNavigator Navigator)
+               private void LoadErrors (XPathNavigator Navigator) 
                {
                        Navigator.MoveToRoot ();
 
@@ -225,13 +174,19 @@ namespace System.Data {
                        }
                }
 
-               private void LoadColumns (DataTable Table, DataRow Row, XPathNavigator Navigator, bool NewRow)
+               private void LoadColumns (DataTable Table, DataRow Row, XPathNavigator Navigator, bool NewRow, LoadType loadType) 
                {
                        if (Navigator.MoveToFirstChild ()) {
 
                                do {
                                        if (Table.Columns.Contains (Navigator.LocalName))
                                                Row [Navigator.LocalName] = Navigator.Value;
+                                       else if (DSet.Tables.Contains (Navigator.LocalName)){
+                                               if (loadType == LoadType.BEFORE)
+                                                       LoadBeforeTable(Navigator);
+                                               else if (loadType == LoadType.CURRENT)
+                                                       LoadCurrentTable(Navigator);
+                                       }
                                                                                
                                } while (Navigator.MoveToNext ());
                                
@@ -240,6 +195,71 @@ namespace System.Data {
                        }
                }
 
+               private void LoadBeforeTable (XPathNavigator Navigator) 
+               {
+                               
+                       String id = null;
+                       DataTable Table = DSet.Tables [Navigator.LocalName];
+                       DataRow Row = Table.NewRow ();
+                                                       
+                       if (Navigator.MoveToFirstAttribute ()) {
+                                                               
+                               do {
+                                       if (Navigator.Name == "diffgr:id")
+                                               id = Navigator.Value;
+                                                                      
+                               } while (Navigator.MoveToNextAttribute ());
+                                                               
+                               Navigator.MoveToParent ();
+                       }
+                                                                                                               
+                       LoadColumns (Table, Row, Navigator, true, LoadType.BEFORE);
+                       DiffGrRows.Add (id, Row); // for later use
+                       Row.AcceptChanges ();
+               }
+
+               private void LoadCurrentTable (XPathNavigator Navigator) 
+               {
+                       
+                       DataTable Table = DSet.Tables [Navigator.LocalName];
+                       DataRow Row = null;
+                       bool NewRow = false;
+                       bool HasErrors = false;
+                       string id = "";
+                                                               
+                       if (Navigator.MoveToFirstAttribute ()) {
+                                                                       
+                               do {
+                                       // Find out was there same row in 'before' section
+                                       if (Navigator.LocalName == "id") {
+                                               id = Navigator.Value;
+                                               if (DiffGrRows.Contains (id))
+                                                       Row = (DataRow)DiffGrRows [id];
+
+                                       }
+                                       else if (Navigator.LocalName == "hasErrors" && String.Compare (Navigator.Value, "true", true) == 0)
+                                               HasErrors = true;
+                               } while (Navigator.MoveToNextAttribute ());
+
+                               // back to business
+                               Navigator.MoveToParent ();
+                       }
+
+                       if (Row == null) {
+                               Row = Table.NewRow ();
+                               NewRow = true;
+                       }
+                                                                                                                               
+                       LoadColumns (Table, Row, Navigator, NewRow, LoadType.CURRENT);
+                                                                       
+                       // back to business
+                       Navigator.MoveToParent();
+                                                                       
+                       if (HasErrors) // If row had errors add row to hashtable for later use
+                               ErrorRows.Add (id, Row);
+               
+               }
+
 
                #endregion // Private methods
        }
index c42c8f6bc3feb7658667775c1b50a89054adb326..2119c2f38f23475706e0f987144da141a842ff79 100644 (file)
@@ -12,7 +12,6 @@
 //
 // (C) 2002 Ville Palo
 //
-// TODO: Relations
 //
 
 using System;
@@ -77,10 +76,15 @@ namespace System.Data {
                private void ReadXmlSchemaSequence (XmlSchemaSequence Sequence, DataTable Table)
                {
                        foreach (XmlSchemaObject TempObj in Sequence.Items) {
-                               
-                               if (TempObj is XmlSchemaElement)
-                                       ReadXmlSchemaElement (TempObj as XmlSchemaElement, ElementType.ELEMENT_COLUMN, Table);
-                               
+                               if (TempObj is XmlSchemaElement){
+                                       XmlSchemaElement schemaElement = (XmlSchemaElement)TempObj;
+                                       // the element can be a Column or a Table
+                                       // tables do not have a type.
+                                       if (schemaElement.SchemaTypeName.Name.Length == 0) 
+                                               ReadXmlSchemaElement (schemaElement, ElementType.ELEMENT_TABLE, Table);
+                                       else
+                                               ReadXmlSchemaElement (schemaElement, ElementType.ELEMENT_COLUMN, Table);
+                               }
                        }
                }
 
@@ -137,9 +141,12 @@ namespace System.Data {
                                        ReadXmlSchemaElement ((XmlSchemaElement)ElementCollection [Element.RefName.Name], ElementType.ELEMENT_TABLE);
                        }
                        else if (ElementType.ELEMENT_UNDEFINED != ElType) {
-
-                               if (ElType == ElementType.ELEMENT_TABLE)
+                               
+                               if (ElType == ElementType.ELEMENT_TABLE){
                                        ReadTable (Element);
+                                       // we have tp return else all child element of the tabel will be computed again.
+                                       return;
+                               }
                                else if (ElType == ElementType.ELEMENT_COLUMN && Table != null)
                                        ReadColumn (Element, Table);
                        }
@@ -153,8 +160,9 @@ namespace System.Data {
                                ReadXmlSchemaType (Element.SchemaType);
 
                        // Read possible constraints
-                       if (Element.Constraints != null && Element.Constraints.Count > 0)
+                       if (Element.Constraints != null && Element.Constraints.Count > 0){
                                ReadXmlSchemaConstraints (Element.Constraints);
+                       }
                }
 
                private void ReadTable (XmlSchemaElement Element)
@@ -223,9 +231,10 @@ namespace System.Data {
                private void ReadXmlSchemaConstraints (XmlSchemaObjectCollection Constraints)
                {
                        foreach (XmlSchemaObject Constraint in Constraints) {
-                               
                                if (Constraint is XmlSchemaUnique)
                                        ReadXmlSchemaUnique ((XmlSchemaUnique)Constraint);
+                               if (Constraint is XmlSchemaKeyref)
+                                       ReadXmlSchemaKeyref ((XmlSchemaKeyref)Constraint, Constraints);
                        }
                }
 
@@ -233,19 +242,15 @@ namespace System.Data {
                private void ReadXmlSchemaUnique (XmlSchemaUnique Unique)
                {
                        // FIXME: Parsing XPath
-                       
                        string TableName = Unique.Selector.XPath;
                        if (TableName.StartsWith (".//"))
                                TableName = TableName.Substring (3);
-                       
                        DataColumn [] Columns;
                        if (DSet.Tables.Contains (TableName)) {
-                               
                                DataTable Table = DSet.Tables [TableName];
                                Columns = new DataColumn [Unique.Fields.Count];
                                int i = 0;
                                foreach (XmlSchemaXPath Field in Unique.Fields) {
-
                                        if (Table.Columns.Contains (Field.XPath)) {
                                                Table.Columns [Field.XPath].Unique = true;
                                                Columns [i] = Table.Columns [Field.XPath];
@@ -253,10 +258,93 @@ namespace System.Data {
                                        }
                                }
 
-                               UniqueConstraint Constraint = new UniqueConstraint (Unique.Name, Columns);
+                               // find if there is an attribute with the constraint name
+                               // if not use the XmlSchemaUnique name.
+                               string constraintName = Unique.Name;
+                               if (Unique.UnhandledAttributes != null){
+                                       foreach (XmlAttribute attr in Unique.UnhandledAttributes){
+                                               if (attr.LocalName == "ConstraintName"){
+                                                       constraintName = attr.Value;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               UniqueConstraint Constraint = new UniqueConstraint (constraintName, Columns);
+                       }
+               }
+
+               [MonoTODO()]
+               private void ReadXmlSchemaKeyref (XmlSchemaKeyref KeyRef, XmlSchemaObjectCollection collection) {
+                       
+                       string TableName = KeyRef.Selector.XPath;
+                       if (TableName.StartsWith (".//"))
+                               TableName = TableName.Substring (3);
+                       DataColumn [] Columns;
+                       if (DSet.Tables.Contains (TableName)) {
+                               DataTable Table = DSet.Tables [TableName];
+                               Columns = new DataColumn [KeyRef.Fields.Count];
+                               int i = 0;
+                               foreach (XmlSchemaXPath Field in KeyRef.Fields) {
+                                       if (Table.Columns.Contains (Field.XPath)) {
+                                               Columns [i] = Table.Columns [Field.XPath];
+                                               i++;
+                                       }
+                               }
+                               string name = KeyRef.Refer.Name;
+                               // get the unique constraint for the releation
+                               UniqueConstraint constraint = GetDSConstraint(name, collection);
+                               DataRelation relation = new DataRelation(KeyRef.Name, constraint.Columns, Columns);
+                               if (KeyRef.UnhandledAttributes != null){
+                                       foreach (XmlAttribute attr in KeyRef.UnhandledAttributes){
+                                               if (attr.LocalName == "IsNested"){
+                                                       if (attr.Value == "true")
+                                                               relation.Nested = true;
+                                               }
+                                       }
+                               }
+
+                               DSet.Relations.Add(relation);
+                       }
+               }
+               
+               // get the unique constraint for the relation.
+               // name - the name of the XmlSchemaUnique element
+               private UniqueConstraint GetDSConstraint(string name, XmlSchemaObjectCollection collection)
+               {
+                       // find the element in the constraint collection.
+                       foreach (XmlSchemaObject shemaObj in collection){
+                               if (shemaObj is XmlSchemaUnique){
+                                       XmlSchemaUnique unique = (XmlSchemaUnique) shemaObj;
+                                       if (unique.Name == name){
+                                               string tableName = unique.Selector.XPath;
+                                               if (tableName.StartsWith (".//"))
+                                                       tableName = tableName.Substring (3);
+                                               
+                                               // find the table in the dataset.
+                                               if (DSet.Tables.Contains(tableName)){
+                                                       DataTable table = DSet.Tables[tableName];
+                                                       string constraintName = unique.Name;
+                                                       // find if there is an attribute with the constraint name
+                                                       // if not use the XmlSchemaUnique name.
+                                                       if (unique.UnhandledAttributes != null){
+                                                               foreach (XmlAttribute attr in unique.UnhandledAttributes){
+                                                                       if (attr.LocalName == "ConstraintName"){
+                                                                               constraintName = attr.Value;
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                                       if (table.Constraints.Contains(constraintName))
+                                                               return (UniqueConstraint)table.Constraints[constraintName];
+                                               }
+
+                                       }
+                               }
                        }
+                       return null;
                }
 
+
                #endregion // Private methods
 
                #region Private listeners