Click here to Skip to main content
15,886,258 members
Articles / Database Development / SQL Server

Database Helper Class Library to Ease Database Operation

Rate me:
Please Sign up or sign in to vote.
3.09/5 (9 votes)
14 Apr 2007CPOL4 min read 87.5K   3K   57  
Database Helper Class Library to Ease Database Operation
///////////////////////////////////////////////////////////////////////////
// Copyright 2003-2005 Falcon Soon
//
// Author: Soon Chun Boon
// Date: 21 September 2004
// Description: 
// Class that represents primary keys or foreign keys in data relationship.
///////////////////////////////////////////////////////////////////////////

using System;
using System.Data;

namespace DBHelper
{
	/// <summary>
	/// Class that represents primary keys or foreign keys.
	/// </summary>
	internal class DBKey
	{
        #region Class Member Declarations
        internal const int COLUMN = 65535;
        internal const int DESCENDING = -2147483648;
        internal const int MAX_COLUMNS = 32;
 
        internal DataColumn[] macolKey;
        internal bool mbExplicitKey;
        internal int miSortOrder;
        #endregion

        /// <summary>
        /// Initialize a new instance of <see cref="DBHelper.DBKey"/> class with the specified
        /// data columns.
        /// </summary>
        /// <param name="acol">An array of <see cref="System.Data.DataColumn"/> which forms 
        /// the database key.</param>
        /// <exception cref="System.ArgumentNullException">
        /// Bad data columns are passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyNoColumns">
        /// Zero data column is passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyTooManyColumns">
        /// Total of passed in data columns is more than the maximum.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyDuplicateColumns">
        /// Duplicate data columns is passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeySortLength">
        /// Passed in sort order total is not same as data column total.
        /// </exception>
        /// <exception cref="DBHelper.DataException.ColumnNotInAnyTable">
        /// A <see cref="System.Data.DataColumn"/> is not belonging to any 
        /// <see cref="System.Data.DataTable"/>.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyTableMismatch">
        /// <see cref="System.Data.DataTable"/> for every <see cref="System.Data.DataColumn"/>
        /// is not same.
        /// </exception>
		public DBKey(DataColumn[] acol)
		{
			this.Create(acol, null);
		}

        /// <summary>
        /// Check whether every column in key belong to same table.
        /// </summary>
        /// <exception cref="DBHelper.DataException.ColumnNotInAnyTable">
        /// A <see cref="System.Data.DataColumn"/> is not belonging to any 
        /// <see cref="System.Data.DataTable"/>.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyTableMismatch">
        /// <see cref="System.Data.DataTable"/> for every <see cref="System.Data.DataColumn"/>
        /// is not same.
        /// </exception>
        internal void CheckState()
        {
            DataTable tblKey = this.macolKey[0].Table;
            if (tblKey == null)
            {
                throw new DataException.ColumnNotInAnyTable();
            }
            for (int iIndex = 1; (iIndex < this.macolKey.Length); iIndex++)
            {
                if (this.macolKey[iIndex].Table == null)
                {
                    throw new DataException.ColumnNotInAnyTable();
                }
                if (this.macolKey[iIndex].Table != tblKey)
                {
                    throw new DataException.KeyTableMismatch();
                }
            }
        }

