Update to my generator v1 nhs number generator

The simplest way to populate your database with test data.

Moderators: JonathanWatts, David Atkinson, Anu Deshpande, Michelle Taylor, Lionel, Emma A

Update to my generator v1 nhs number generator

Postby jbaggaleyV2 » Thu Nov 07, 2013 11:28 pm

I am trying to update my NHs number generator for the current version of the data generator but the generator tool refuses to recognise my module. It has been placed in C:\\Program Files (x86)\\Red Gate\\SQL Data Generator 2\\Generators and compiled to DotNet2.
Is there anything I have done wrong in the code below? The code is a simple class library initially based on the Basic library but when that didn't work either, used elements of the full example.
I originally posted this in http://www.red-gate.com/messageboard/vi ... hp?t=10953 a few years ago...

Thanks
Jon


Code: Select all
using System;
using System.Collections;
using System.Globalization;
using RedGate.SQLDataGenerator.Engine.Generators;
using RedGate.SQLDataGenerator.Engine.Generators.Static;
using RedGate.SQLDataGenerator.Engine.Generators.Support;

namespace NHS
{
     [Generator(typeof(int), \"Generic\", \"NHS Number\", \"A valid check digited NHS number\")]
    public class NhsNumberGenerator : GeneratorBase, IUniqueableGenerator
    {
         private Random _random;

        // public int Seed { get; set; }
         public bool Unique { get; set; }

        public NhsNumberGenerator(GeneratorParameters parameters) :base(parameters)
        {
         
        }

         public override IEnumerator GetNonNullEnumerator(GenerationSession session)
        {
            while (true)
                yield return GenerateNhsNumber();
        }

        private bool StandardNhsTest(string nhsNumberToTest)
        {
            var calcResult = 0;
            var returnValue = true;

            // Remove any spaces if number is in 3 3 4 format
            nhsNumberToTest = nhsNumberToTest.Replace(\" \", string.Empty);

            // Simple validation
            if (nhsNumberToTest.Length != 10)
                // Only 10 characters allowed
                returnValue = false;
            else if (!IsNumeric(nhsNumberToTest))
                // is numeric
                returnValue = false;
            else if (\",0000000000,1111111111,2222222222,3333333333,4444444444,5555555555,6666666666,7777777777,8888888888,9999999999\".Contains(nhsNumberToTest))
                // Make sure no consecutive numbers
                returnValue = false;

            if (returnValue)
            {
                // Step 1 - add the numbers multiplied by their weighting
                for (int digitIndex = 0; digitIndex < 9; digitIndex++)
                {
                    calcResult += Convert.ToInt32(nhsNumberToTest.Substring(digitIndex, 1)) * (10 - digitIndex);
                }

                // Step 2 Mod 11 calcuation to get remainder
                calcResult = calcResult % 11;

                // Step 3 - take remainder from 11 to give check digit
                calcResult = 11 - calcResult;
                if (calcResult == 11)
                {
                    calcResult = 0;
                }

                // Test calculated check digit against real digit
                if (Convert.ToInt32(nhsNumberToTest.Substring(9, 1)) != calcResult)
                {
                    returnValue = false;
                }
            }
            return returnValue;
        }
        /// <summary>
        /// Helper function to generate valid NHS numbers.
        /// </summary>
        /// <returns></returns>
        private string GenerateNhsNumber()
        {
            if (_random == null) _random = new Random(Seed);
           
            var calcResult = 0;

            var nhsNumberToTest = _random.Next(100000000, 999999998).ToString(CultureInfo.InvariantCulture);

            // Step 1 - add the numbers multiplied by their weighting
            for (var digitIndex = 0; digitIndex < 9; digitIndex++)
                calcResult += Convert.ToInt32(nhsNumberToTest.Substring(digitIndex, 1))*(10 - digitIndex);

            // Step 2 Mod 11 calcuation to get remainder
            calcResult = calcResult % 11;

            // Step 3 - take remainder from 11 to give check digit
            calcResult = 11 - calcResult;
            if (calcResult == 11)
                calcResult = 0;
            else if (calcResult >= 10)  // If >10 is an invalid number so generate another
                nhsNumberToTest = GenerateNhsNumber();
            else
                nhsNumberToTest += calcResult.ToString(CultureInfo.InvariantCulture);

            // Do a last sanity check to stop invalid checkdigit numbers coming through.
            return StandardNhsTest(nhsNumberToTest) ? nhsNumberToTest : GenerateNhsNumber();
        }

        /// <summary>
        /// Determines whether the specified expression is numeric.
        /// </summary>
        /// <param name=\"expression\">The expression.</param>
        /// <returns>
        ///    <c>true</c> if the specified expression is numeric; otherwise, <c>false</c>.
        /// </returns>
        private static Boolean IsNumeric(Object expression)
        {
            if (expression == null || expression is DateTime)
                return false;

            if (expression is Int16 || expression is Int32 || expression is Int64 || expression is Decimal || expression is Single || expression is Double || expression is Boolean)
                return true;

            try
            {
                if (expression is string)
                    Double.Parse(expression as string);
                else
                    Double.Parse(expression.ToString());
                return true;
            }
            catch (FormatException)
            { } // just dismiss errors but return false
            return false;
        }
    }

}
:-)zz[
jbaggaleyV2
 
Posts: 3
Joined: Thu Nov 07, 2013 11:17 pm

Postby Brian Donahue » Mon Nov 11, 2013 3:28 pm

As long as the class inherits GeneratorBase and is compiled referencing the same DLLs as the ones in your SQL Data Generator program folder, and is copied to the generators folder, SDG should pick the generator up. In your case it should show up under the category "generic".

I have a build that works with the current (2.x) version that you can try:
ftp://Z3441:uLYeWUoc@supportftp.red-gat ... erator.zip

(note, this file may not be available in 30 days, for future reference)
Brian Donahue
 
Posts: 6669
Joined: Mon Aug 23, 2004 10:48 am

Brilliant - that works perfectly...

Postby jbaggaleyV2 » Mon Nov 11, 2013 3:38 pm

What did you do differently because I notice it was 1/2k larger than my previously compiled version?
:-)zz[
jbaggaleyV2
 
Posts: 3
Joined: Thu Nov 07, 2013 11:17 pm

Postby Brian Donahue » Tue Nov 12, 2013 12:10 pm

I'm not sure because I haven't seen your DLL but I assume it's the updated references.
Brian Donahue
 
Posts: 6669
Joined: Mon Aug 23, 2004 10:48 am

Thank you

Postby jbaggaleyV2 » Tue Nov 12, 2013 2:50 pm

That's strange, I only have the v2 generator on my machine so I am not sure how the references are wrong but if you haven't needed to change my code then that is great & it is just some tinkering at my end....

Thanks for your help!
:-)zz[
jbaggaleyV2
 
Posts: 3
Joined: Thu Nov 07, 2013 11:17 pm


Return to SQL Data Generator 2

Who is online

Users browsing this forum: No registered users and 0 guests