bool enforceConstraints = this.EnforceConstraints;
this.EnforceConstraints = false;
for (int t = 0; t < tableCollection.Count; t++) {
- tableCollection [t].Clear ();
+ tableCollection[t].Clear ();
}
this.EnforceConstraints = enforceConstraints;
}
public virtual DataSet Clone ()
{
- DataSet Copy = new DataSet ();
+ // need to return the same type as this...
+ DataSet Copy = (DataSet) Activator.CreateInstance(GetType(), true);
+
CopyProperties (Copy);
foreach (DataTable Table in Tables) {
- Copy.Tables.Add (Table.Clone ());
+ // tables are often added in no-args constructor, don't add them
+ // twice.
+ if (!Copy.Tables.Contains(Table.TableName)) {
+ Copy.Tables.Add (Table.Clone ());
+ }
}
//Copy Relationships between tables after existance of tables
}
DataRow newRow = copyTable.NewRow ();
- copyTable.Rows.Add (newRow);
row.CopyValuesToRow (newRow);
+ copyTable.Rows.Add (newRow);
newRow.XmlRowID = row.XmlRowID;
addedRows.Add (row,row);
}
return ReadXml (new XmlTextReader (reader), mode);
}
- public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
+ // LAMESPEC: XmlReadMode.Fragment is far from presisely
+ // documented. MS.NET infers schema against this mode.
+ public XmlReadMode ReadXml (XmlReader input, XmlReadMode mode)
{
- switch (reader.ReadState) {
+ switch (input.ReadState) {
case ReadState.EndOfFile:
case ReadState.Error:
case ReadState.Closed:
return mode;
}
// Skip XML declaration and prolog
- reader.MoveToContent();
- if (reader.EOF)
+ input.MoveToContent ();
+ if (input.EOF)
return mode;
- XmlReadMode Result = mode;
+ // FIXME: We need more decent code here, but for now
+ // I don't know the precise MS.NET behavior, I just
+ // delegate to specific read process.
+ switch (mode) {
+ case XmlReadMode.IgnoreSchema:
+ return ReadXmlIgnoreSchema (input, mode, true);
+ case XmlReadMode.ReadSchema:
+ return ReadXmlReadSchema (input, mode, true);
+ }
+ // remaining modes are: Auto, InferSchema, Fragment, Diffgram
- // If diffgram, then read the first element as diffgram
- if (reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) {
- switch (mode) {
- case XmlReadMode.Auto:
- case XmlReadMode.DiffGram:
- XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
- DiffLoader.Load (reader);
- // (and leave rest of the reader as is)
- return XmlReadMode.DiffGram;
- case XmlReadMode.Fragment:
- reader.Skip ();
- // (and continue to read)
- break;
- default:
- reader.Skip ();
- // (and leave rest of the reader as is)
- return mode;
+ XmlReader reader = input;
+
+ int depth = reader.Depth;
+ XmlReadMode result = mode;
+ bool skippedTopLevelElement = false;
+ string potentialDataSetName = null;
+ XmlDocument doc = null;
+ bool shouldReadData = mode != XmlReadMode.DiffGram;
+ bool shouldNotInfer = Tables.Count > 0;
+
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ doc = new XmlDocument ();
+ do {
+ doc.AppendChild (doc.ReadNode (reader));
+ } while (!reader.EOF &&
+ doc.DocumentElement == null);
+ reader = new XmlNodeReader (doc);
+ reader.MoveToContent ();
+ break;
+ case XmlReadMode.DiffGram:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace))
+ goto case XmlReadMode.Auto;
+ break;
+ }
+
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ case XmlReadMode.ReadSchema:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace) &&
+ !(reader.LocalName == "schema" &&
+ reader.NamespaceURI == XmlSchema.Namespace))
+ potentialDataSetName = reader.LocalName;
+ goto default;
+ case XmlReadMode.Fragment:
+ break;
+ default:
+ if (!(reader.LocalName == "diffgram" &&
+ reader.NamespaceURI == XmlConstants.DiffgrNamespace) &&
+ !(reader.LocalName == "schema" &&
+ reader.NamespaceURI == XmlSchema.Namespace)) {
+ if (!reader.IsEmptyElement) {
+ reader.Read ();
+ reader.MoveToContent ();
+ skippedTopLevelElement = true;
+ }
+ else {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+ DataSetName = reader.LocalName;
+ break;
+ }
+ reader.Read ();
+ }
}
+ break;
}
+
// If schema, then read the first element as schema
if (reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) {
+ shouldNotInfer = true;
switch (mode) {
case XmlReadMode.IgnoreSchema:
case XmlReadMode.InferSchema:
reader.Skip ();
- // (and break up read)
- return mode;
+ break;
case XmlReadMode.Fragment:
ReadXmlSchema (reader);
- // (and continue to read)
break;
+ case XmlReadMode.DiffGram:
case XmlReadMode.Auto:
if (Tables.Count == 0) {
ReadXmlSchema (reader);
- return XmlReadMode.ReadSchema;
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.ReadSchema;
} else {
// otherwise just ignore and return IgnoreSchema
reader.Skip ();
- return XmlReadMode.IgnoreSchema;
+ result = XmlReadMode.IgnoreSchema;
}
- default:
+ break;
+ case XmlReadMode.ReadSchema:
ReadXmlSchema (reader);
- // (and leave rest of the reader as is)
- return mode; // When DiffGram, return DiffGram
+ break;
}
}
+
+ // If diffgram, then read the first element as diffgram
+ if (reader.LocalName == "diffgram" && reader.NamespaceURI == XmlConstants.DiffgrNamespace) {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.IgnoreSchema:
+ case XmlReadMode.DiffGram:
+ XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
+ DiffLoader.Load (reader);
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.DiffGram;
+ shouldReadData = false;
+ break;
+ case XmlReadMode.Fragment:
+ reader.Skip ();
+ break;
+ default:
+ reader.Skip ();
+ break;
+ }
+ }
+
+ // if schema after diffgram, just skip it.
+ if (!shouldReadData && reader.LocalName == "schema" && reader.NamespaceURI == XmlSchema.Namespace) {
+ shouldNotInfer = true;
+ switch (mode) {
+ default:
+ reader.Skip ();
+ break;
+ case XmlReadMode.ReadSchema:
+ case XmlReadMode.DiffGram:
+ if (Tables.Count == 0)
+ ReadXmlSchema (reader);
+ break;
+ }
+ }
+
+ if (reader.EOF)
+ return result == XmlReadMode.Auto ?
+ potentialDataSetName != null && !shouldNotInfer ?
+ XmlReadMode.InferSchema :
+ XmlReadMode.IgnoreSchema : result;
+
// Otherwise, read as dataset... but only when required.
- XmlReadMode explicitReturnMode = XmlReadMode.Auto;
- XmlDocument doc;
- switch (mode) {
- case XmlReadMode.Auto:
- if (Tables.Count > 0)
- goto case XmlReadMode.IgnoreSchema;
- else
- goto case XmlReadMode.InferSchema;
- case XmlReadMode.InferSchema:
- doc = new XmlDocument ();
- do {
- doc.AppendChild (doc.ReadNode (reader));
- reader.MoveToContent ();
- if (doc.DocumentElement != null)
- break;
- } while (!reader.EOF);
- InferXmlSchema (doc, null);
- reader = new XmlNodeReader (doc);
- explicitReturnMode = XmlReadMode.InferSchema;
- break;
- case XmlReadMode.ReadSchema:
- doc = new XmlDocument ();
- do {
- doc.AppendChild (doc.ReadNode (reader));
- reader.MoveToContent ();
- if (doc.DocumentElement != null)
- break;
- } while (!reader.EOF);
- if (doc.DocumentElement != null) {
- XmlElement schema = doc.DocumentElement ["schema", XmlSchema.Namespace] as XmlElement;
- if (schema != null) {
- ReadXmlSchema (new XmlNodeReader (schema));
- explicitReturnMode = XmlReadMode.ReadSchema;
- }
+ if (shouldReadData && !shouldNotInfer) {
+ switch (mode) {
+ case XmlReadMode.Auto:
+ if (Tables.Count > 0)
+ goto case XmlReadMode.IgnoreSchema;
+ else
+ goto case XmlReadMode.InferSchema;
+ case XmlReadMode.InferSchema:
+ InferXmlSchema (doc, null);
+ if (mode == XmlReadMode.Auto)
+ result = XmlReadMode.InferSchema;
+ break;
+ case XmlReadMode.IgnoreSchema:
+ case XmlReadMode.Fragment:
+ case XmlReadMode.DiffGram:
+ break;
+ default:
+ shouldReadData = false;
+ break;
}
- reader = new XmlNodeReader (doc);
- break;
- case XmlReadMode.IgnoreSchema:
- case XmlReadMode.Fragment:
- break;
- default:
- reader.Skip ();
- return mode;
}
- XmlDataReader.ReadXml (this, reader, mode);
- if (explicitReturnMode != XmlReadMode.Auto)
- return explicitReturnMode;
- return mode == XmlReadMode.Auto ? XmlReadMode.IgnoreSchema : mode;
+ if (shouldReadData) {
+ XmlReader dataReader = reader;
+ if (doc != null) {
+ dataReader = new XmlNodeReader (doc);
+ dataReader.MoveToContent ();
+ }
+ if (reader.NodeType == XmlNodeType.Element)
+ XmlDataReader.ReadXml (this, dataReader,
+ mode);
+ }
+
+ if (skippedTopLevelElement) {
+ switch (result) {
+ case XmlReadMode.Auto:
+ case XmlReadMode.InferSchema:
+// DataSetName = potentialDataSetName;
+// result = XmlReadMode.InferSchema;
+ break;
+ }
+ if (reader.NodeType == XmlNodeType.EndElement)
+ reader.ReadEndElement ();
+ }
+//*
+ while (input.Depth > depth)
+ input.Read ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.Read ();
+//*/
+ input.MoveToContent ();
+
+ return result == XmlReadMode.Auto ?
+ XmlReadMode.IgnoreSchema : result;
}
#endregion // Public Methods
protected virtual void ReadXmlSerializable (XmlReader reader)
{
- reader.MoveToContent ();
- reader.ReadStartElement ();
- reader.MoveToContent ();
- ReadXmlSchema (reader);
- reader.MoveToContent ();
- ReadXml (reader, XmlReadMode.DiffGram);
- reader.MoveToContent ();
- reader.ReadEndElement ();
+ ReadXml (reader);
}
void IXmlSerializable.ReadXml (XmlReader reader)
XmlSchema IXmlSerializable.GetSchema ()
{
- return BuildSchema ();
+ return GetSchemaSerializable ();
}
protected virtual bool ShouldSerializeRelations ()
}
#endregion
- #region Private Xml Serialisation
+ #region Private Methods
+
+ private XmlReadMode ReadXmlIgnoreSchema (XmlReader input, XmlReadMode mode, bool checkRecurse)
+ {
+ if (input.LocalName == "schema" &&
+ input.NamespaceURI == XmlSchema.Namespace) {
+ input.Skip ();
+ }
+ else if (input.LocalName == "diffgram" &&
+ input.NamespaceURI == XmlConstants.DiffgrNamespace) {
+ XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
+ DiffLoader.Load (input);
+ }
+ else if (checkRecurse ||
+ input.LocalName == DataSetName &&
+ input.NamespaceURI == Namespace) {
+ XmlDataReader.ReadXml (this, input, mode);
+ }
+ else if (checkRecurse && !input.IsEmptyElement) {
+ int depth = input.Depth;
+ input.Read ();
+ input.MoveToContent ();
+ ReadXmlIgnoreSchema (input, mode, false);
+ while (input.Depth > depth)
+ input.Skip ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.ReadEndElement ();
+ }
+ input.MoveToContent ();
+ return XmlReadMode.IgnoreSchema;
+ }
+
+ private XmlReadMode ReadXmlReadSchema (XmlReader input, XmlReadMode mode, bool checkRecurse)
+ {
+ if (input.LocalName == "schema" &&
+ input.NamespaceURI == XmlSchema.Namespace) {
+ ReadXmlSchema (input);
+ }
+ else if (checkRecurse && !input.IsEmptyElement) {
+ int depth = input.Depth;
+ input.Read ();
+ input.MoveToContent ();
+ ReadXmlReadSchema (input, mode, false);
+ while (input.Depth > depth)
+ input.Skip ();
+ if (input.NodeType == XmlNodeType.EndElement)
+ input.ReadEndElement ();
+ }
+ else
+ input.Skip ();
+ input.MoveToContent ();
+ return XmlReadMode.ReadSchema;
+ }
private string WriteObjectXml (object o)
{
}
// set the schema id
- string xmlNSURI = "http://www.w3.org/2000/xmlns/";
schema.Id = DataSetName;
XmlDocument doc = new XmlDocument ();
XmlAttribute attr = null;
ArrayList atts = new ArrayList ();
- attr = doc.CreateAttribute ("", "xmlns", xmlNSURI);
+ attr = doc.CreateAttribute ("", "xmlns", XmlConstants.XmlnsNS);
atts.Add (attr);
nsmgr.AddNamespace ("xs", XmlSchema.Namespace);
nsmgr.AddNamespace (XmlConstants.TnsPrefix, Namespace);
nsmgr.AddNamespace (String.Empty, Namespace);
}
- if (CheckExtendedPropertyExists ())
+ if (CheckExtendedPropertyExists (tables, relations))
nsmgr.AddNamespace (XmlConstants.MspropPrefix, XmlConstants.MspropNamespace);
if (atts.Count > 0)
elem.Name = XmlConvert.EncodeName (DataSetName);
// Add namespaces used in DataSet components (tables, columns, ...)
- foreach (DataTable dt in Tables) {
+ foreach (DataTable dt in tables) {
foreach (DataColumn col in dt.Columns)
CheckNamespace (col.Prefix, col.Namespace, nsmgr, schema);
CheckNamespace (dt.Prefix, dt.Namespace, nsmgr, schema);
if (prefix != "xmlns" && prefix != "xml" && ns != null && ns != String.Empty)
schema.Namespaces.Add (prefix, ns);
}
+
return schema;
}
-
- private bool CheckExtendedPropertyExists ()
+
+ private bool CheckExtendedPropertyExists (
+ DataTableCollection tables,
+ DataRelationCollection relations)
{
if (ExtendedProperties.Count > 0)
return true;
- foreach (DataTable dt in Tables) {
+ foreach (DataTable dt in tables) {
if (dt.ExtendedProperties.Count > 0)
return true;
foreach (DataColumn col in dt.Columns)
if (c.ExtendedProperties.Count > 0)
return true;
}
- foreach (DataRelation rel in Relations)
+ if (relations == null)
+ return false;
+ foreach (DataRelation rel in relations)
if (rel.ExtendedProperties.Count > 0)
return true;
return false;
}
// Add all constraints in all tables to the schema.
- private void AddConstraintsToSchema (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, DataRelationCollection relations, XmlDocument doc)
+ private void AddConstraintsToSchema (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, DataRelationCollection relations, XmlDocument doc)
{
// first add all unique constraints.
Hashtable uniqueNames = AddUniqueConstraints (elem, constraintPrefix, tables, doc);
foreach (DataColumn column in uqConst.Columns) {
field = new XmlSchemaXPath();
string typePrefix = column.ColumnMapping == MappingType.Attribute ? "@" : "";
- field.XPath = typePrefix + constraintPrefix + column.ColumnName;
+ field.XPath = typePrefix + constraintPrefix+column.ColumnName;
uniq.Fields.Add(field);
}
ArrayList elements;
ArrayList atts;
DataColumn simple;
-
+
ArrayList xattrs = new ArrayList();
XmlAttribute xattr;
// FIXME: Handle prefix mapping correctly.
schemaToAdd.Namespaces.Add (prefix, col.Namespace);
}
- if (!col.AllowDBNull)
- att.Use = XmlSchemaUse.Required;
-
- if (col.MaxLength > -1)
- att.SchemaType = GetTableSimpleType (doc, col);
- else
- att.SchemaTypeName = MapType (col.DataType);
- // FIXME: what happens if extended properties are set on attribute columns??
if (!col.AllowDBNull)
att.Use = XmlSchemaUse.Required;
if (col.DefaultValue.ToString () != String.Empty)
}
att.UnhandledAttributes = xattrs.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
+ xattrs.Clear ();
if (col.MaxLength > -1)
att.SchemaType = GetTableSimpleType (doc, col);
else
att.SchemaTypeName = MapType (col.DataType);
+ // FIXME: what happens if extended properties are set on attribute columns??
schemaAttributes.Add (att);
}
}
if (attList.Count > 0)
xsobj.UnhandledAttributes = attList.ToArray (typeof (XmlAttribute)) as XmlAttribute [];
- }
+ }
private string SafeNS (string ns)
{