New tests, updates
[mono.git] / mcs / class / System.Data / System.Data / XmlSchemaDataImporter.cs
index 15bd538b1adc82bc08e4be30625c6be080b6ed5e..24950a7497ab22bd638c17c0d0fd20c4c5a02f50 100644 (file)
@@ -290,14 +290,21 @@ namespace System.Data
                        e.Name = "bar";
                        s.Items.Add (e);
                        s.Compile (null);
+#if NET_2_0
+                       schemaIntegerType = ((XmlSchemaSimpleType) a.AttributeSchemaType).Datatype;
+                       schemaDecimalType = ((XmlSchemaSimpleType) b.AttributeSchemaType).Datatype;
+                       schemaAnyType = e.ElementSchemaType as XmlSchemaComplexType;
+#else
                        schemaIntegerType = a.AttributeType as XmlSchemaDatatype;
                        schemaDecimalType = b.AttributeType as XmlSchemaDatatype;
                        schemaAnyType = e.ElementType as XmlSchemaComplexType;
+#endif
                }
 
                #region Fields
 
                DataSet dataset;
+               bool forDataSet;
                XmlSchema schema;
 
                ArrayList relations = new ArrayList ();
@@ -318,9 +325,10 @@ namespace System.Data
 
                // .ctor()
 
-               public XmlSchemaDataImporter (DataSet dataset, XmlReader reader)
+               public XmlSchemaDataImporter (DataSet dataset, XmlReader reader, bool forDataSet)
                {
                        this.dataset = dataset;
+                       this.forDataSet = forDataSet;
                        dataset.DataSetName = "NewDataSet"; // Initialize always
                        schema = XmlSchema.Read (reader, null);
                        if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace)
@@ -343,8 +351,13 @@ namespace System.Data
                                        if (datasetElement == null &&
                                                IsDataSetElement (el))
                                                datasetElement = el;
+#if NET_2_0
+                                       if (el.ElementSchemaType is XmlSchemaComplexType &&
+                                           el.ElementSchemaType != schemaAnyType)
+#else
                                        if (el.ElementType is XmlSchemaComplexType &&
-el.ElementType != schemaAnyType)
+                                           el.ElementType != schemaAnyType)
+#endif
                                                targetElements.Add (obj);
                                }
                        }
@@ -364,8 +377,13 @@ el.ElementType != schemaAnyType)
                        foreach (XmlSchemaObject obj in schema.Items) {
                                if (obj is XmlSchemaElement) {
                                        XmlSchemaElement el = obj as XmlSchemaElement;
+#if NET_2_0
+                                       if (el.ElementSchemaType is XmlSchemaComplexType &&
+                                           el.ElementSchemaType != schemaAnyType)
+#else
                                        if (el.ElementType is XmlSchemaComplexType &&
-el.ElementType != schemaAnyType)
+                                           el.ElementType != schemaAnyType)
+#endif
                                                targetElements.Add (obj);
                                }
                        }
@@ -440,7 +458,12 @@ el.ElementType != schemaAnyType)
                {
                        XmlSchemaElement el = p as XmlSchemaElement;
                        if (el != null) {
-                               XmlSchemaComplexType ct = el.ElementType as XmlSchemaComplexType;
+                               XmlSchemaComplexType ct = null;
+#if NET_2_0
+                               ct = el.ElementSchemaType as XmlSchemaComplexType;
+#else
+                               ct = el.ElementType as XmlSchemaComplexType;
+#endif
                                if (ct == null || ct == schemaAnyType)
                                        return true; // column element
                                if (ct.AttributeUses.Count > 0)
@@ -466,13 +489,19 @@ el.ElementType != schemaAnyType)
                                return;
 
                        // If type is not complex, just skip this element
+#if NET_2_0
+                       if (! (el.ElementSchemaType is XmlSchemaComplexType && el.ElementSchemaType != schemaAnyType))
+#else
                        if (! (el.ElementType is XmlSchemaComplexType && el.ElementType != schemaAnyType))
+#endif
                                return;
 
                        if (IsDataSetElement (el)) {
                                ProcessDataSetElement (el);
                                return;
                        }
+                       else
+                               dataset.Locale = CultureInfo.CurrentCulture;
 
                        // Register as a top-level element
                        topLevelElements.Add (el);
@@ -485,9 +514,15 @@ el.ElementType != schemaAnyType)
                        dataset.DataSetName = el.Name;
                        this.datasetElement = el;
 
