Better MyGeneration templates and debugging.

Anything that doesn't fall into the defect or enhancement categories

Better MyGeneration templates and debugging.

Postby CameronB on Tue Apr 06, 2010 12:57 am

Hi!

I have been asked many times in the past to give a better explanation of what I have been using (and still use to this day) to drive my Code generation using MyGeneration, driven from VS2008 with the ability to fully debug and step through templates.

So what follows is as brief an explanation as possible that should set you up to build better/stronger/faster templates! 8)
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 1 - set up your CSGEN template file

Postby CameronB on Tue Apr 06, 2010 1:09 am

Ok, so the first thing you need is the actual template file that the MyGeneration engine picks up. I've added a basic example below.

You may notice some things, and they're important!

In the file itself are two sections; one for the GUI that is drawn which lets you select which DB elements to use and the other that actually runs the template.

In each section you need to add references to the DLL's that you will be building your templates in.
You will also need to add the correct namespaces in.

As we are going to build both the UI and the template engine within the DLL, the contents of the CSGEN file are very minimal.

The body for the template itself does very little work...
  • It loads the UI input data
  • It creates an instance of the template class
  • It overrides the Render method to just call the templates Launch function

And that, as they say, is that.


Code: Select all
##|TYPE Template
##|UNIQUEID 73823267-1e40-44ba-82e8-150d68f68f9e
##|TITLE My MSSQL Crud Simple $
##|NAMESPACE MyMSSQLCrud.C#
##|SOURCE_TYPE Source
##|OUTPUT_LANGUAGE C#
##|COMMENTS_BEGIN
This template generates simple CRUD stored procs.
##|COMMENTS_END
##|GUI_ENGINE .Net Script
##|GUI_LANGUAGE C#
##|GUI_BEGIN
<%#DEBUG%><%#REFERENCE System.Windows.Forms.dll %>
<%#REFERENCE System.Windows.Forms.dll %>
<%#REFERENCE MyGeneration.MyChanges.dll,Sql Crud Simple.DLL %>
<%#NAMESPACE System, System.Text, System.Collections, Zeus, Zeus.UserInterface, Zeus.DotNetScript, MyGeneration.MyChanges, SQL_Crud_Simple.Interface %>


public class GeneratedGui : DotNetScriptGui
{
   protected SqlCrudInterface aInterface;
   
   public GeneratedGui(ZeusGuiContext context) : base(context)
   {
      if(context.Objects.ContainsKey("DnpUtils"))
      {
         DnpUtils.ReadInputFromCache(context);
      }
      
      aInterface = new SqlCrudInterface(input, MyMeta, DnpUtils, ui);   
   }


    public override void Setup()
    {
        aInterface.Launch();
    }
   
   public void cmbDatabases_onchange(GuiComboBox control)
   {
      aInterface.cmbDatabases_onchange(control);
   }
}
##|GUI_END
##|BODY_MODE Markup
##|BODY_ENGINE .Net Script
##|BODY_LANGUAGE C#
##|BODY_TAG_START <%
##|BODY_TAG_END %>
##|BODY_BEGIN
<%#DEBUG%><%#REFERENCE System.Windows.Forms.dll,MyGeneration.MyChanges.dll,Sql Crud Simple.DLL,System.Drawing.dll,Linq To SQL.dll%><%#NAMESPACE System.Windows.Forms,System.Drawing,System.Collections.Generic,MyGeneration.MyChanges,SQL_Crud_Simple %><%
public class MyBaseTemplate : DotNetScriptTemplate
{

   protected MyTemplate aTemplate;
   protected SqlCrudScriptSetting ss;

    public MyBaseTemplate(ZeusTemplateContext context) : base(context)
    {
        if (context.Objects.ContainsKey("DnpUtils"))
        {
            DnpUtils.SaveInputToCache(context);
        }

        //Set MyMeta options in order to make sure the correct language and data type
        //generator are used.
        MyMeta.Language = "C#";
        MyMeta.DbTarget = "DbType";
      ss = new SqlCrudScriptSetting(input, MyMeta.Databases, DnpUtils);
        aTemplate =
            new MyTemplate(input, MyMeta, DnpUtils, output, ss);
   
    }
         
   public override void Render()
   {
      aTemplate.Launch();       
   }
}
##|BODY_END
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 2 - Setting up your external tools menu items.

Postby CameronB on Tue Apr 06, 2010 1:20 am

Although not actually required for debugging at all, it is extremely useful for our purposes as a teaching tool here.