        /// <summary>
        /// Create a new database key.
        /// </summary>
        /// <param name="acol">An array of <see cref="System.Data.DataColumn"/> which 
        /// represent the database key.</param>
        /// <param name="aiSortOrders">An array of integer which represent each column's
        /// sort order.</param>
        /// <exception cref="System.ArgumentNullException">
        /// Bad data columns are passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyNoColumns">
        /// Zero data column is passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyTooManyColumns">
        /// Total of passed in data columns is more than the maximum.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyDuplicateColumns">
        /// Duplicate data columns is passed.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeySortLength">
        /// Passed in sort order total is not same as data column total.
        /// </exception>
        /// <exception cref="DBHelper.DataException.ColumnNotInAnyTable">
        /// A <see cref="System.Data.DataColumn"/> is not belonging to any 
        /// <see cref="System.Data.DataTable"/>.
        /// </exception>
        /// <exception cref="DBHelper.DataException.KeyTableMismatch">
        /// <see cref="System.Data.DataTable"/> for every <see cref="System.Data.DataColumn"/>
        /// is not same.
        /// </exception>
        private void Create(DataColumn[] acol, int[] aiSortOrders)
        {
            this.mbExplicitKey = false;
            if (acol == null)
            {
                throw new ArgumentNullException("acol");
            }
            if (acol.Length == 0)
            {
                throw new DataException.KeyNoColumns();
            }
            if (acol.Length > MAX_COLUMNS)
            {
                throw new DataException.KeyTooManyColumns(MAX_COLUMNS);
            }
            for (int iIndex = 0; (iIndex < acol.Length); iIndex++)
            {
                if (acol[iIndex] == null)
                {
                    throw new ArgumentNullException("acol");
                }
            }
            for (int iIndex = 0; (iIndex < acol.Length); iIndex++)
            {
                for (int iIndex2 = 0; (iIndex2 < iIndex); iIndex2++)
                {
                    if (acol[iIndex] == acol[iIndex2])
                    {
                        throw new DataException.KeyDuplicateColumns(acol[iIndex].ColumnName);
                    }
                }
            }
            if ((aiSortOrders != null) && (aiSortOrders.Length != acol.Length))
            {
                throw new DataException.KeySortLength();
            }
            this.miSortOrder = 0;
            if (aiSortOrders != null)
            {
                for (int iIndex = 0; (iIndex < aiSortOrders.Length); iIndex++)
                {
                    this.miSortOrder |= ((aiSortOrders[iIndex] & 1) << (iIndex & 31));
                }
            }
            this.macolKey = new DataColumn[acol.Length];
            for (int iIndex = 0; (iIndex < acol.Length); iIndex++)
            {
                this.macolKey[iIndex] = acol[iIndex];
            }
            this.CheckState();
        }

        #region Equality and Hash Code Methods
        /// <summary>
        /// Compare the equality of the specified DBKey instance with this DBKey instance.
        /// </summary>
        /// <param name="objKey">The DBKey instance to compare.</param>
        /// <returns>True if the compared DBKey instance is equal with this DBKey instance,
        /// otherwise return False.</returns>
        public virtual bool ColumnsEqual(DBKey objKey)
        {
            int iIndexMain;
            int iIndexCompare;
            DataColumn[] acolMainKey = this.Columns;
            DataColumn[] acolCompareKey = objKey.Columns;
            if (acolMainKey == acolCompareKey)
            {
                return (true);
            }
            if ((acolMainKey == null) || (acolCompareKey == null))
            {
                return (false);
            }
            if (acolMainKey.Length != acolCompareKey.Length)
            {
                return (false);
            }
            for (iIndexMain = 0; (iIndexMain < acolMainKey.Length); iIndexMain++)
            {
                iIndexCompare = 0;
                while ((iIndexCompare < acolCompareKey.Length))
                {
                    if (acolMainKey[iIndexMain].Equals(acolCompareKey[iIndexCompare]))
                    {
                        break;
                    }
                    ++iIndexCompare;
                }
                if (iIndexCompare == acolCompareKey.Length)
                {
                    return (false);
                }
            }
            return (true);
        }

        /// <summary>
        /// Checks whether the specified DataColumn instance is in the database key.
        /// </summary>
        /// <param name="col">The DataColumn instance to be checked.</param>
        /// <returns>True if the DataColumn instance is in the key otherwise return False.</returns>
        public virtual bool ContainsColumn(DataColumn col)
        {
            for (int iIndex = 0; (iIndex < this.macolKey.Length); iIndex++)
            {
                if (col == this.macolKey[iIndex])
                {
                    return (true);
                }
            }
            return (false);
        }

        /// <summary>
        /// Checks the equality of the compared <see cref="DBHelper.DBKey"/> instance 
        /// with this <see cref="DBHelper.DBKey"/> instance.
        /// </summary>
        /// <param name="objCompareKey">The <see cref="DBHelper.DBKey"/> instance to be compared.</param>
        /// <returns>True if the compared <see cref="DBHelper.DBKey"/> instance is same with this 
        /// <see cref="DBHelper.DBKey"/> instance otherwise return False.</returns>
        public override bool Equals(object objCompareKey)
        {
            if (!(objCompareKey is DBKey))
            {
                return (false);
            }
            bool bFlag = false;
            DataColumn[] acolMain = this.Columns;
            DataColumn[] acolCompare = ((DBKey) objCompareKey).Columns;
            if (acolMain == acolCompare)
            {
                return (true);
            }
            if ((acolMain == null) || (acolCompare == null))
            {
                return (false);
            }
            if (acolMain.Length != acolCompare.Length)
            {
                return (false);
            }
            bFlag = true;
            for (int iIndex = 0; (iIndex < acolMain.Length); iIndex++)
            {
                if (!acolMain[iIndex].Equals(acolCompare[iIndex]))
                {
                    return (false);
                }
            }
            return (bFlag);
        }

