[DefaultProperty ("DataSetName")]
[Serializable]
public class DataSet : MarshalByValueComponent, IListSource,
- ISupportInitialize, ISerializable, IXmlSerializable {
+ ISupportInitialize, ISerializable, IXmlSerializable
+ {
private string dataSetName;
private string _namespace = "";
private string prefix;
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)
}
[MonoTODO]
- protected DataSet (SerializationInfo info, StreamingContext context) : this () {
+ protected DataSet (SerializationInfo info, StreamingContext context) : this ()
+ {
throw new NotImplementedException ();
}
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;
}
//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];
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);
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);
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)
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 ();
/*\
* 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)
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;
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 ();
void IXmlSerializable.WriteXml (XmlWriter writer)
{
DoWriteXmlSchema (writer);
- WriteXml (writer, XmlWriteMode.IgnoreSchema, true);
+ WriteXml (writer, XmlWriteMode.DiffGram, true);
}
protected virtual bool ShouldSerializeRelations ()
#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
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;
}
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);
}
}
}
}
+
+ 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 ()
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 ();
att.SchemaTypeName = MapType (col.DataType);
complex.Attributes.Add (att);
}
+
return elem;
}
/// 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
//Sort out the columns
foreach (DataColumn col in table.Columns) {
- switch (col.ColumnMapping)
- {
+ switch (col.ColumnMapping) {
case MappingType.Attribute:
atts.Add (col);
break;
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;
}
}
}
+
+ 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;
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 ();
#region ctors
- public XmlDiffLoader (DataSet DSet)
+ public XmlDiffLoader (DataSet DSet)
{
this.DSet = DSet;
}
#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 ();
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 ();
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 ();
}
}
- 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 ());
}
}
+ 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
}
//
// (C) 2002 Ville Palo
//
-// TODO: Relations
//
using System;
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);
+ }
}
}
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);
}
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)
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);
}
}
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];
}
}
- 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