As you may have seen elsewhere the steps to do this are..
  • Go to Tools then External Tools
  • Click Add
  • Give the new tool menu a Title
  • Set the Command as C:\Program Files\MyGeneration13\ZeusCmd.exe
  • Set the Arguments as -t "C:\Program Files\MyGeneration13\Templates\MyTemplates\MyTemplate.csgen"
  • Setting the initial directory as C:\Program Files\MyGeneration13
  • Ensure that only the Use Output window option is checked.

I've made some assumptions here about where you've installed MyGeneration.

From this we learn that the ZeusCmd.exe is the engine that actually does all the smarts when it comes to driving a template. The main executable of MyGeneration is just a shell to load and control things.

The arguments show that you specify the name of the template you want to generate with the -t directive
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 3 - Create your Template Library Project/Solution

Postby CameronB on Tue Apr 06, 2010 2:21 am

I'm going to make some broad assumptions here - those being that you know how to drive your VS2008 engine so I'll skip the obvious things and get to the meat..

Create your VS2008 library project.

Once this is done go to the properties of the project
  • On the Debug tab, change the Start Action to start an external action. Can you guess what? That's right, it's the ZeusCmd.exe prog.
  • The Start Options will also need to change to reflect the change you would have made in your command line arguments in the step above to load the correct template file
  • Set the Working Directory to the MyGeneration install directory.

Now you will need to add a few MyGeneration references to your template library project.
  • Dnp.Utils.dll
  • MyMeta.dll
  • System.Data.SQLite.dll
  • PluginInterfaces.dll
  • Zeus.dll
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 4 - ScriptSetting Classes

Postby CameronB on Tue Apr 06, 2010 2:22 am

Create a ScriptSetting class.

It will look something like..
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Zeus;

namespace MyGeneration.MyChanges
{
    public class ScriptSetting
    {
        private IZeusInput m_Input = null;
        private MyMeta.IDatabases m_Databases = null;
        private ArrayList m_RelationTables;
        private Dnp.Utils.Utils m_DnpUtils;

        static protected ScriptSetting _instance = null;

        protected ScriptSetting(IZeusInput i, MyMeta.IDatabases dbs, Dnp.Utils.Utils dnp)
        {
            _instance = this;
            m_Input = i;
            m_Databases = dbs;
            m_RelationTables = new ArrayList();
            m_DnpUtils = dnp;
            UseEndRegionComments = true;
            UseEndBracketComments = true;
        }

        public static ScriptSetting GetInstance()
        {
            return _instance;
        }

        public static ScriptSetting InitInstance(IZeusInput i, MyMeta.IDatabases dbs, Dnp.Utils.Utils dnp)
        {
            _instance = new ScriptSetting(i, dbs, dnp);
            return _instance;
        }

        public IZeusInput Input
        {
            get
            {
                return m_Input;
            }
        }

        public Dnp.Utils.Utils DnpUtils
        {
            get
            {
                return m_DnpUtils;
            }
        }
        public MyMeta.IDatabases Databases
        {
            get
            {
                return m_Databases;
            }
        }

        public string DatabaseName
        {
            get
            {
                return m_Input["cmbDatabase"].ToString();
            }
        }

        public string ReferencedNamespace
        {
            get
            {
                return m_Input["txtReferencedNamespace"].ToString();
            }
        }

        public ArrayList Tables
        {
            get
            {
                object aResult = m_Input["lstTables"];
                if (aResult == null)
                    aResult = new ArrayList();
                return aResult as ArrayList;
            }
        }

        public ArrayList RelationTables
        {
            get
            {
                return m_RelationTables;
            }
            set
            {
                m_RelationTables = value;
            }
        }

        public ArrayList Views
        {
            get
            {
                object aResult = m_Input["lstViews"];
                if (aResult == null)
                    aResult = new ArrayList();
                return aResult as ArrayList;
            }
        }

        public ArrayList Procs
        {
            get
            {
                object aResult = m_Input["lstProcs"];
                if (aResult == null)
                    aResult = new ArrayList();
                return aResult as ArrayList;
            }
        }

        public bool TrimStrings
        {
            get
            {
                return (bool)m_Input["cbPerformTrimming"];
            }
        }

        public bool SeedCheck
        {
            get
            {
                return (bool)m_Input["cbPerformSeedCheck"];
            }
        }

        public bool DecorateMembers
        {
            get
            {
                return (bool)m_Input["cbDecorateMembers"];
            }
        }

        public bool GenerateDebugCode
        {
            get
            {
                return (bool)m_Input["cbGenDebug"];
            }
        }

        public bool SealedClasses
        {
            get
            {
                return (bool)m_Input["cbSealClasses"];
            }
        }

        public bool AbstractClasses
        {
            get
            {
                return (bool)m_Input["cbAbstractClasses"];
            }
        }

        public bool GenerateSQLiteOID
        {
            get
            {
                return (bool)m_Input["cbSQLiteID"];
            }
        }

        public bool PartialClasses
        {
            get
            {
                return (bool)m_Input["cbPartialClasses"];
            }
        }

        public string ClassModifiers
        {
            get
            {
                string modifiers = "public ";
                if (this.SealedClasses)
                {
                    modifiers += "sealed ";
                }

                if (this.AbstractClasses)
                {
                    modifiers += "abstract ";
                }

                if (this.PartialClasses)
                {
                    modifiers += "partial ";
                }

                return modifiers;
            }
        }

        public bool ReturnEmptyStrings
        {
            get
            {
                return (bool)m_Input["cbReturnStringEmpty"];
            }
        }


        public string OutputPath
        {
            get
            {
                string strResult = m_Input["txtPath"].ToString();
                if (!strResult.EndsWith("\\"))
                    strResult += "\\";
                return strResult;
            }
        }

        public string NameSpace
        {
            get
            {
                return m_Input["txtNamespace"] as string;
            }
        }

        public string BaseClass
        {
            get
            {
                return m_Input["txtBaseClass"] as string;
            }
        }

        public string ViewBaseClass
        {
            get
            {
                return m_Input["txtViewBaseClass"] as string;
            }
        }

        public string ConcurrencyColumn
        {
            get
            {
                return (string)m_Input["txtConcurrentFlag"];
            }
        }

        public bool UsePreservation
        {
            get
            {
                return (bool)m_Input["cbUsePreservation"];
            }
        }

        public bool UsePascalStyle
        {
            get
            {
                return (bool)m_Input["cbUsePascalStyle"];
            }
        }

        public bool UsePrefixedMemberNames
        {
            get
            {
                return MemberPrefix != null && MemberPrefix.Length > 0;
            }
        }

        public string MemberPrefix
        {
            get
            {
                return (string)m_Input["txtMemberPrefix"];
            }
        }

        public bool ProtectedDataMembers
        {
            get
            {
                return (bool)m_Input["cbProtectedDataMembers"];
            }
        }

        public bool CreateDefaultConstructor
        {
            get
            {
                return (bool)m_Input["cbCreateDefaultConstructor"];
            }
        }

        public bool CreateHtmlReport
        {
            get
            {
                return (bool)m_Input["cbHtmlRpt"];
            }
        }

        public object GetProperty(string property)
        {
            return (object)m_Input[property];
        }

        public bool UseEndRegionComments { get; set; }
       
        public bool UseEndBracketComments { get; set; }

    }
}
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 5 - Base Classes

Postby CameronB on Tue Apr 06, 2010 2:23 am

Create a Base Class
This class is used as the Base class for all other things you will build in the library and will have some shortcut methods you may like to include.
This will look vaguely something like...

Code: Select all
using System;
using System.Collections.Generic;
using Zeus;
using MyMeta;
using Dnp.Utils;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Data.Linq;
using System.Linq;
using System.Reflection;
using System.Collections;

namespace MyGeneration.MyChanges
{
    public class MyUtility : ICloneable
    {
        public IZeusInput input;
        public IZeusOutput output;
        protected ScriptSetting m_UserScriptSettings;
        protected string _resource = String.Empty;

        protected void setPreserveFile(string aFile)
        {
            setPreserveFile(ScriptSetting.GetInstance().OutputPath, aFile);
        }

        protected void setPreserveFile(string aPath, string aFile, string prefix, string suffix)
        {
            output.setPreserveSource(System.IO.Path.Combine(aPath, aFile), prefix, suffix);
        }

        protected void setPreserveFile(string path, string aFile)
        {
            output.setPreserveSource(System.IO.Path.Combine(path, aFile), "/*** ", " ***/");
        }

        protected void writePreserveBlock(string aPreserveBlockName)
        {
            writeln();
            writeln(output.getPreserveBlock(aPreserveBlockName));
            writeln();
        }
....TRUNCATED!

        #region Clone
        /// <summary>
        /// Deep Copy Clone this, and returning a reference to a cloned object.
        /// </summary>
        /// <returns>
        /// Reference to the new cloned object.
        /// </returns>
        public object Clone()
        {
            //First we create an instance of this specific type.
            object newObject = Activator.CreateInstance(this.GetType());

            //We get the array of fields for the new type instance.
            FieldInfo[] fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

            int i = 0;

            foreach (FieldInfo fi in this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                //We query if the fields support the ICloneable interface.
                System.Type ICloneType = fi.FieldType.GetInterface("ICloneable", true);

                if ((ICloneType != null) && (fi.GetValue(this) != null))
                {
                    ICloneable IClone = (ICloneable)fi.GetValue(this);
                    fields[i].SetValue(newObject, IClone.Clone());
                }
                else if (fi.GetValue(this) != null)
                    fields[i].SetValue(newObject, fi.GetValue(this));

                //Now we check if the object support the
                //IEnumerable interface, so if it does
                //we need to enumerate all its items and check if
                //they support the ICloneable interface.
                System.Type IEnumerableType = fi.FieldType.GetInterface("IEnumerable", true);
                if ((IEnumerableType != null) && (fi.GetValue(this) != null))
                {
                    //Get the IEnumerable interface from the field.
                    IEnumerable IEnum = (IEnumerable)fi.GetValue(this);

                    System.Type IListType = fields[i].FieldType.GetInterface("IList", true);
                    System.Type IDicType = fields[i].FieldType.GetInterface("IDictionary", true);

                    int j = 0;
                    if (IListType != null)
                    {
                        //Getting the IList interface.
                        IList list = (IList)fields[i].GetValue(newObject);

                        foreach (object obj in IEnum)
                        {
                            ICloneType = obj.GetType().GetInterface("ICloneable", true);

                            if ((ICloneType != null) && (obj != null))
                            {
                                ICloneable IClone = (ICloneable)obj;
                                list[j] = IClone.Clone();
                            }
                            else if (obj != null)
                                list[j] = obj;
                            j++;
                        }
                    }
                    else if (IDicType != null)
                    {
                        IDictionary dic = (IDictionary)fields[i].GetValue(newObject);
                        j = 0;

                        foreach (DictionaryEntry de in IEnum)
                        {
                            ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
                            if ((ICloneType != null) && (de.Value != null))
                            {
                                ICloneable IClone = (ICloneable)de.Value;
                                dic[de.Key] = IClone.Clone();
                            }
                            else if (de.Value != null)
                                dic[de.Key] = de.Value;
                            j++;
                        }
                    }
                }
                i++;
            }

            return newObject;
        }

        public virtual MyUtility DeepClone()
        {
            //First do a shallow copy.
            MyUtility returnData = (MyUtility )this.MemberwiseClone();

            //Get the type.
            Type type = returnData.GetType();

            //Now get all the member variables.
            FieldInfo[] fieldInfoArray = type.GetFields();

            //Deepclone members that extend THData.
            //This will ensure we get everything we need.
            foreach (FieldInfo fieldInfo in fieldInfoArray)
            {
                //This gets the actual object in that field.
                object sourceFieldValue = fieldInfo.GetValue(this);

                //See if this member is THData
                if (sourceFieldValue is MyUtility )
                {
                    //If so, cast as a THData.
                    MyUtility sourceTHData = (MyUtility )sourceFieldValue;

                    //Create a clone of it.
                    MyUtility clonedTHData = sourceTHData.DeepClone();

                    //Within the cloned containig class.
                    fieldInfo.SetValue(returnData, clonedTHData);
                }
            }
            return returnData;
        }


        protected MyUtility ()
        {
        }

        #endregion
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 6 - Create Interface Class

Postby CameronB on Tue Apr 06, 2010 2:28 am

Create an Interface class.
This is the class that drives the UI.
Code: Select all
using System;
using System.Collections.Generic;
using Zeus;
using MyMeta;
using Dnp.Utils;
using Zeus.UserInterface;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections;

namespace MyGeneration.MyChanges
{
    public class MyInterface : MyUtility
    {

        private List<IProcedure> ourProcs = new List<IProcedure>();

        protected MyMeta.dbRoot MyMeta;
        protected Dnp.Utils.Utils DnpUtils;
        protected Zeus.UserInterface.GuiController ui;

        protected GuiComboBox cmbDatabases;

        protected GuiLabel lblError;

        public MyInterface(IZeusInput _input, dbRoot _MyMeta, Dnp.Utils.Utils _DnpUtils, Zeus.UserInterface.GuiController _ui)
        {
            input = _input;
            MyMeta = _MyMeta;
            DnpUtils = _DnpUtils;
            //output = _output;
            ui = _ui;
            NumberOfColumns = 1;
            lblError = _ui.AddLabel("lblError", "", "An error has occurred");
        }

        public void Launch()
        {
            Setup();
        }

        protected int maxWidth
        {
            get
            {
                return ui.Width - 30;
            }
        }

        protected override void Setup()
        {
            if (!input.Contains("lstTables") || !input.Contains("txtPath"))
            {
                ui.Title = "SQL Crud Simple";
                ui.Top = 20;
                ui.Left = 20;
                ui.Width = 800;
                ui.Height = 600;

                BuildOutputPathSelector();

                BuildDbComponentsSelectors(300, false, true, false);

                GuiCheckBox cbSingleOutputFile = ui.AddCheckBox("cbSingleOutputFile", "Generate a single output file only", false, "If checked, only one .SQL file is generated so it can be executed against the DB in one go");
                GuiCheckBox cbSingleFilePerProc = ui.AddCheckBox("cbSingleFilePerProc", "Generate a single output file per procedure", false, "If checked, each proc is generated individually and has a unique file - note drops should not be rendered");
                GuiCheckBox cbGenerateDrops = ui.AddCheckBox("cbGenerateDrops", "Generate the DROP statements", true, "If checked, the stored procedures will be dropped before being recreated");

                ui.ShowGui = true;
            }
            else
            {
                ui.ShowGui = false;
            }
        }
        protected void BuildOutputPathSelector()
        {
            BuildOutputPathSelector(string.Empty);
        }

        protected void BuildOutputPathSelector(string AdditionalPathInfo)
        {

            // Grab default output path
            string sOutputPath = "";
            if (input.Contains("defaultOutputPath"))
            {
                sOutputPath = input["defaultOutputPath"].ToString();
            }

            // Setup Folder selection input control.
            GuiLabel lblPath = ui.AddLabel("lblPath", "Output path:", "Select the output path in the field below.");
            lblPath.Width = 70;
            GuiTextBox outpath = ui.AddTextBox("txtPath", System.IO.Path.Combine(sOutputPath, AdditionalPathInfo), "Select the Output Path.");
            outpath.Width = ui.Width - lblPath.Left - lblPath.Width - 130;
            outpath.Left = lblPath.Left + lblPath.Width;
            outpath.Top = lblPath.Top;
            GuiFilePicker btnSelectPath = ui.AddFilePicker("btnPath", "Browse...", "Select the Output Path.", "txtPath", true);
            btnSelectPath.Width = 90;
            btnSelectPath.Top = outpath.Top;
            btnSelectPath.Left = outpath.Left + outpath.Width + 10;
        }

        protected int NumberOfColumns { get; set; }

        private int _nextColumn = 1;
        private int _currentTop = 0;

        private int nextLeft
        {
            get
            {
                return (15 + ((maxWidth / NumberOfColumns) * (_nextColumn - 1)));
            }
        }

        private int controlWidth
        {
            get
            {
                return (maxWidth / NumberOfColumns) - (10 * (NumberOfColumns - 1));
            }
        }

        private void Reposition(GuiControl aControl)
        {
            Reposition(aControl, null);
        }

        private void Reposition(GuiControl aControl, GuiControl aLabelControl)
        {
            if (aLabelControl != null)
            {
                if ((_currentTop != 0) && (_nextColumn != 1))
                {
                    aLabelControl.Top = _currentTop;
                }
                aControl.Top = aLabelControl.Top;

                _currentTop = aLabelControl.Top;
                aLabelControl.Left = nextLeft;
                aLabelControl.Width = controlWidth / 3;
            }
            else
            {
                if ((_currentTop != 0) && (_nextColumn != 1))
                    aControl.Top = _currentTop;
            }

            aControl.Left = ((aLabelControl == null ? nextLeft : nextLeft + maxWidth / NumberOfColumns / 3));
            if (aLabelControl == null)
                aControl.Width = controlWidth;
            else
                aControl.Width = controlWidth / 3 * 2;

            _currentTop = aControl.Top;
            _nextColumn++;
            if (_nextColumn > NumberOfColumns)
                _nextColumn = 1;
        }

        protected GuiCheckBox AddCheckBox(string id, string text, bool isChecked, string tooltip)
        {
            GuiCheckBox aCheckbox = ui.AddCheckBox(id, text, isChecked, tooltip);
            Reposition(aCheckbox);
            return aCheckbox;
        }

