Click here to Skip to main content
15,886,362 members
Articles / Web Development / ASP.NET

Secrets for Setting Up Continuous Integration

Rate me:
Please Sign up or sign in to vote.
2.88/5 (7 votes)
23 Feb 2009CPOL5 min read 65.4K   54   41  
A few simple tips that should help when you are considering setting up CI
using System.Collections.Generic;
using System.Data;
using Agile.Genie.Descriptors;
using GeneratorCustomization;

namespace Descriptors.GeneratorCustomization
{
    /// <summary>
    /// Container for all tables that are included tables.
    /// We only genertate code for these tables.
    /// </summary>
    public class IncludedTable
    {
        private readonly string _database;
        private readonly string _table;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="table">Name of the table to be included.</param>
        /// <param name="database">Name of the database the table is in.</param>
        private IncludedTable(string table, string database)
        {
            _table = table;
            _database = database;
        }

        /// <summary>
        /// Name of the table that is to be included.
        /// </summary>
        public string Table
        {
            get { return _table; }
        }

        /// <summary>
        /// Name of the database that the table is in.
        /// </summary>
        public string Database
        {
            get { return _database; }
        }

        /// <summary>
        /// Instantiate a new included table.
        /// </summary>
        /// <param name="table">Name of the table to be included.</param>
        /// <returns></returns>
        public static IncludedTable Build(string table)
        {
            return new IncludedTable(table, string.Empty);
        }

        /// <summary>
        /// Instantiate a new included table.
        /// </summary>
        /// <param name="table">Name of the table to be included.</param>
        /// <param name="database">Name of the database the table is in.</param>
        /// <returns></returns>
        public static IncludedTable Build(string table, string database)
        {
            return new IncludedTable(table, database);
        }

        private readonly static Dictionary<string,List<string>> excludedTables = new Dictionary<string,List<string>>(); 

        /// <summary>
        /// Returns true if the database the table is in has an included column 'All'.
        /// OR there is a match on the database and table name in the included columns xml file, 'IncludedTable' table.
        /// Also encapsulates logic for 'EXCLUDED' tables.
        /// </summary>
        public static bool TableShouldBeIncluded(DatabaseTable table)
        {
            // if it's not set to be 'included' then return false 
            // note that for most databases, it will have 'All' tables
            if (! IncludedTableCollection.All.MatchOnDatabaseAndTable(table))
                return false;

            // Ok so if it is to be Included (could be because ALL tables are included)
            // then we need to double check that the table has not been explicitly excluded.
            PopulateExcludedTableDictionary();
            
            // first check the tables excluded from ALL database code generation
            
            if(excludedTables.ContainsKey("All"))
            {
                if (IsTableExcluded(table, excludedTables["All"]))
                    return false;
            }
            // now check the tables excplicitly excluded for this database
            if(excludedTables.ContainsKey(table.DatabaseName))
            {
                if (IsTableExcluded(table, excludedTables[table.DatabaseName]))
                    return false;
            }

            return true;
        }

        /// <summary>
        /// Returns true if the table has been defined to be excluded (in GeneratorDetailsData)
        /// </summary>
        private static bool IsTableExcluded(DatabaseTable table, List<string> excludedList)
        {
                foreach(string excluded in excludedList)
                {
                    // first, we allow ending with *
                    if(excluded.EndsWith("*"))
                    {
                        if(table.Name.StartsWith(excluded.Replace("*", ""), System.StringComparison.InvariantCultureIgnoreCase))
                            return true;
                    }
                    
                        // then, we allow starting with *
                    else if(excluded.StartsWith("*"))
                    {
                        if(table.Name.EndsWith(excluded.Replace("*", ""), System.StringComparison.InvariantCultureIgnoreCase))
                            return true;
                    }

                        // finally check the exact match
                    else if(excluded.Equals(table.Name, System.StringComparison.InvariantCultureIgnoreCase))
                        return true;
                }
            
            return false;
        }

        private static void PopulateExcludedTableDictionary()
        {
            // only populate once
            if(excludedTables.Count != 0)
                return;

            foreach (DataRow row in GeneratorsData.GetDataRowsFor("ExcludedTable"))
            {
                string database = row["Database"].ToString();
                string excludedText = row["TableName"].ToString();

                // first see if there is an existing list for the database
                
                if(excludedTables.ContainsKey(database))
                {
                    List<string> databaseList = excludedTables[database];
                    databaseList.Add(excludedText);
                }
                else
                {
                    List<string> databaseList = new List<string>();
                    databaseList.Add(excludedText);
                    excludedTables.Add(database, databaseList);
                }
            }
        }

        #region Nested type: Testing

        /// <summary>
        /// Support methods for testing use only
        /// </summary>
        public class Testing
        {
            /// <summary>
            /// Get the test included table. Details are:-
            /// TestTable
            /// </summary>
            /// <returns></returns>
            public static IncludedTable GetTestIncludedTable()
            {
                return Build("TestTable");
            }
        }

        #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
Software Developer (Senior) Peer Placements Pty Ltd
Australia Australia
I live in Sydney and have been a developer for almost a decade now. I have a passion for technology and a strong interest in discovering 'better, cleaner, faster' ways to get systems out the door because I believe software development takes too long. If I have an idea I want to realise it as quickly as possible...plus writing systems for someone else I want to deliver quickly so I can move onto the next interesting project!

Comments and Discussions