        /// <summary>
        /// Gets the debug string of this <see cref="DBHelper.DBKey"/> instance.
        /// </summary>
        /// <returns>Return a string consists of every key's column with its sort order.</returns>
        public string GetDebugString()
        {
            int[] aiSortOrder = this.SortOrder;

            string strText = "{key: ";
            for (int iIndex = 0; (iIndex < this.macolKey.Length); iIndex++)
            {
                strText = strText + this.macolKey[iIndex].ColumnName + ((aiSortOrder[iIndex] == 1) ? " DESC" : "") + ((iIndex < (this.macolKey.Length - 1)) ? ", " : string.Empty);
            }
            return strText + "}";
        }

        /// <summary>
        /// Gets the hash code of this <see cref="DBHelper.DBKey"/> instance.
        /// </summary>
        /// <returns>The hash code of this DBKey instance.</returns>
        public override int GetHashCode()
        {
            int iHashCode = 0;
            DataColumn[] acol = this.Columns;
            if (acol == null)
            {
                return (iHashCode);
            }
            int iHashLength = ((acol.Length <= 2) ? acol.Length : 2);
            for (int iIndex = 0; (iIndex < iHashLength); iIndex++)
            {
                iHashCode += acol[iIndex].GetHashCode();
            }
            return (iHashCode);
        }
        #endregion

//        /// <summary>
//        /// Return the index description in an array of integer.
//        /// </summary>
//        /// <returns>The index description in an array of integer.</returns>
//        internal virtual int[] GetIndexDesc()
//        {
//            int[] aiIndex = new int[this.macolKey.Length];
//            int iSortOrder = this.miSortOrder;
//            for (int iIndex = 0; (iIndex < this.macolKey.Length); iIndex++)
//            {
//                aiIndex[iIndex] = (this.macolKey[iIndex].Ordinal | (iSortOrder << 31));
//                iSortOrder = (iSortOrder >> 1);
//            }
//            return (aiIndex);
//        }

//        internal virtual Index GetSortIndex()
//        {
//            return (this.GetSortIndex(DataViewRowState.CurrentRows));
//        }

//        internal virtual Index GetSortIndex(DataViewRowState enuRecordStates)
//        {
//            return (this.macolKey[0].Table.GetIndex(this.GetIndexDesc(), enuRecordStates, null));
//        }

//        public virtual bool RecordsEqual(int iRecord1, int iRecord2)
//        {
//            for (int iIndex = 0; (iIndex < this.macolKey.Length); iIndex++)
//            {
//                if (this.macolKey[iIndex].Compare(iRecord1, iRecord2) != 0)
//                {
//                    return (false);
//                }
//            }
//            return (true);
//        }

//        internal static bool SortDecending(int iIndexDesc)
//        {
//            return ((iIndexDesc & -2147483648) != 0);
//        }

//        internal static int ColumnOrder(int iIndexDesc)
//        {
//            return (iIndexDesc & 65535);
//        }

        #region Class Property Declarations
        /// <summary>
        /// Returns an array of <see cref="System.Data.DataColumn"/> that forms
        /// the database keys.
        /// </summary>
        public virtual DataColumn[] Columns
        {
            get
            {
                return this.macolKey;
            }
        }

        /// <summary>
        /// Return an array of integer which specifies the sort order for every data column.
        /// </summary>
        /// <remarks>
        /// 1 is descending otherwise 0 is ascending.
        /// </remarks>
        public virtual int[] SortOrder
        {
            get
            {
                int iSortOrder = this.miSortOrder;
                int[] aiSortOrder = new int[this.macolKey.Length];
                for (int iIndex = 0; (iIndex < this.macolKey.Length); iIndex++)
                {
                    aiSortOrder[iIndex] = (iSortOrder & 1);
                    iSortOrder = (iSortOrder >> 1);
                }
                return (aiSortOrder);
            }
        }

        /// <summary>
        /// Return <see cref="System.Data.DataTable"/> of the database keys.
        /// </summary>
        public virtual DataTable Table
        {
            get
            {
                return (this.macolKey[0].Table);
            }
        }

        #endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Malaysia Malaysia
Had worked as analyst programmer for 4 years. Now helping in family business but still involved actively in .Net development whenever there is a free time.

Comments and Discussions