Click here to Skip to main content
11,412,833 members (71,412 online)
Click here to Skip to main content
Add your own
alternative version

Database Helper Class Library to Ease Database Operation

, 14 Apr 2007 CPOL
Database Helper Class Library to Ease Database Operation
article_demo.zip
DBHelperQuickRelationshipSamples
DBHelperQuickRelationshipSamples
App.ico
DBHelperQuickRelationshipSamples.csproj.user
DBHelperQuickRelationshipSamples.suo
DBHelperQuickSelectSamples
DBHelperQuickSelectSamples
DBHelperQuickSelectSamples.csproj.user
DBHelperQuickSelectSamples.suo
DBHelperQuickHelperSamples
DBHelperQuickHelperSamples
App.ico
DBHelperQuickHelperSamples.csproj.user
DBHelperQuickHelperSamples.suo
DBHelperQuickInsUpdDelSamples
DBHelperQuickInsUpdDelSamples
DBHelperQuickInsUpdDelSamples.csproj.user
DBHelperQuickInsUpdDelSamples.suo
article_src.zip
Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces
Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces.csproj.user
Microsoft.ApplicationBlocks.ExceptionManagement.suo
DbHelper
DBHelper.chm
DBHelper.csproj.user
DbHelper.ndoc
DBHelper.suo
Microsoft.ApplicationBlocks.ExceptionManagement
ExceptionManagerText.xsx
Microsoft.ApplicationBlocks.ExceptionManagement.csproj.user
Microsoft.ApplicationBlocks.suo
///////////////////////////////////////////////////////////////////////////
// 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)

Share

About the Author

falconsoon

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.1 | Last Updated 14 Apr 2007
Article Copyright 2007 by falconsoon
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid