++2006-03-20 Senganal T <tsenganal@novell.com>
++
++ * DataSet.cs :
++ - CopyRelations () : When copying the relation, do not add constraints
++ automatically for the relation.
++ - OnMergeFailed () : If merge fails and no handler is set for the MergeFailedEvent,
++ then throw DataException
++ * ConstraintCollection.cs :
++ - Add () : Check if a constraint already exists on the Columns that are being
++ constrained.
++ - IndexOf () : Do not check for equivalent constraints, check for the exact instance.
++ * MergeManager.cs ():
++ - AdjustSchema () :
++ - Handle the MissingSchemaAction.Error case,
++ - Do not create constraints when mergin the DataRelation
++ - Follow the semantics for schema merge/validation when constraints are already present
++ in the target DataSet.
++ - AdjustPrimaryKeys () :
++ - Code cleanup
++ - Verify Order of Columns in the PrimaryKey when merging.
++ - ResolveColumns : Changed the arument to DataSet. Simplifies code elsewhere.
++ - CompareColumnArrays, CompareColumnArrays : Helper funtions.
++
+ 2006-03-09 Senganal T <tsenganal@novell.com>
+
+ * DataRow.cs :
+ - RejectChanges () : Add the row to index, if it was in deleted state and
+ Update the index if in Modified State.
+ - AcceptChanges () : Do not update the Indexes.
+ - EndEdit () : Update the indexes even if BeginLoadData has been called
+ on the table. Ideally, indexes should not be maintained during DataLoad,
+ but this needs to handled in multiple places correctly. For now, just maintain
+ the index to ensure correct operation.
+
+ 2006-03-05 Senganal T <tsenganal@novell.com>
+
+ * DataSet.cs :
+ - BeginInit (), EndInit () : Implemented methods
+ - InitInProgress : Added.
+ * DataTable.cs
+ - EndInit () : Move the adding of columns and constraints
+ to FinishInit.
+ - FinishInit () : Added. Adds the Constraints and Columns
+ to the collection.
+ - InitInProgress : Added.
+ * Constraint.cs
+ - FinishInit () : Added. Virtual method
+ - InitInProgress : Added. Virtual property
+ * UniqueConstraint.cs
+ * ForeignKeyConstraint.cs
+ - FinishInit () : Added.
+ - InitInProgress : Added.
+ - DataColsNotValidated : Removed.
+ * ConstraintCollection.cs
+ - PostAddRange : Removed event
+ - PostEndEdit () : Renamed to PostAddRange
+ - Add () : Simplified the testing if constraint is initialized
+ - AddRange () : Simplified initializing the constraints
+ * DataTableCollection.cs
+ - PostAddRange () : Added. Adds the tables to the collection
+ * DataColumnColletion.cs
+ - PostEndInit () : Renamed to PostAddRange.Also, add column to
+ the collection only if not null.
+
+ Added/Implemented methods for design time support. Renamed some methods for consistency
+ in naming across classes for methods serving the same purpose.
+
+ 2006-02-24 Senganal T <tsenganal@novell.com>
+
+ * UniqueConstraint.cs :
+ - ChildConstraint : Added. Simplifies verifying if constraints are
+ related.
+ - CanRemoveFromCollection : Fixed the check to verify if constraints is
+ linked to a ForeignKeyConstraint. Fixes #77630
+ * ForeignKeyConstraint.cs :
+ - _validateRemoveParentConstraint : Removed. Not used anymore
+ - ParentConstraint : Added. Simplifies verifying if constraints are
+
+ 2006-02-22 Senganal T <tsenganal@novell.com>
+
+ * DataRow.cs
+ - RejectChanges : Do not remove Row from Indexes when state is Deleted.
+ - CheckChildRows : When checking for the ChildRows, use the current value
+ and not the original value.
+
+ 2006-02-18 Atsushi Enomoto <atsushi@ximian.com>
+
+ * CustomDataClassGenerator.cs : Patch by Marek Habersack. xsd now
+ outputs AutoIncrement, AutoIncrementSeed, AutoIncrementStep and
+ ReadOnly properties. This fixes bug #77576.
+
+ 2006-02-17 Chris Toshok <toshok@ximian.com>
+
+ * System.Data/DataSet.cs, System.Data/DataView.cs,
+ System.Data/ForeignKeyConstraint.cs,
+ System.Data/DataViewManager.cs, System.Data/DataRow.cs,
+ System.Data/DataSysDescriptionAttribute.cs,
+ System.Data/UniqueConstraint.cs, System.Data/DataTable.cs,
+ System.Data/DataRelation.cs: lots of attribute work, removing
+ DataSysDescription atributes (and marking the class obsolete) for
+ 2.0.
+
+ 2006-02-17 Chris Toshok <toshok@ximian.com>
+
+ * DataAdapterException.cs: remove this file.
+
+ 2006-02-17 Chris Toshok <toshok@ximian.com>
+
+ * DataTableReader.cs: Switch to the (bool) form of Dispose to
+ override, as the no-arg form isn't virtual.
+
+ * Constraint.cs: #ifdef out more DataSysDescriptions.
+
+ * ConstraintException.cs: add ..ctor (string, Exception) for 2.0.
+
+ 2006-02-17 Chris Toshok <toshok@ximian.com>
+
+ * DataColumn.cs: #ifdef all the DataSysDescriptions !NET_2_0.
+
+ * AdapterMappingException.cs: nuke this file.
+
+ * IDbAsyncConnection.cs, IDbAsyncCommand.cs, IGetTypedData.cs,
+ ISetTypedData.cs, IDataReader2.cs, IDataSources.cs,
+ IDbExecutionContext.cs, IDataRecord2.cs, IDataUpdatableRecord.cs:
+ remove these 2.0 files.
+
+ 2006-02-17 Chris Toshok <toshok@ximian.com>
+
+ * ConstraintCollection.cs: in 2.0, class is not serializable and
+ is sealed. make all the "virtuals" #if !NET_2_0 as well.
+
+ * Constraint.cs: not serializable in 2.0.
+
+ * DataColumnCollection.cs: in 2.0, class is not serializable and
+ is sealed. make all the "virtuals" #if !NET_2_0 as well.
+
+ * DataRelationCollection.cs: not serializable in 2.0.
+
+ * DataRelation.cs: not serializable in 2.0.
+
+ * DataRowBuilder.cs: class is sealed in 2.0.
+
+ * DataRowCollection.cs: in 2.0, class is not serialized and is
+ sealed. Also, Add isn't virtual in 2.0 (as the class is sealed).
+
+ * DataRow.cs: not serializable in 2.0.
+
+ * DataSet.cs: remove some DataSysDescriptions from the 2.0 build,
+ and s/GetDataReader/CreateDataReader.
+
+ * DataTableCollection.cs: in 2.0, class is not serializable and is
+ sealed. make all the "virtuals" #if !NET_2_0 as well.
+
+ * DataTableReader.cs: remove VisibleFieldCount property.
+
+ * DataViewSettingCollection.cs: not serializable in 2.0.
+
+ * DataViewSetting.cs: not serializable in 2.0.
+
+ * ForeignKeyConstraint.cs: serializable in 2.0.
+
+ * OperationAbortedException.cs: class is sealed and serializable.
+
+ * PropertyCollection.cs: serializable in 2.0.
+
+ * StatementCompletedEventArgs.cs: class is sealed.
+
+ * UniqueConstraint.cs: not serializable in 2.0.
+
+ 2006-02-16 Senganal T <tsenganal@novell.com>
+
+ * XmlSchemaWriter :
+ WriteDataSetElement : Add an annotation element if exists.
+ WriteDataRelationAnnotation : New. Write a DataRelation as an annotation.
+ WriteConstraints : Write ForeignKeyConstraint even when not associated with
+ a DataRelation and add a "ConstraintOnly=true" attribute for such constraints.
+ * XmlConstants.cs : Add a new constant - ConstraintOnly
+ * XmlSchemaImporter.cs :
+ - ConstraintStructure : Add field ,IsConstraintOnly, to distinguish if a foreignkeyconstraint
+ is related to relation or not.
+ - GenerateRelation : Handle the case when parentkey and childkey contain multiple columnnames.
+
+ 2006-02-11 Senganal T <tsenganal@novell.com>
+
+ * UniqueConstraint.cs :
+ - PostAddRange : Check PrimaryKey is not already set for the table
+ * DataTable.cs :
+ - PrimaryKey : follow ms.net behavior when BeginInit , EndInit is used.
+ - Add new priamry key only when EndInit is called.
+ - Incase of an error, retain old primarykey
+ - EndInit :
+ - Add Constraints after columns are added.
+ - If both PrimaryKey Property and PrimaryKey Constraint are set,
+ then the Constraint takes precedence.
+ fixes bug #77404
+
+ 2006-02-03 Senganal T <tsenganal@novell.com>
+
+ * DataTableCollection.cs :
+ - Remove () : Check for invalid TableName
+ - Add () : Verify the table doesn't belong to another dataset
+ * DataView.cs :
+ - CompleteLastAdded () : Do not raise ItemAdded Event as it is
+ already raised in AddNew().
+ * DataColumn.cs :
+ - Expression : Verify that the Column names in the expression are valid
+ - ResetCollectionInfo : Renamed to ResetColumnInfo
+ * DataRow.cs :
+ - RejectChanges () : Reorganized the code to do the Right thing.
+ - Item : Dont check for detached and deleted rows as these are
+ done elsewhere.
+ * DataRowCollection.cs :
+ - Add () : Check for null value
+ * DataTable.cs :
+ - PrimaryKey : Set AllowDBNull=false for all the key columns
+ - ImportRow : Import the row only if it is not in Detached state. if in Deleted
+ state, perform the validation when AcceptChanges/RejectChanges is called.
+ * DataColumnCollection.cs :
+ - Add : Validate the column expression before adding it to the collection.
+ - GetColumnDependency () : New. Get the dependencies on the column
+ - CanRemove : Move checks to GetColumnDependency
+ - Clear () : Simplified code. Remove unncessary checks.Also, dont check Expression col.
+ - IndexOf - Check argument.
+ Overall , appropriate error msg's are thrown if Remove/Clear fails. Removed a few
+ redundant checks performed and moved the common code to GetColumnDependency.
+
+ 2006-01-31 Senganal T <tsenganal@novell.com>
+
+ * DataSet.cs : Modified CopyRelations ()
+ - Added code to copy ForeignKeyConstraints. Fixes #77411.
+
+ 2006-01-18 Boris Kirzner <borisk@mainsoft.com>
+ * DataColumn.cs: added PropertyCchangedEvent handling.
+
+ 2006-01-17 Senganal T <tsenganal@novell.com>
+
+ * DataRow.cs:
+ ItemArray : Modified to raise RowInTableException only if
+ the concerned row has been removed from the table.Fixes
+ bug #77267
+
+ 2006-01-16 Boris Kirzner <borisk@mainsoft.com>
+ * DataTable.cs: Drop dependend indexes on column removal.
+
+ 2006-01-16 Atsushi Enomoto <atsushi@ximian.com>
+
+ * CustomDataClassGenerator.cs :
+ When a DataRelation connects the same table as parent and child,
+ generate parent row property as BlahRowParent. Fixed bug #77248.
+
+ 2006-01-10 Senganal T <tsenganal@novell.com>
+ * DataRowCollection.cs
+ - Added ListChangedEvent to notify reset of the collection.
+ * DataView.cs
+ - Subscribes to the ListChangedEvent of DataRowCollection
+ Fixes bug #77188
+
+ 2006-01-09 Senganal T <tsenganal@novell.com>
+ * RelatedDataView.cs
+ * DataColumn.cs
+ - Resolving a name clash in IExpression
+
+ 2006-01-06 Senganal T <tsenganal@novell.com>
+
+ * DataColumn.cs
+ * DataColumnCollection.cs
+ - Reset the Parameters of DataColumn to Default Values when
+ column is removed from the Table's Collection
+
+ 2006-01-03 Senganal T <tsenganal@novell.com>
+
+ * DataTable.cs :
+ - ParseSortString() : Changed the way the sort string is parsed.
+ Using a regex to parse the string.Fixes bug #77104
+
2005-12-12 Konstantin Triger <kostat@mainsoft.com>
* DataRow.cs: Added index Updates.
throw new ArgumentException("Constraint already belongs to this collection.");
if (null != constraint.ConstraintCollection)
throw new ArgumentException("Constraint already belongs to another collection.");
-
+
++ //check if a constraint already exists for the datacolums
++ foreach (Constraint c in this) {
++ if (!c.Equals (constraint))
++ continue;
++ throw new DataException ("Constraint matches contraint named '" + c.ConstraintName
++ + "' already in collection");
++ }
++
//check for duplicate name
if (_isDuplicateConstraintName(constraint.ConstraintName,null) )
throw new DuplicateNameException("Constraint name already exists.");
public int IndexOf(Constraint constraint)
{
-- return List.IndexOf(constraint);
++ int index = 0;
++ foreach (Constraint c in this) {
++ if (c == constraint)
++ return index;
++ index++;
++ }
++ return -1;
}
- public virtual int IndexOf(string constraintName)
+ public
+ #if !NET_2_0
+ virtual
+ #endif
+ int IndexOf(string constraintName)
{
//LAMESPEC: Spec doesn't say case insensitive
//it should to be consistant with the other
i++;\r
}\r
\r
-- DataRelation cRel = new DataRelation (MyRelation.RelationName, P_DC, C_DC);\r
- //cRel.ChildColumns = MyRelation.ChildColumns;\r
- //cRel.ChildTable = MyRelation.ChildTable;\r
- //cRel.ExtendedProperties = cRel.ExtendedProperties; \r
- //cRel.Nested = MyRelation.Nested;\r
- //cRel.ParentColumns = MyRelation.ParentColumns;\r
- //cRel.ParentTable = MyRelation.ParentTable;\r
- \r
++ DataRelation cRel = new DataRelation (MyRelation.RelationName, P_DC, C_DC, false);\r
Copy.Relations.Add (cRel);\r
}\r
+ \r
+ // Foreign Key constraints are not cloned in DataTable.Clone\r
+ // so, these constraints should be cloned when copying the relations.\r
+ foreach (DataTable table in this.Tables) {\r
+ foreach (Constraint c in table.Constraints) {\r
+ if (!(c is ForeignKeyConstraint) \r
+ || Copy.Tables[table.TableName].Constraints.Contains (c.ConstraintName))\r
+ continue;\r
+ ForeignKeyConstraint fc = (ForeignKeyConstraint)c;\r
+ DataTable parentTable = Copy.Tables [fc.RelatedTable.TableName];\r
+ DataTable currTable = Copy.Tables [table.TableName];\r
+ DataColumn[] parentCols = new DataColumn [fc.RelatedColumns.Length];\r
+ DataColumn[] childCols = new DataColumn [fc.Columns.Length];\r
+ for (int j=0; j < parentCols.Length; ++j)\r
+ parentCols [j] = parentTable.Columns[fc.RelatedColumns[j].ColumnName];\r
+ for (int j=0; j < childCols.Length; ++j)\r
+ childCols [j] = currTable.Columns[fc.Columns[j].ColumnName];\r
+ currTable.Constraints.Add (fc.ConstraintName, parentCols, childCols);\r
+ }\r
+ }\r
}\r
\r
- \r
- \r
- \r
public DataSet GetChanges ()\r
{\r
return GetChanges (DataRowState.Added | DataRowState.Deleted | DataRowState.Modified);\r
{\r
if (MergeFailed != null)\r
MergeFailed (this, e);\r
++ else\r
++ throw new DataException (e.Conflict);\r
}\r
\r
[MonoTODO]\r
bool prevEC = targetSet.EnforceConstraints;
targetSet.EnforceConstraints = false;
++
foreach (DataTable t in sourceSet.Tables)
MergeManager.Merge(targetSet, t, preserveChanges, missingSchemaAction);
// return false if adjusting fails.
private static bool AdjustSchema(DataSet targetSet, DataSet sourceSet, MissingSchemaAction missingSchemaAction)
{
-- if (missingSchemaAction == MissingSchemaAction.Add || missingSchemaAction == MissingSchemaAction.AddWithKey) {
-- foreach (DataRelation relation in sourceSet.Relations) {
-- // TODO : add more precise condition (columns)
-- if (!targetSet.Relations.Contains(relation.RelationName)) {
-- DataTable targetTable = targetSet.Tables[relation.ParentColumns[0].Table.TableName];
-- DataColumn[] parentColumns = ResolveColumns(sourceSet,targetTable,relation.ParentColumns);
-- targetTable = targetSet.Tables[relation.ChildColumns[0].Table.TableName];
-- DataColumn[] childColumns = ResolveColumns(sourceSet,targetTable,relation.ChildColumns);
-- if (parentColumns != null && childColumns != null) {
-- DataRelation newRelation = new DataRelation(relation.RelationName,parentColumns,childColumns);
-- newRelation.Nested = relation.Nested;
-- targetSet.Relations.Add(newRelation);
-- }
++ if (missingSchemaAction == MissingSchemaAction.Ignore)
++ return true;
++
++ foreach(DataTable sourceTable in sourceSet.Tables) {
++
++ DataTable targetTable = targetSet.Tables[sourceTable.TableName];
++ if (targetTable == null)
++ continue;
++
++ foreach (Constraint constraint in sourceTable.Constraints) {
++
++ Constraint targetConstraint = null;
++
++ string constraintName = constraint.ConstraintName;
++ if (targetTable.Constraints.Contains (constraintName))
++ constraintName = "";
++
++ UniqueConstraint uc = constraint as UniqueConstraint;
++ // PrimaryKey is already taken care of while merging the table
++ // ForeignKey constraint takes care of Parent Unique Constraints
++ if (uc != null) {
++ if (uc.IsPrimaryKey || uc.ChildConstraint != null)
++ continue;
++ DataColumn[] columns = ResolveColumns (targetSet, uc.Columns);
++ targetConstraint = new UniqueConstraint (constraintName, columns, false);
}
-- else {
-- // TODO : should we throw an exeption ?
++
++ ForeignKeyConstraint fc = constraint as ForeignKeyConstraint;
++ if (fc != null) {
++ DataColumn[] columns = ResolveColumns (targetSet, fc.Columns);
++ DataColumn[] relatedColumns = ResolveColumns (targetSet, fc.RelatedColumns);
++ targetConstraint = new ForeignKeyConstraint (constraintName, relatedColumns, columns);
}
-- }
--
-- foreach(DataTable sourceTable in sourceSet.Tables) {
-- DataTable targetTable = targetSet.Tables[sourceTable.TableName];
--
-- if (targetTable != null) {
-- foreach(Constraint constraint in sourceTable.Constraints) {
--
-- if (constraint is UniqueConstraint) {
-- UniqueConstraint uc = (UniqueConstraint)constraint;
-- // FIXME : add more precise condition (columns)
-- if ( !targetTable.Constraints.Contains(uc.ConstraintName) ) {
-- DataColumn[] columns = ResolveColumns(sourceSet,targetTable,uc.Columns);
-- if (columns != null) {
-- UniqueConstraint newConstraint = new UniqueConstraint(uc.ConstraintName,columns,uc.IsPrimaryKey);
-- targetTable.Constraints.Add(newConstraint);
-- }
-- }
-- else {
-- // FIXME : should we throw an exception ?
-- }
-- }
-- else {
-- ForeignKeyConstraint fc = (ForeignKeyConstraint)constraint;
-- // FIXME : add more precise condition (columns)
-- if (!targetTable.Constraints.Contains(fc.ConstraintName)) {
-- DataColumn[] columns = ResolveColumns(sourceSet,targetTable,fc.Columns);
-- DataTable relatedTable = targetSet.Tables[fc.RelatedTable.TableName];
-- DataColumn[] relatedColumns = ResolveColumns(sourceSet,relatedTable,fc.RelatedColumns);
-- if (columns != null && relatedColumns != null) {
-- ForeignKeyConstraint newConstraint = new ForeignKeyConstraint(fc.ConstraintName,relatedColumns,columns);
-- targetTable.Constraints.Add(newConstraint);
-- }
-- }
-- else {
-- // FIXME : should we throw an exception ?
-- }
-- }
-- }
++
++ bool dupConstraintFound = false;
++ foreach (Constraint cons in targetTable.Constraints) {
++ if (!targetConstraint.Equals (cons))
++ continue;
++ dupConstraintFound = true;
++ break;
}
++
++ // If equivalent-constraint already exists, then just do nothing
++ if (dupConstraintFound)
++ continue;
++
++ if (missingSchemaAction == MissingSchemaAction.Error)
++ throw new DataException ("Target DataSet missing " + targetConstraint.GetType () +
++ targetConstraint.ConstraintName);
++ else
++ targetTable.Constraints.Add (targetConstraint);
++ }
++ }
++
++ foreach (DataRelation relation in sourceSet.Relations) {
++ DataRelation targetRelation = targetSet.Relations [relation.RelationName];
++ if (targetRelation == null) {
++ if (missingSchemaAction == MissingSchemaAction.Error)
++ throw new ArgumentException ("Target DataSet mising definition for " +
++ relation.RelationName);
++
++ DataColumn[] parentColumns = ResolveColumns (targetSet, relation.ParentColumns);
++ DataColumn[] childColumns = ResolveColumns (targetSet, relation.ChildColumns);
++ targetRelation = targetSet.Relations.Add (relation.RelationName, parentColumns,
++ childColumns, false);
++ targetRelation.Nested = relation.Nested;
++ } else if (!CompareColumnArrays (relation.ParentColumns, targetRelation.ParentColumns) ||
++ !CompareColumnArrays (relation.ChildColumns, targetRelation.ChildColumns)) {
++ RaiseMergeFailedEvent (null, "Relation " + relation.RelationName +
++ " cannot be merged, because keys have mismatch columns.");
}
}
return true;
}
-- private static DataColumn[] ResolveColumns(DataSet targetSet,DataTable targetTable,DataColumn[] sourceColumns)
++ private static DataColumn[] ResolveColumns(DataSet targetSet, DataColumn[] sourceColumns)
{
if (sourceColumns != null && sourceColumns.Length > 0) {
-- // TODO : worth to check that all source colums come from the same table
++ // lets just assume that all columns are from the Same table
++ DataTable targetTable = targetSet.Tables [sourceColumns[0].Table.TableName];
if (targetTable != null) {
int i=0;
DataColumn[] targetColumns = new DataColumn[sourceColumns.Length];
++
++ DataColumn tmpCol ;
foreach(DataColumn sourceColumn in sourceColumns) {
-- targetColumns[i++] = targetTable.Columns[sourceColumn.ColumnName];
++ tmpCol = targetTable.Columns[sourceColumn.ColumnName];
++ if (tmpCol == null)
++ throw new DataException ("Column " + sourceColumn.ColumnName +
++ " does not belong to table " + targetTable.TableName);
++ targetColumns [i++] = tmpCol;
}
return targetColumns;
}
return null;
}
--
++
// adjust the table schema according to the missingschemaaction param.
// return false if adjusting fails.
private static bool AdjustSchema(DataSet targetSet, DataTable sourceTable, MissingSchemaAction missingSchemaAction, ref DataTable newTable)
{
-- string tableName = sourceTable.TableName;
--
// if the source table not exists in the target dataset
// we act according to the missingschemaaction param.
-- int tmp = targetSet.Tables.IndexOf(tableName);
-- // we need to check if it is equals names
-- if (tmp != -1 && !targetSet.Tables[tmp].TableName.Equals(tableName))
-- tmp = -1;
-- if (tmp == -1) {
-- if (missingSchemaAction == MissingSchemaAction.Ignore) {
++ DataTable targetTable = targetSet.Tables [sourceTable.TableName];
++ if (targetTable == null) {
++ if (missingSchemaAction == MissingSchemaAction.Ignore)
return true;
-- }
-- if (missingSchemaAction == MissingSchemaAction.Error) {
-- throw new ArgumentException("Target DataSet missing definition for "+ tableName + ".");
-- }
--
-- DataTable cloneTable = (DataTable)sourceTable.Clone();
-- targetSet.Tables.Add(cloneTable);
-- tableName = cloneTable.TableName;
-- }
--
-- DataTable table = targetSet.Tables[tableName];
--
++
++ if (missingSchemaAction == MissingSchemaAction.Error)
++ throw new ArgumentException ("Target DataSet missing definition for " +
++ sourceTable.TableName + ".");
++
++ targetTable = (DataTable)sourceTable.Clone();
++ targetSet.Tables.Add(targetTable);
++ }
++
for (int i = 0; i < sourceTable.Columns.Count; i++) {
DataColumn sourceColumn = sourceTable.Columns[i];
// if a column from the source table doesn't exists in the target table
// we act according to the missingschemaaction param.
-- DataColumn targetColumn = table.Columns[sourceColumn.ColumnName];
++ DataColumn targetColumn = targetTable.Columns [sourceColumn.ColumnName];
if(targetColumn == null) {
-- if (missingSchemaAction == MissingSchemaAction.Ignore) {
++ if (missingSchemaAction == MissingSchemaAction.Ignore)
continue;
-- }
-- if (missingSchemaAction == MissingSchemaAction.Error) {
-- throw new ArgumentException(("Column '" + sourceColumn.ColumnName + "' does not belong to table Items."));
-- }
++ if (missingSchemaAction == MissingSchemaAction.Error)
++ throw new DataException ("Target table " + targetTable.TableName +
++ " missing definition for column " + sourceColumn.ColumnName);
-- targetColumn = new DataColumn(sourceColumn.ColumnName, sourceColumn.DataType, sourceColumn.Expression, sourceColumn.ColumnMapping);
-- table.Columns.Add(targetColumn);
-- }
--
-- if (sourceColumn.Unique) {
-- try {
-- targetColumn.Unique = sourceColumn.Unique;
-- }
-- catch(Exception e){
--// Console.WriteLine("targetColumn : {0} targetTable : {1} ",targetColumn.ColumnName,table.TableName);
-- foreach(DataRow row in table.Rows) {
--// Console.WriteLine(row[targetColumn]);
-- }
-- throw e;
-- }
++ targetColumn = new DataColumn(sourceColumn.ColumnName, sourceColumn.DataType,
++ sourceColumn.Expression, sourceColumn.ColumnMapping);
++ targetTable.Columns.Add(targetColumn);
}
if(sourceColumn.AutoIncrement) {
}
}
-- if (!AdjustPrimaryKeys(table, sourceTable)) {
++ if (!AdjustPrimaryKeys(targetTable, sourceTable))
return false;
-- }
-- newTable = table;
++ newTable = targetTable;
return true;
}
--
++
++
// find if there is a valid matching between the targetTable PrimaryKey and the
// sourceTable primatyKey.
// return true if there is a match, else return false and raise a MergeFailedEvent.
private static bool AdjustPrimaryKeys(DataTable targetTable, DataTable sourceTable)
{
-- // if the length of one of the tables primarykey if 0 - there is nothing to check.
-- if (sourceTable.PrimaryKey.Length != 0) {
-- if (targetTable.PrimaryKey.Length == 0) {
-- // if target table has no primary key at all -
-- // import primary key from source table
-- DataColumn[] targetColumns = new DataColumn[sourceTable.PrimaryKey.Length];
--
-- for(int i=0; i < sourceTable.PrimaryKey.Length; i++){
-- DataColumn sourceColumn = sourceTable.PrimaryKey[i];
-- DataColumn targetColumn = targetTable.Columns[sourceColumn.ColumnName];
--
-- if (targetColumn == null) {
-- // is target table has no column corresponding
-- // to source table PK column - merge fails
-- string message = "Column " + sourceColumn.ColumnName + " does not belongs to table " + targetTable.TableName;
-- MergeFailedEventArgs e = new MergeFailedEventArgs(sourceTable, message);
-- targetTable.DataSet.OnMergeFailed(e);
-- return false;
-- }
-- else {
-- targetColumns[i] = targetColumn;
-- }
-- }
-- targetTable.PrimaryKey = targetColumns;
-- }
-- else {
-- // if target table already has primary key and
-- // if the length of primarykey is not equal - merge fails
-- if (targetTable.PrimaryKey.Length != sourceTable.PrimaryKey.Length) {
-- string message = "<target>.PrimaryKey and <source>.PrimaryKey have different Length.";
-- MergeFailedEventArgs e = new MergeFailedEventArgs(sourceTable, message);
-- targetTable.DataSet.OnMergeFailed(e);
-- return false;
-- }
-- else {
-- // we have to see that each primary column in the target table
-- // has a column with the same name in the sourcetable primarykey columns.
-- bool foundMatch;
-- DataColumn[] targetDataColumns = targetTable.PrimaryKey;
-- DataColumn[] srcDataColumns = sourceTable.PrimaryKey;
--
-- // loop on all primary key columns in the targetTable.
-- for (int i = 0; i < targetDataColumns.Length; i++) {
-- foundMatch = false;
-- DataColumn col = targetDataColumns[i];
--
-- // find if there is a column with the same name in the
-- // sourceTable primary key columns.
-- for (int j = 0; j < srcDataColumns.Length; j++) {
-- if (srcDataColumns[j].ColumnName == col.ColumnName) {
-- foundMatch = true;
-- break;
-- }
-- }
-- if (!foundMatch) {
-- string message = "Mismatch columns in the PrimaryKey : <target>." + col.ColumnName + " versus <source>." + srcDataColumns[i].ColumnName + ".";
-- MergeFailedEventArgs e = new MergeFailedEventArgs(sourceTable, message);
-- targetTable.DataSet.OnMergeFailed(e);
-- return false;
-- }
--
-- }
-- }
-- }
++ if (sourceTable.PrimaryKey.Length == 0)
++ return true;
++
++ // If targetTable does not have a PrimaryKey, just import the sourceTable PrimaryKey
++ if (targetTable.PrimaryKey.Length == 0) {
++ DataColumn[] targetColumns = ResolveColumns (targetTable.DataSet, sourceTable.PrimaryKey);
++ targetTable.PrimaryKey = targetColumns;
++ return true;
++ }
++
++ // If both the tables have a primary key, verify that they are equivalent.
++ // raise a MergeFailedEvent if the keys are not equivalent
++ if (targetTable.PrimaryKey.Length != sourceTable.PrimaryKey.Length) {
++ RaiseMergeFailedEvent (targetTable, "<target>.PrimaryKey and <source>.PrimaryKey have different Length.");
++ return false;
}
++ for (int i=0; i < targetTable.PrimaryKey.Length; ++i) {
++ if (targetTable.PrimaryKey [i].ColumnName.Equals (sourceTable.PrimaryKey [i].ColumnName))
++ continue;
++ RaiseMergeFailedEvent (targetTable, "Mismatch columns in the PrimaryKey : <target>." +
++ targetTable.PrimaryKey [i].ColumnName + " versus <source>." + sourceTable.PrimaryKey [i].ColumnName);
++ return false;
++ }
return true;
}
--
++
// fill the data from the source table to the target table
private static void fillData(DataTable targetTable, DataTable sourceTable, bool preserveChanges)
{
MergeRow(targetTable, row, preserveChanges);
}
}
--
++
// check tha column from 2 tables that has the same name also has the same datatype.
private static void checkColumnTypes(DataTable targetTable, DataTable sourceTable)
{
DataColumn fromCol = sourceTable.Columns[i];
DataColumn toCol = targetTable.Columns[fromCol.ColumnName];
if((toCol != null) && (toCol.DataType != fromCol.DataType))
-- throw new DataException("<target>." + fromCol.ColumnName + " and <source>." + fromCol.ColumnName + " have conflicting properties: DataType property mismatch.");
++ throw new DataException("<target>." + fromCol.ColumnName + " and <source>." +
++ fromCol.ColumnName + " have conflicting properties: DataType " +
++ " property mismatch.");
}
}
++
++ private static bool CompareColumnArrays (DataColumn[] arr1, DataColumn[] arr2)
++ {
++ if (arr1.Length != arr2.Length)
++ return false;
++
++ for (int i=0; i < arr1.Length; ++i)
++ if (!arr1 [i].ColumnName.Equals (arr2 [i].ColumnName))
++ return false;
++ return true;
++ }
++
++ private static void RaiseMergeFailedEvent (DataTable targetTable, string errMsg)
++ {
++ MergeFailedEventArgs args = new MergeFailedEventArgs (targetTable, errMsg);
++ targetTable.DataSet.OnMergeFailed (args);
++ }
}
}
++2006-03-20 Senganal T <tsenganal@novell.com>
++
++ * DataSetTest2.cs
++ - Added testcases for issues in Merge,Copy
++ * ConstraintCollectionTest2.cs
++ - Added testcases for issues in Add , IndexOf
++
+ 2006-03-19 Boris Kirzner <borisk@mainsoft.com>
+
+ * ConstraintCollectionTest2.cs, DataColumnCollectionTest.cs,
+ DataRowCollectionTest.cs, DataTableCollectionTest.cs: ifdef code that is not
+ supposed to work in TARGET_JVM by now.
+
+ 2006-03-09 Senganal T <tsenganal@novell.com>
+
+ * DataRowCollectionTest2.cs :
+ * DataTableTest2.cs :
+ - Fixed NotWorking tests.
+
+ 2006-03-07 Senganal T <tsenganal@novell.com>
+
+ * DataRowCollectionTest2.cs :
+ * DataTableTest2.cs :
+ - Added failing testcases as NotWorking tests.
+
+ 2006-03-05 Senganal T <tsenganal@novell.com>
+
+ * DataSetTest2.cs
+ * ConstraintCollectionTest2.cs
+ * DataViewTest.cs
+ * DataRelationTest.cs
+ Added testcases for BeginInit and EndInit methods
+
+ 2006-02-24 Senganal T <tsenganal@novell.com>
+
+ * ConstraintCollectionTest2.cs : added testcase for #77630
+
+ 2006-02-22 Senganal T <tsenganal@novell.com>
+
+ * DataRowCollectionTest2.cs : Check if index is maintained for row on calling RejectChanges.
+ * DataTableTest2.cs : Check if data is loaded and merged (if key exists) correctly.
+ * ForeignKeyConstraintTest.cs : Check if a ParentColumn value can be modified
+ when the row is in 'Added' State. Also, check if child col values are
+ updated correctly.
+
+ 2006-02-16 Senganal T <tsenganal@novell.com>
+
+ * DataSetTest2.cs :
+ - WriteXmlSchema_ForeignKeyConstraint : testcase for bug #77557
+ - WriteXmlSchema_RelationAnnotation :
+ - WriteXmlSchema_Relations_ForeignKeys :
+ ensure Relations and ForeignKeyConstraints are written and read correctly.
+ * DataSetReadXmlSchema.cs :
+ - ReadConstraints :
+ verify reading a foreignkeyconstraint doesent create a relation.
+ - ReadAnnotatedRelations_MultipleColumns :
+ verify multiple columns are read correctly if part of annotated relation.
+
+ 2006-02-11 Senganal T <tsenganal@novell.com>
+
+ * DataTableTest.cs : Check AllowDBNull is set to false for PrimaryKey cols.
+ * DataTableTest2.cs : added testcases for bug #77404
+
+ 2006-02-03 Senganal T <tsenganal@novell.com>
+
+ * DataTableCollectionTest2.cs,EvaluateExceptionTest.cs,
+ DataColumnTest.cs,DataRowViewTest.cs,DataRowCollectionTest2.cs,
+ DataTableTest2.cs,DataTableTest.cs,DataColumnCollectionTest2.cs,
+ DataColumnCollectionTest.cs,DataViewTest.cs,DataColumnTest2.cs
+ - Removed 'NotWorking' attributes for the testcases fixed
+ - Added few new testcases
+
+ 2006-01-17 Senganal T <tsenganal@novell.com>
+
+ * DataRowTest2.cs : added testcase for bug #77267
+
+ 2006-01-16 Boris Kirzner <borisk@mainsoft.com>
+ * DataColumnCollectionTest2.cs: added test case for index update on
+ column removal
+
+ 2006-01-16 Atsushi Enomoto <atsushi@ximian.com>
+
+ * TypedDataSetGeneratorTest.cs : added test for bug #77248, but we
+ cannot enable it since it depends on mcs "installed".
+
+ 2006-01-10 Senganal T <tsenganal@novell.com>
+ * DataViewTest2.cs
+ - Added testcase for bug #77188
+
+ 2006-01-06 Senganal T <tsenganal@novell.com>
+ * DataColumnTest.cs
+ * DataColumnCollectionTest.cs
+ - Added couple of tests for Expression Columns.
+
+ 2006-01-03 Senganal T <tsenganal@novell.com>
+ * DataSetTypedDataSetTest.cs : corrected the path to file : TypedDataSet.xml
+ to make sure the testcases pass
+
+ 2006-01-03 Senganal T <tsenganal@novell.com>
+ *DataViewTest.cs : added testcases for bug #77104
+
+ 2006-01-02 Boris Kirzner <borisk@mainsoft.com>
+ * DataTableCollectionTest2.cs, DataColumnTest2.cs,
+ DataViewTest2.cs, DataRowCollectionTest2.cs, DataTableTest2.cs,
+ DataRelationCollectionTest2.cs, ForeignKeyConstraintTest2.cs,
+ DataSetTest2.cs, ConstraintCollectionTest2.cs, DataRowTest2.cs,
+ DataColumnCollectionTest2.cs: new tests from Mainsoft repository.
+ * DataSetTypedDataSetTest.cs, VersionNotFoundException.cs,
+ MissingPrimaryKeyExceptionTest.cs: added files with new tests.
+ * TypedDataSet.xml - new xml file (for TypeDataSetTest.cs).
+
+ 2005-12-20 Senganal T <tsenganal@novell.com>
+ * DataColumnTest.cs : added testcase for #77025
+
+ 2005-12-15 Konstantin Triger <kostat@mainsoft.com>
+
+ * DataTableTest.cs: added SelectRowState test.
+
+ 2005-12-07 Boris Kirzner <borisk@mainsoft.com>
+ * DataTableTest.cs: added ifdef for feature not supported in TARGET_JVM.
+
2005-11-30 Konstantin Triger <kostat@mainsoft.com>
* DataColumnTest.cs: Added ExpressionSubstringlimits.
}
++ [Test] public void IndexOf_SameColumns ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++ DataColumn pcol = table1.Columns.Add ("col1");
++ DataColumn ccol = table2.Columns.Add ("col1");
++
++ ds.Relations.Add ("fk_rel", pcol, ccol);
++
++ ForeignKeyConstraint fk = new ForeignKeyConstraint ("fk", pcol, ccol);
++ Assert.AreEqual (-1, ds.Tables [1].Constraints.IndexOf (fk), "#1");
++ }
++
++ [Test]
++ public void Add_RelationFirst_ConstraintNext()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++ DataColumn pcol = table1.Columns.Add ("col1");
++ DataColumn ccol = table2.Columns.Add ("col1");
++
++ ds.Relations.Add ("fk_rel", pcol, ccol);
++
++ try {
++ table2.Constraints.Add ("fk_cons", pcol, ccol);
++ Assert.Fail ("#1 Cannot add duplicate fk constraint");
++ }catch (DataException e) {
++ }
++
++ try {
++ table1.Constraints.Add ("pk_cons", pcol, false);
++ Assert.Fail ("#2 Cannot add duplicate unique constraint");
++ }catch (DataException e) {
++ }
++ }
++
++ [Test]
++ public void Add_ConstraintFirst_RelationNext ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++ DataColumn pcol = table1.Columns.Add ("col1");
++ DataColumn ccol = table2.Columns.Add ("col1");
++
++ table2.Constraints.Add ("fk_cons", pcol, ccol);
++
++ // Should not throw DataException
++ ds.Relations.Add ("fk_rel", pcol, ccol);
++
++ Assert.AreEqual (1, table2.Constraints.Count, "#1 duplicate constraint shudnt be added");
++ Assert.AreEqual (1, table1.Constraints.Count, "#2 duplicate constraint shudnt be added");
++ Assert.AreEqual ("fk_cons", table2.Constraints [0].ConstraintName, "#3 shouldnt be overwritten");
++ Assert.AreEqual ("Constraint1", table1.Constraints [0].ConstraintName, "#4 shouldnt be overwritten");
++ }
++
[Test] public void IsReadOnly()
{
DataTable dt = DataProvider.CreateUniqueConstraint();
CompareResults_2("merge 3",ds,dsTarget1);
}
++ [Test]
++ public void Merge_RelationWithoutConstraints ()
++ {
++ DataSet ds = new DataSet ();
++
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn ccol = table2.Columns.Add ("col1", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++ DataRelation rel = ds1.Relations.Add ("rel1", ds1.Tables[0].Columns[0],
++ ds1.Tables [1].Columns [0], false);
++
++ ds.Merge (ds1);
++ Assert.AreEqual (1, ds.Relations.Count , "#1");
++ Assert.AreEqual (0, ds.Tables [0].Constraints.Count , "#2");
++ Assert.AreEqual (0, ds.Tables [1].Constraints.Count , "#2");
++ }
++
++ [Test]
++ public void Merge_DuplicateConstraints ()
++ {
++ DataSet ds = new DataSet ();
++
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn ccol = table2.Columns.Add ("col1", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++
++ DataRelation rel = ds.Relations.Add ("rel1", pcol, ccol);
++
++ ds1.Tables [1].Constraints.Add ("fk", ds1.Tables [0].Columns [0], ds1.Tables [1].Columns [0]);
++
++ // No Exceptions shud be thrown
++ ds.Merge (ds1);
++ Assert.AreEqual (1, table2.Constraints.Count, "#1 Constraints shudnt be duplicated");
++ }
++
++ [Test]
++ public void Merge_DuplicateConstraints_1 ()
++ {
++ DataSet ds = new DataSet ();
++
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn ccol = table2.Columns.Add ("col1", typeof (int));
++ DataColumn pcol1 = table1.Columns.Add ("col2", typeof (int));
++ DataColumn ccol1 = table2.Columns.Add ("col2", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++
++ table2.Constraints.Add ("fk", pcol, ccol);
++ ds1.Tables [1].Constraints.Add ("fk", ds1.Tables [0].Columns ["col2"], ds1.Tables [1].Columns ["col2"]);
++
++ // No Exceptions shud be thrown
++ ds.Merge (ds1);
++ Assert.AreEqual (2, table2.Constraints.Count, "#1 fk constraint shud be merged");
++ Assert.AreEqual ("Constraint1", table2.Constraints [1].ConstraintName, "#2 constraint name shud be changed");
++ }
++
++ [Test]
++ public void CopyClone_RelationWithoutConstraints ()
++ {
++ DataSet ds = new DataSet ();
++
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn ccol = table2.Columns.Add ("col1", typeof (int));
++
++ DataRelation rel = ds.Relations.Add ("rel1", pcol, ccol, false);
++
++ DataSet ds1 = ds.Copy ();
++ DataSet ds2 = ds.Clone ();
++
++ Assert.AreEqual (1, ds1.Relations.Count, "#1");
++ Assert.AreEqual (1, ds2.Relations.Count, "#2");
++
++ Assert.AreEqual (0, ds1.Tables [0].Constraints.Count, "#3");
++ Assert.AreEqual (0, ds1.Tables [1].Constraints.Count, "#4");
++
++ Assert.AreEqual (0, ds2.Tables [0].Constraints.Count, "#5");
++ Assert.AreEqual (0, ds2.Tables [1].Constraints.Count, "#6");
++ }
++
++ [Test]
++ [ExpectedException (typeof (DataException))]
++ public void Merge_MissingEventHandler ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn pcol1 = table1.Columns.Add ("col2", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++ table1.PrimaryKey = new DataColumn[] {pcol};
++ ds1.Tables [0].PrimaryKey = new DataColumn[] {ds1.Tables [0].Columns [1]};
++
++ // Exception shud be raised when handler is not set for MergeFailed Event
++ ds1.Merge (ds);
++ }
++
++ [Test]
++ [ExpectedException (typeof(DataException))]
++ public void Merge_MissingColumn ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++
++ table1.Columns.Add ("col1", typeof (int));
++ table2.Columns.Add ("col1", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++
++ ds1.Tables [0].Columns.Add ("col2");
++
++ ds.Merge (ds1, true, MissingSchemaAction.Error);
++ }
++
++ [Test]
++ public void Merge_MissingConstraint ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++ table1.Columns.Add ("col1", typeof (int));
++ table2.Columns.Add ("col1", typeof (int));
++
++ try {
++ DataSet ds1 = ds.Copy ();
++ DataSet ds2 = ds.Copy ();
++ ds2.Tables [0].Constraints.Add ("uc", ds2.Tables [0].Columns [0], false);
++ ds1.Merge (ds2, true, MissingSchemaAction.Error);
++ Assert.Fail ("#1 If uniqueconstraint is missing, exception shud be thrown");
++ }catch (DataException e) {
++ }
++
++ try {
++ DataSet ds1 = ds.Copy ();
++ DataSet ds2 = ds.Copy ();
++ ds2.Tables [0].Constraints.Add ("fk", ds2.Tables [0].Columns [0], ds2.Tables[1].Columns [0]);
++ ds1.Tables [0].Constraints.Add ("uc", ds1.Tables [0].Columns [0],false);
++ ds1.Merge (ds2, true, MissingSchemaAction.Error);
++ Assert.Fail ("#2 If foreignkeyconstraint is missing, exception shud be thrown");
++ }catch (DataException e) {
++ }
++
++ try {
++ DataSet ds1 = ds.Copy ();
++ DataSet ds2 = ds.Copy ();
++ ds2.Relations.Add ("rel", ds2.Tables [0].Columns [0], ds2.Tables[1].Columns [0], false);
++ ds1.Merge (ds2, true, MissingSchemaAction.Error);
++ Assert.Fail ("#2 If datarelation is missing, exception shud be thrown");
++ }catch (ArgumentException e) {
++ }
++ }
++
++ [Test]
++ [ExpectedException (typeof (DataException))]
++ public void Merge_PrimaryKeys_IncorrectOrder ()
++ {
++ DataSet ds = new DataSet ();
++ DataTable table1 = ds.Tables.Add ("table1");
++ DataTable table2 = ds.Tables.Add ("table2");
++ DataColumn pcol = table1.Columns.Add ("col1", typeof (int));
++ DataColumn pcol1 = table1.Columns.Add ("col2", typeof (int));
++ DataColumn ccol = table2.Columns.Add ("col1", typeof (int));
++
++ DataSet ds1 = ds.Copy ();
++ table1.PrimaryKey = new DataColumn[] {pcol,pcol1};
++ ds1.Tables [0].PrimaryKey = new DataColumn [] {ds1.Tables[0].Columns [1], ds1.Tables [0].Columns [0]};
++
++ // Though the key columns are the same, if the order is incorrect
++ // Exception must be raised
++ ds1.Merge (ds);
++ }
++
void CompareResults_1(string Msg,DataSet ds, DataSet dsTarget)
{
// check Parent Primary key length