        protected GuiTextBox AddLabeledTextBox(string label, string id, string text, string tooltip)
        {
            GuiLabel aLabel = ui.AddLabel("lbl_" + id, label, tooltip);

            GuiTextBox aTextbox = ui.AddTextBox(id, text, tooltip);
            Reposition(aTextbox, aLabel);
            return aTextbox;
        }

        protected GuiComboBox AddLabeledComboBox(string label, string id, string tooltip)
        {
            GuiLabel aLabel = ui.AddLabel("lbl_" + id, label, tooltip);
            GuiComboBox aCombo = ui.AddComboBox(id, tooltip);
            Reposition(aCombo, aLabel);
            return aCombo;
        }

#region Build Database Components Selectors
        /// <summary>
        /// Builds the Database selector and the table, view and stored procs selectors
        /// </summary>
        /// <param name="DbSelectHeight">The height to use for the table, view and stored procs list boxes</param>
        protected void BuildDbComponentsSelectors(int DbSelectHeight)
        {
            BuildDbComponentsSelectors(DbSelectHeight, true, true, true);
        }

        protected void BuildDbComponentsSelectors(int DbSelectHeight, bool ShowTables, bool ShowViews, bool ShowProcs)
        {
            int numberOfComponents = (ShowTables ? 1 : 0) + (ShowViews ? 1 : 0) + (ShowProcs ? 1 : 0);
            int TopSpot = 0;
            int LeftSpot = 0;

            // Setup Database selection combobox.
            GuiLabel label_d = ui.AddLabel("lblDatabases", "Select a database:", "Select a database in the dropdown below.");
            cmbDatabases = ui.AddComboBox("cmbDatabase", "Select a database.");
           
            cmbDatabases.Width = maxWidth;

            if (ShowTables)
            {
                #region Setup Tables selection multi-select listbox.
                // Setup Tables selection multi-select listbox.
                GuiLabel lblTables = ui.AddLabel("lblTables", "Select table(s):", "Select tables from the listbox below.");
                lblTables.Width = maxWidth / numberOfComponents;
                GuiListBox lstTables = ui.AddListBox("lstTables", "Select tables.");
                lstTables.Height = DbSelectHeight;
                lstTables.Width = maxWidth / numberOfComponents;
                TopSpot = lblTables.Top;
                LeftSpot = lblTables.Left + lblTables.Width;
                #endregion
            }

            if (ShowViews)
            {
                #region Setup Views selection multi-select listbox.
                GuiLabel lblViews = ui.AddLabel("lblViews", "Select views:", "Select views for which a BusinessEntity should be created.");
                lblViews.Width = maxWidth / numberOfComponents;
                if (TopSpot != 0)
                {
                    lblViews.Left = LeftSpot;
                    lblViews.Top = TopSpot;
                }
                GuiListBox lstViews = ui.AddListBox("lstViews", "Select views.");
                lstViews.Height = DbSelectHeight;
                lstViews.Width = maxWidth / numberOfComponents;
                lstViews.Left = lblViews.Left;
                lstViews.Enabled = true;
                TopSpot = lblViews.Top;
                LeftSpot = lblViews.Left + lblViews.Width;
                #endregion
            }

            if (ShowProcs)
            {
                #region Setup Procedures selection multi-select listbox.
                GuiLabel lblProcs = ui.AddLabel("lblProcs", "Select procedures:", "Select procedures from the listbox below.");
                lblProcs.Width = maxWidth / numberOfComponents;
                if (TopSpot != 0)
                {
                    lblProcs.Left = LeftSpot;
                    lblProcs.Top = TopSpot;
                }
                GuiListBox lstProcs = ui.AddListBox("lstProcs", "Select procedures.");
                lstProcs.Height = DbSelectHeight;
                lstProcs.Width = maxWidth / numberOfComponents;
                lstProcs.Left = lblProcs.Left;
                lstProcs.Enabled = true;
                #endregion
            }

            // Attach the onchange event to the cmbDatabases control.
            setupDatabaseDropdown();
            cmbDatabases.AttachEvent("onchange", "cmbDatabases_onchange");
        }