-                       // Search for msdata:Locale attribute
+                       // Search for locale attributes
+                       bool useCurrent = false;
                        if (el.UnhandledAttributes != null) {
                                foreach (XmlAttribute attr in el.UnhandledAttributes) {
+#if NET_2_0
+                                       if (attr.LocalName == "UseCurrentLocale" &&
+                                               attr.NamespaceURI == XmlConstants.MsdataNamespace)
+                                               useCurrent = true;
+#endif
                                        if (attr.LocalName == "Locale" &&
                                                attr.NamespaceURI == XmlConstants.MsdataNamespace) {
                                                CultureInfo ci = new CultureInfo (attr.Value);
@@ -495,9 +530,18 @@ el.ElementType != schemaAnyType)
                                        }
                                }
                        }
+#if NET_2_0
+                       if (!useCurrent && !dataset.LocaleSpecified) // then set current culture instance _explicitly_
+                               dataset.Locale = CultureInfo.CurrentCulture;
+#endif
 
                        // Process content type particle (and create DataTable)
-                       XmlSchemaComplexType ct = el.ElementType as XmlSchemaComplexType;
+                       XmlSchemaComplexType ct = null;
+#if NET_2_0
+                       ct = el.ElementSchemaType as XmlSchemaComplexType;
+#else
+                       ct = el.ElementType as XmlSchemaComplexType;
+#endif
                        XmlSchemaParticle p = ct != null ? ct.ContentTypeParticle : null;
                        if (p != null)
                                HandleDataSetContentTypeParticle (p);
@@ -507,7 +551,11 @@ el.ElementType != schemaAnyType)
                {
                        XmlSchemaElement el = p as XmlSchemaElement;
                        if (el != null) {
+#if NET_2_0
+                               if (el.ElementSchemaType is XmlSchemaComplexType && el.RefName != el.QualifiedName)
+#else
                                if (el.ElementType is XmlSchemaComplexType && el.RefName != el.QualifiedName)
+#endif
                                        ProcessDataTableElement (el);
                        }
                        else if (p is XmlSchemaGroupBase) {
@@ -525,6 +573,7 @@ el.ElementType != schemaAnyType)
 
                        DataTable table = new DataTable (tableName);
                        table.Namespace = el.QualifiedName.Namespace;
+                       TableStructure oldTable = currentTable;
                        currentTable = new TableStructure (table);
 
                        dataset.Tables.Add (table);
@@ -540,7 +589,12 @@ el.ElementType != schemaAnyType)
 
                        // Handle complex type (NOTE: It is (or should be)
                        // impossible the type is other than complex type).
-                       XmlSchemaComplexType ct = (XmlSchemaComplexType) el.ElementType;
+                       XmlSchemaComplexType ct = null;
+#if NET_2_0
+                       ct = (XmlSchemaComplexType) el.ElementSchemaType;
+#else
+                       ct = (XmlSchemaComplexType) el.ElementType;
+#endif
 
                        // Handle attributes
                        foreach (DictionaryEntry de in ct.AttributeUses)
@@ -577,6 +631,8 @@ el.ElementType != schemaAnyType)
                                table.Columns.Add ((DataColumn) de.Value);
                        foreach (DataColumn dc in currentTable.NonOrdinalColumns)
                                table.Columns.Add (dc);
+
+                       currentTable = oldTable;
                }
 
                private DataRelation GenerateRelationship (RelationStructure rs)
@@ -654,7 +710,12 @@ el.ElementType != schemaAnyType)
                        DataColumn col = new DataColumn ();
                        col.ColumnName = attr.QualifiedName.Name;
                        col.Namespace = attr.QualifiedName.Namespace;
-                       XmlSchemaDatatype dt = GetSchemaPrimitiveType (attr.AttributeType);
+                       XmlSchemaDatatype dt = null;
+#if NET_2_0
+                       dt = GetSchemaPrimitiveType (((XmlSchemaSimpleType) attr.AttributeSchemaType).Datatype);
+#else
+                       dt = GetSchemaPrimitiveType (attr.AttributeType);
+#endif
                        // This complicated check comes from the fact that
                        // MS.NET fails to map System.Object to anyType (that
                        // will cause ReadTypedObject() fail on XmlValidatingReader).
@@ -674,7 +735,11 @@ el.ElementType != schemaAnyType)
                        if (attr.Use == XmlSchemaUse.Required)
                                col.AllowDBNull = false;
 
+#if NET_2_0
+                       FillFacet (col, attr.AttributeSchemaType as XmlSchemaSimpleType);
+#else
                        FillFacet (col, attr.AttributeType as XmlSchemaSimpleType);
+#endif
 
                        // Call this method after filling the name
                        ImportColumnMetaInfo (attr, attr.QualifiedName, col);
@@ -689,7 +754,11 @@ el.ElementType != schemaAnyType)
                        col.DefaultValue = GetElementDefaultValue (el);
                        col.AllowDBNull = (el.MinOccurs == 0);
 
+#if NET_2_0
+                       if (el.ElementSchemaType is XmlSchemaComplexType && el.ElementSchemaType != schemaAnyType)
+#else
                        if (el.ElementType is XmlSchemaComplexType && el.ElementType != schemaAnyType)
+#endif
                                FillDataColumnComplexElement (parent, el, col);
                        else if (el.MaxOccurs != 1)
                                FillDataColumnRepeatedSimpleElement (parent, el, col);
@@ -700,7 +769,6 @@ el.ElementType != schemaAnyType)
                // common process for element and attribute
                private void ImportColumnMetaInfo (XmlSchemaAnnotated obj, XmlQualifiedName name, DataColumn col)
                {
-                       int ordinal = -1;
                        if (obj.UnhandledAttributes != null) {
                                foreach (XmlAttribute attr in obj.UnhandledAttributes) {
                                        if (attr.NamespaceURI != XmlConstants.MsdataNamespace)
@@ -725,7 +793,7 @@ el.ElementType != schemaAnyType)
                                                col.ReadOnly = XmlConvert.ToBoolean (attr.Value);
                                                break;
                                        case XmlConstants.Ordinal:
-                                               ordinal = int.Parse (attr.Value);
+                                               int ordinal = int.Parse (attr.Value);
                                                break;
                                        }
                                }
@@ -761,7 +829,7 @@ el.ElementType != schemaAnyType)
 
                        // If the element is not referenced one, the element will be handled later.
                        if (el.RefName == XmlQualifiedName.Empty)
-                               targetElements.Add (el);
+                               ProcessDataTableElement (el);
 
                }
 
@@ -826,7 +894,11 @@ el.ElementType != schemaAnyType)
                        cc2.Namespace = el.QualifiedName.Namespace;
                        cc2.ColumnMapping = MappingType.SimpleContent;
                        cc2.AllowDBNull = false;
+#if NET_2_0
+                       cc2.DataType = ConvertDatatype (GetSchemaPrimitiveType (el.ElementSchemaType));
+#else
                        cc2.DataType = ConvertDatatype (GetSchemaPrimitiveType (el.ElementType));
+#endif
 
                        dt.Columns.Add (cc2);
                        dt.Columns.Add (cc);
@@ -847,8 +919,13 @@ el.ElementType != schemaAnyType)
                        col.ColumnName = XmlHelper.Decode (el.QualifiedName.Name);
                        col.Namespace = el.QualifiedName.Namespace;
                        col.ColumnMapping = MappingType.Element;
+#if NET_2_0
+                       col.DataType = ConvertDatatype (GetSchemaPrimitiveType (el.ElementSchemaType));
+                       FillFacet (col, el.ElementSchemaType as XmlSchemaSimpleType);
+#else
                        col.DataType = ConvertDatatype (GetSchemaPrimitiveType (el.ElementType));
                        FillFacet (col, el.ElementType as XmlSchemaSimpleType);
+#endif
 
                        ImportColumnMetaInfo (el, el.QualifiedName, col);
 
@@ -973,8 +1050,13 @@ el.ElementType != schemaAnyType)
                        string tableName = c.TableName;
                        
                        DataTable dt = dataset.Tables [tableName];
-                       if (dt == null)
-                               throw new DataException (String.Format ("Invalid XPath selection inside selector. Cannot find: {0}", tableName));
+                       if (dt == null) {
+                               if (forDataSet)
+                                       throw new DataException (String.Format ("Invalid XPath selection inside selector. Cannot find: {0}", tableName));
+                               else
+                                       // nonexistent table name. .NET ignores it for DataTable.ReadXmlSchema().
+                                       return;
+                       }
 
                        DataColumn [] cols = new DataColumn [c.Columns.Length];
                        for (int i = 0; i < cols.Length; i++) {
@@ -1079,7 +1161,7 @@ el.ElementType != schemaAnyType)
 
                        if (!c.IsConstraintOnly) {
                                // generate the relation.
-                               DataRelation rel = new DataRelation (c.ConstraintName, uniq.Columns, cols, false);
+                               DataRelation rel = new DataRelation (c.ConstraintName, uniq.Columns, cols, true);
                                rel.Nested = c.IsNested;
                                rel.SetParentKeyConstraint (uniq);
                                rel.SetChildKeyConstraint (fkc);