// // System.Data.Constraint.cs // // Author: // Franklin Wise // Daniel Morgan // Tim Coleman (tim@timcoleman.com) // // // (C) Ximian, Inc. 2002 // Copyright (C) Tim Coleman, 2002 // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.ComponentModel; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Data.Common; namespace System.Data { [Serializable] internal delegate void DelegateConstraintNameChange (object sender, string newName); [DefaultProperty ("ConstraintName")] #if !NET_2_0 [Serializable] #endif [TypeConverterAttribute (typeof (ConstraintConverter))] public abstract class Constraint { internal event DelegateConstraintNameChange BeforeConstraintNameChange; //if constraintName is not set then a name is //created when it is added to //the ConstraintCollection //it can not be set to null, empty or duplicate //once it has been added to the collection private string _constraintName; private PropertyCollection _properties; private Index _index; //Used for membership checking private ConstraintCollection _constraintCollection; DataSet dataSet; protected Constraint () { dataSet = null; _properties = new PropertyCollection(); } [CLSCompliant (false)] protected internal virtual DataSet _DataSet { get { return dataSet; } } [DataCategory ("Data")] #if !NET_2_0 [DataSysDescription ("Indicates the name of this constraint.")] #endif [DefaultValue ("")] public virtual string ConstraintName { get{ return _constraintName == null ? "" : _constraintName; } set{ //This should only throw an exception when it //is a member of a ConstraintCollection which //means we should let the ConstraintCollection //handle exceptions when this value changes _onConstraintNameChange(value); _constraintName = value; } } [Browsable (false)] [DataCategory ("Data")] #if !NET_2_0 [DataSysDescription ("The collection that holds custom user information.")] #endif public PropertyCollection ExtendedProperties { get { return _properties; } #if NET_2_0 internal set { _properties = value; } #endif } #if !NET_2_0 [DataSysDescription ("Indicates the table of this constraint.")] #endif public abstract DataTable Table { get; } internal ConstraintCollection ConstraintCollection { get{ return _constraintCollection; } set{ _constraintCollection = value; } } private void _onConstraintNameChange (string newName) { if (null != BeforeConstraintNameChange) { BeforeConstraintNameChange (this, newName); } } //call once before adding a constraint to a collection //will throw an exception to prevent the add if a rule is broken internal abstract void AddToConstraintCollectionSetup (ConstraintCollection collection); internal abstract bool IsConstraintViolated (); internal static void ThrowConstraintException(){ throw new ConstraintException("Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."); } bool initInProgress = false; internal virtual bool InitInProgress { get { return initInProgress; } set { initInProgress = value; } } internal virtual void FinishInit (DataTable table) { } internal void AssertConstraint() { // The order is important.. IsConstraintViolated fills the RowErrors if it detects // a violation if (!IsConstraintViolated()) return; if (Table._duringDataLoad || (Table.DataSet != null && !Table.DataSet.EnforceConstraints)) return; ThrowConstraintException(); } internal abstract void AssertConstraint(DataRow row); internal virtual void RollbackAssert (DataRow row) { } //call once before removing a constraint to a collection //can throw an exception to prevent the removal internal abstract void RemoveFromConstraintCollectionCleanup (ConstraintCollection collection); [MonoTODO] protected void CheckStateForProperty () { throw new NotImplementedException (); } protected internal void SetDataSet (DataSet dataSet) { this.dataSet = dataSet; } internal Index Index { get { return _index; } set { if (_index != null) { _index.RemoveRef(); Table.DropIndex(_index); } _index = value; if (_index != null) { _index.AddRef(); } } } internal abstract bool IsColumnContained(DataColumn column); internal abstract bool CanRemoveFromCollection(ConstraintCollection col, bool shouldThrow); /// /// Gets the ConstraintName, if there is one, as a string. /// public override string ToString () { return _constraintName == null ? "" : _constraintName; } } }