        public void setupDatabaseDropdown()
        {
            try
            {
                if (MyMeta.IsConnected)
                {
                    cmbDatabases.BindData(MyMeta.Databases);
                    if (MyMeta.DefaultDatabase != null)
                    {
                        cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Alias;
                        bindTables(cmbDatabases.SelectedValue);
                        bindViews(cmbDatabases.SelectedValue);
                        bindProcedures(cmbDatabases.SelectedValue);
                    }
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }
        }

        public void setSavePath(string sDatabase)
        {
            //int count = 0;

            GuiTextBox txtPath = ui["txtPath"] as GuiTextBox;
            GuiTextBox txtNamespace = ui["txtNamespace"] as GuiTextBox; //ui.AddTextBox("", MyMeta.DefaultDatabase.Alias + ".DalLinq", "Provide your objects namespace.");
            GuiTextBox txtPathUC = ui["txtPathUC"] as GuiTextBox;
           
            try
            {
                if (txtPath != null && txtNamespace != null)
                {

                    Regex regExPath = new Regex("\\\\MyChanges\\\\.*[a-zA-Z0-9-_ ].*\\\\");
                    Regex regExNamespace = new Regex(@"MyChanges\..*[a-zA-Z0-9-_ ].*\.");

                    if (!regExPath.IsMatch(txtPath.Text))
                    {
                        regExPath = new Regex("\\\\MyChanges\\\\.*[a-zA-Z0-9-_ ].*");
                        txtPath.Text = regExPath.Replace(txtPath.Text, string.Format(@"\MyChanges\{0}", sDatabase));
                    }
                    else
                        txtPath.Text = regExPath.Replace(txtPath.Text, string.Format(@"\MyChanges\{0}\", sDatabase));

                    if (!regExNamespace.IsMatch(txtNamespace.Text))
                    {
                        regExNamespace = new Regex(@"MyChanges\..*[a-zA-Z0-9-_ ].*");
                        txtNamespace.Text = regExNamespace.Replace(txtNamespace.Text, string.Format(@"MyChanges.{0}", sDatabase));
                    }
                    else
                        txtNamespace.Text = regExNamespace.Replace(txtNamespace.Text, string.Format(@"MyChanges.{0}.", sDatabase));

                }

                if (txtPathUC != null)
                {
                    Regex regExPathUC = new Regex("\\\\MyChanges\\\\.*[a-zA-Z0-9-_ ].*\\\\");
                    txtPathUC.Text = regExPathUC.Replace(txtPathUC.Text, string.Format(@"\MyChanges\{0}\", sDatabase));
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;

            }
        }

        public void bindTables(string sDatabase)
        {
            //int count = 0;

            GuiListBox lstTables = ui["lstTables"] as GuiListBox;

            try
            {
                if (lstTables != null)
                {
                    IDatabase db = MyMeta.Databases[sDatabase];
                    lstTables.BindData(db.Tables);
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;

            }
        }

        public void bindViews(string sDatabase)
        {
            //int count = 0;

            GuiListBox lstViews = ui["lstViews"] as GuiListBox;

            try
            {
                if (lstViews != null)
                {
                    IDatabase db = MyMeta.Databases[sDatabase];
                    List<IView> views = new List<IView>();
                    foreach (IView view in db.Views)
                    {
                        if (!view.Alias.StartsWith("avw_"))
                            views.Add(view);
                    }

                    lstViews.BindData(views);//db.Views);
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;

            }
        }

        public void bindProcedures(string sDatabase)
        {
//            GuiLabel lblError = ui["lblError"] as GuiLabel;
            //int count = 0;

            GuiListBox lstProcs = ui["lstProcs"] as GuiListBox;

            try
            {
                if (lstProcs != null)
                {
                    IDatabase db = MyMeta.Databases[sDatabase];

                    ourProcs.Clear();
                    foreach (IProcedure aProc in db.Procedures)
                    {
                        bool fAdd = true;
                        if (aProc.Name.Contains("sp_"))
                            fAdd = false;
                        if (aProc.Name.Contains("fn_"))
                            fAdd = false;
                        if (aProc.Name.Contains("dm_"))
                            fAdd = false;
                        if (aProc.Name.Contains("xp_"))
                            fAdd = false;
                        if (aProc.Name.Contains("admin_"))
                            fAdd = false;
                        if (fAdd)
                            ourProcs.Add(aProc);
                    }
                   
                    lstProcs.BindData(ourProcs);

                    lblError.Text = "";
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }
        }

        public void cmbDatabases_onchange(GuiComboBox control)
        {
            GuiComboBox cmbDatabases = ui["cmbDatabase"] as GuiComboBox;

            setSavePath(cmbDatabases.SelectedText);
            bindTables(cmbDatabases.SelectedText);
            bindViews(cmbDatabases.SelectedText);
            bindProcedures(cmbDatabases.SelectedText);
        }

#endregion

        public string LoadSetting(string item, string configName)
        {
            string value = null;

            string path = string.Format(@"{0}\{1}", @System.Windows.Forms.Application.StartupPath, "configuration");
            string filePath = string.Format(@"{0}\{1}{2}", path, configName, @".config");

            if (File.Exists(filePath))
            {
                StreamReader sr = File.OpenText(filePath);
                string line;

                while (sr.Peek() > 0)
                {
                    line = sr.ReadLine();
                    if (line.Contains(item))
                    {
                        int startIndex = line.IndexOf("=");

                        value = line.Substring(startIndex + 1, (line.Length - startIndex) - 1);
                        break;
                    }
                }

                sr.Close();

            }

            return value;
        }

        public void SaveSetting(string item, string value, string configName)
        {
            StreamWriter sw;

            string path = string.Format(@"{0}\{1}", @System.Windows.Forms.Application.StartupPath, "configuration");
            string filePath = string.Format(@"{0}\{1}{2}", path, configName, @".config");

            bool fileExists = File.Exists(filePath);
            bool folderExists = Directory.Exists(path);

            if (!folderExists)
            {
                Directory.CreateDirectory(path);
            }

            if (!fileExists)
            {
                sw = File.CreateText(filePath);
                sw.WriteLine(string.Format("{0}=" + value, item));
                sw.Close();
            }
            else
            {
                string text = File.ReadAllText(filePath);
                if (text != null)
                {
                    int startConnstringIndex = text.IndexOf(item);
                    int endConnStringIndex = 0;
                    if (startConnstringIndex >= 0)
                        endConnStringIndex = text.IndexOf("\r\n", startConnstringIndex);

                    if (startConnstringIndex >= 0 && endConnStringIndex >= 0)
                    {
                        string substring = text.Substring(startConnstringIndex, endConnStringIndex - startConnstringIndex);
                        text = text.Replace(substring, string.Format("{0}=" + value, item));
                    }
                    else
                        text += string.Format("{0}=" + value + "\r\n", item);

                    File.WriteAllText(filePath, text);
                }
            }
        }
    }
}

CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Step 7 - The Template class

Postby CameronB on Tue Apr 06, 2010 2:43 am

Ok, so we've almost come to the juicy part.

There's a few ways to go here, and I'm going to leave much of the work here to you as I've already provided a LARGE leap forward as a head start.

If you have a look at the templates for Gentle.NET you will notice that the author creates wrappers for the Table and View classes. I too created similar classes for these classes, as well as the Column and Proc classes.

You may not need to do this.

More importantly though, if you observe from within MyGeneration you will notice that any template loaded has its Template Code and its corresponding Template Source. You edit the code and the source changes accordingly.

It is the Template Source code that you can take and place within your project and effectively mow step through and debug. I highly recommend grabbing the code for the Gentle.NET template source, throwing that in your template library, hooking it up and seeing how it does its job.

Now it may occur to you that much of what I have given you so far is a little superfluous. Much of the classes I have demonstrated are indeed, and alternatively could have been ripped right from the generated source from MyGeneration.

I'm sure there will be many among you that will perhaps be a little lost at this stage. Never fear, give it a go and if you have any problems with it don't hesitate to ask a question here and I'll try to help you out ASAP.

Unfortunately I am unable to share my template code with anyone at this time. I have, however, provided you with enough information so that you should be able to progress on from here.

Good luck, and post here with your experiences. I want to see MyGeneration live on a little longer.
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm

Re: Better MyGeneration templates and debugging.

Postby CameronB on Tue Jun 29, 2010 12:33 am

Well, perhaps my instructions were not quite clear enough, I'm not sure....

But now I know that this file has all you need.

MyGenHTML.zip
Debuggable DLL C# Project file example and CSGEN file
(7.44 KiB) Downloaded 13 times


It basically follows the same instructions as outlined above. But it's all been done for you.

If you have any further queries regards this, :idea: please post a reply in this thread so that others can... um... learn from your pain? :D

I've subscribed to this topic so I should be able to answer any questions pretty quickly.

Thanks & Good luck

Cameron
CameronB
Corporal
 
Posts: 19
Joined: Sun Sep 28, 2008 10:46 pm


Return to General Questions or Comments

Who is online

Users browsing this forum: Yahoo [Bot] and 1 guest