##|TYPE Template ##|UNIQUEID 24597e63-c7e8-4a22-bc40-00e774c474d7 ##|TITLE Gentle.NET Business Entity $Rev: 0010 $ ##|NAMESPACE GentleNET.VbNet ##|SOURCE_TYPE Source ##|OUTPUT_LANGUAGE VB.Net ##|COMMENTS_BEGIN This template generates Gentle.NET Business Object classes from database table definitions. ##|COMMENTS_END ##|GUI_ENGINE .Net Script ##|GUI_LANGUAGE C# ##|GUI_BEGIN <%#DEBUG%><%#REFERENCE System.Windows.Forms.dll %> <%#REFERENCE System.Windows.Forms.dll %> <%#NAMESPACE System, System.Text, System.Collections, Zeus, Zeus.UserInterface, Zeus.DotNetScript %> public class GeneratedGui : DotNetScriptGui { public GeneratedGui(ZeusGuiContext context) : base(context) { if(context.Objects.ContainsKey("DnpUtils")) { DnpUtils.ReadInputFromCache(context); } } public override void Setup() { if ( !input.Contains("lstTables") || !input.Contains("txtPath") ) { ui.Title = "Gentle.NET Business Entity (VB)"; ui.Top = 20; ui.Left = 20; ui.Width = 640; ui.Height = 730; // Grab default output path string sOutputPath = ""; if (input.Contains("defaultOutputPath")) { sOutputPath = input["defaultOutputPath"].ToString(); } // Setup Folder selection input control. GuiLabel lblPath = ui.AddLabel("lblPath", "Select the output path:", "Select the output path in the field below."); lblPath.Width = 120; GuiTextBox outpath = ui.AddTextBox("txtPath", sOutputPath, "Select the Output Path."); outpath.Width = ui.Width - lblPath.Left - lblPath.Width - 30; outpath.Left = lblPath.Left + lblPath.Width; outpath.Top = lblPath.Top; GuiFilePicker btnSelectPath = ui.AddFilePicker("btnPath", "Browse...", "Select the Output Path.", "txtPath", true); btnSelectPath.Width = lblPath.Width + outpath.Width; // namespace references GuiLabel lblReferencedNamespace = ui.AddLabel ("lblReferencedNamespace", "Ref. Namespace: ", "Any additional referenced Namespace."); lblReferencedNamespace.Width = 120; GuiTextBox txtReferencedNamespace = ui.AddTextBox("txtReferencedNamespace", "", "Any additional referenced Namespace."); txtReferencedNamespace.Width = ui.Width - lblReferencedNamespace.Width - lblReferencedNamespace.Left - 30; txtReferencedNamespace.Top = lblReferencedNamespace.Top; txtReferencedNamespace.Left = lblReferencedNamespace.Left + lblReferencedNamespace.Width; GuiLabel lblNS = ui.AddLabel ("lblNamespace", "Namespace: ", "Provide your objects namespace."); lblNS.Width = 120; GuiTextBox txtNamespace = ui.AddTextBox("txtNamespace", MyMeta.DefaultDatabase.Alias, "Provide your objects namespace."); txtNamespace.Width = ui.Width - lblNS.Width - lblNS.Left - 30; txtNamespace.Top = lblNS.Top; txtNamespace.Left = lblNS.Left + lblNS.Width; GuiLabel lblBase = ui.AddLabel ("lblBaseClass", "Base class: ", "Provide your objects base class, derived from Persistent."); lblBase.Width = 120; GuiTextBox txtBaseClass = ui.AddTextBox("txtBaseClass", "Persistent", "Provide your objects base class."); txtBaseClass.Width = ui.Width - lblBase.Width - lblBase.Left - 30; txtBaseClass.Top = lblBase.Top; txtBaseClass.Left = lblBase.Left + lblBase.Width; GuiLabel lblViewBase = ui.AddLabel ("lblViewBaseClass", "Views Base class: ", "Provide your view objects base class (not derived from Persistent."); lblViewBase.Width = 120; GuiTextBox txtViewBaseClass = ui.AddTextBox("txtViewBaseClass", "", "Provide your view objects base class."); txtViewBaseClass.Width = ui.Width - lblViewBase.Width - lblViewBase.Left - 30; txtViewBaseClass.Top = lblViewBase.Top; txtViewBaseClass.Left = lblViewBase.Left + lblViewBase.Width; GuiLabel lblConc = ui.AddLabel ("lblConcurrentFlag", "Concurrency column: ", "Provide a column name which keeps concurrent status flag"); lblConc.Width = 120; GuiTextBox txtConcurrentFlag = ui.AddTextBox("txtConcurrentFlag", "", "Provide a column name which keeps concurrent status flag."); txtConcurrentFlag.Width = ui.Width - lblConc.Width - lblConc.Left - 30; txtConcurrentFlag.Top = lblConc.Top; txtConcurrentFlag.Left = lblConc.Left + lblConc.Width; GuiCheckBox cbCreatePKConstructor = ui.AddCheckBox("cbCreatePKConstructor", "Generate PrimaryKey constructor", false, "If checked, a constructor with only the primary keys is generated"); cbCreatePKConstructor.Width = ui.Width / 2 - 10; cbCreatePKConstructor.Enabled = true; GuiCheckBox cbDecorateMembers = ui.AddCheckBox("cbDecorateMembers", "Put Gentle attribute decorations on members", true, "If checked, decoration is on members, if not checked decoration is on properties"); cbDecorateMembers.Width = ui.Width / 2 - 10; GuiCheckBox cbPerformSeedCheck = ui.AddCheckBox("cbPerformSeedCheck", "Perform autokey seed check", false, "Checking this will add a seed check on MS SQL Server autokeys in [class]::Retrieve()"); cbPerformSeedCheck.Width = ui.Width / 2 - 10; GuiCheckBox cbSealClasses = ui.AddCheckBox("cbSealClasses", "Seal the generated classes", false, "Checking this will cause generated classes to be sealed (and generate only private members)"); cbSealClasses.Width = ui.Width / 2 - 10; GuiCheckBox cbUsePreservation = ui.AddCheckBox("cbUsePreservation", "Insert code preservation blocks", false, "Generates MyGeneration code preservation blocks to protect manual changes during regeneration."); cbUsePreservation.Width = ui.Width / 2 - 10; GuiCheckBox cbUsePascalStyle = ui.AddCheckBox("cbUsePascalStyle", "Change object names to PascalStyle", true, "Checking will change the names to PascalStyle for better reading."); cbUsePascalStyle.Width = ui.Width / 2 - 10; GuiCheckBox cbCreateDefaultConstructor = ui.AddCheckBox("cbCreateDefaultConstructor", "Create a default (parameterless) constructor", false, "Create a default (parameterless) constructor."); cbCreateDefaultConstructor.Width = ui.Width / 2 - 10; GuiCheckBox cbNullObjectPattern = ui.AddCheckBox("cbNullObjectPattern", "Implement null object pattern", false, "Implements a null/nothing object which is returned when no records are found rather than null/nothing."); cbNullObjectPattern.Width = ui.Width / 2 - 10; GuiCheckBox cbPerformTrimming = ui.AddCheckBox("cbPerformTrimming", "Trim string values in results", true, "Checking this will cause generated code to automatically trim trailing spaces in string values"); cbPerformTrimming.Top = cbCreatePKConstructor.Top; cbPerformTrimming.Left = cbCreatePKConstructor.Left + cbCreatePKConstructor.Width; cbPerformTrimming.Width = cbCreatePKConstructor.Width; GuiCheckBox cbReturnStringEmpty = ui.AddCheckBox("cbReturnStringEmpty", "Return string instead of null", true, "Checking this will cause generated properties to return string.Empty if they are not set in the database"); cbReturnStringEmpty.Top = cbDecorateMembers.Top; cbReturnStringEmpty.Left = cbPerformTrimming.Left; cbReturnStringEmpty.Width = cbPerformTrimming.Width; GuiCheckBox cbAbstractClasses = ui.AddCheckBox("cbAbstractClasses", "Create abstract rather than concrete classes", false, "Generates abstract classes rather than concrete ones."); cbAbstractClasses.Top = cbPerformSeedCheck.Top; cbAbstractClasses.Left = cbPerformTrimming.Left; cbAbstractClasses.Width = cbPerformTrimming.Width; GuiCheckBox cbSQLiteID = ui.AddCheckBox("cbSQLiteID", "Create read only (O)ID column for SQLite entities", false, "Generates an OID property that maps to SQLite OID autokey column."); cbSQLiteID.Top = cbSealClasses.Top; cbSQLiteID.Left = cbAbstractClasses.Left; cbSQLiteID.Width = cbAbstractClasses.Width; GuiCheckBox cbPartialClasses = ui.AddCheckBox("cbPartialClasses", "Generate .NET 2.0 partial classes", true, "Add the partial keyword to generated classes for .NET 2.0 usage."); cbPartialClasses.Top = cbUsePreservation.Top; cbPartialClasses.Left = cbSQLiteID.Left; cbPartialClasses.Width = cbSQLiteID.Width; GuiCheckBox cbProtectedDataMembers = ui.AddCheckBox("cbProtectedDataMembers", "Use protected accessibility modifier for members", false, "Uses protected (instead of private) accessiblity modified for members."); cbProtectedDataMembers.Top = cbUsePascalStyle.Top; cbProtectedDataMembers.Left = cbSQLiteID.Left; cbProtectedDataMembers.Width = cbSQLiteID.Width; cbProtectedDataMembers.AttachEvent("onclick", "cbProtectedDataMembers_onclick"); GuiLabel lblMemberPrefix = ui.AddLabel ("lblMemberPrefix", "Member prefix: ", "Specify the string used to prefix all member names."); lblMemberPrefix.Visible = true; lblMemberPrefix.Top = cbNullObjectPattern.Top; lblMemberPrefix.Left = cbSQLiteID.Left; lblMemberPrefix.Width = 80; GuiTextBox txtMemberPrefix = ui.AddTextBox("txtMemberPrefix", "", "Prefix all member names with this string."); txtMemberPrefix.Visible = true; txtMemberPrefix.Top = lblMemberPrefix.Top; txtMemberPrefix.Left = lblMemberPrefix.Left + lblMemberPrefix.Width + 4; txtMemberPrefix.Width = 40; //GuiCheckBox cbTemp = ui.AddCheckBox("cbTemp", "Temp", false, "Temp"); //cbTemp.Top = cbUsePreservation.Top; //cbTemp.Left = cbUseGentleCaching.Left; //cbTemp.Width = cbUseGentleCaching.Width; // Setup Database selection combobox. GuiLabel label_d = ui.AddLabel("lblDatabases", "Select a database:", "Select a database in the dropdown below."); label_d.Top = txtMemberPrefix.Top + txtMemberPrefix.Height + 4; GuiComboBox cmbDatabases = ui.AddComboBox("cmbDatabase", "Select a database."); cmbDatabases.Width = btnSelectPath.Width; // Setup Tables selection multi-select listbox. GuiLabel lblTables = ui.AddLabel("lblTables", "Select table(s):", "Select tables from the listbox below."); lblTables.Width = btnSelectPath.Width / 2; GuiListBox lstTables = ui.AddListBox("lstTables", "Select tables."); lstTables.Height = 170; lstTables.Width = btnSelectPath.Width / 2; // Setup Views selection multi-select listbox. GuiLabel lblViews = ui.AddLabel("lblViews", "Select views:", "Select views for which a BusinessEntity should be created."); lblViews.Width = btnSelectPath.Width / 2; lblViews.Left = lblTables.Left + lblTables.Width; lblViews.Top = lblTables.Top; GuiListBox lstViews = ui.AddListBox("lstViews", "Select views."); lstViews.Height = 170; lstViews.Width = btnSelectPath.Width / 2; lstViews.Left = lblViews.Left; lstViews.Enabled = true; // Attach the onchange event to the cmbDatabases control. setupDatabaseDropdown(cmbDatabases); cmbDatabases.AttachEvent("onchange", "cmbDatabases_onchange"); // Attach the onchange event to cbAbstractClasses and cbSealClasses, // if one is checked, the other should be disabled. cbAbstractClasses.AttachEvent("onclick", "cbAbstractClasses_onclick"); cbSealClasses.AttachEvent("onclick", "cbSealClasses_onclick"); ui.ShowGui = true; } else { ui.ShowGui = false; } } public void setupDatabaseDropdown(GuiComboBox cmbDatabases) { try { if (MyMeta.IsConnected) { cmbDatabases.BindData(MyMeta.Databases); if (MyMeta.DefaultDatabase != null) { cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Alias; bindTables(cmbDatabases.SelectedValue); bindViews(cmbDatabases.SelectedValue); } } } catch (Exception ex) { } } public void bindTables(string sDatabase) { int count = 0; GuiListBox lstTables = ui["lstTables"] as GuiListBox; try { IDatabase db = MyMeta.Databases[sDatabase]; lstTables.BindData(db.Tables); } catch (Exception ex) { } } public void bindViews(string sDatabase) { int count = 0; GuiListBox lstViews = ui["lstViews"] as GuiListBox; try { IDatabase db = MyMeta.Databases[sDatabase]; lstViews.BindData(db.Views); } catch (Exception ex) { } } public void cmbDatabases_onchange(GuiComboBox control) { GuiComboBox cmbDatabases = ui["cmbDatabase"] as GuiComboBox; bindTables(cmbDatabases.SelectedText); bindViews(cmbDatabases.SelectedText); } public void cbAbstractClasses_onclick(GuiCheckBox control) { GuiCheckBox cbAbstract = ui["cbAbstractClasses"] as GuiCheckBox; GuiCheckBox cbSeal = ui["cbSealClasses"] as GuiCheckBox; if(cbAbstract.Checked) { cbSeal.Enabled = false; } else { cbSeal.Enabled = true; } } public void cbSealClasses_onclick(GuiCheckBox control) { GuiCheckBox cbAbstract = ui["cbAbstractClasses"] as GuiCheckBox; GuiCheckBox cbSeal = ui["cbSealClasses"] as GuiCheckBox; if(cbSeal.Checked) { cbAbstract.Enabled = false; } else { cbAbstract.Enabled = true; } } public void cbProtectedDataMembers_onclick(GuiCheckBox control) { GuiCheckBox cbProtectedDataMembers = ui["cbProtectedDataMembers"] as GuiCheckBox; GuiLabel lblPrefix = ui["lblMemberPrefix"] as GuiLabel; GuiTextBox tbPrefix = ui["txtMemberPrefix"] as GuiTextBox; lblPrefix.Visible = cbProtectedDataMembers.Checked; tbPrefix.Visible = cbProtectedDataMembers.Checked; } } ##|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,System.Drawing.dll%><%#NAMESPACE System.Windows.Forms,System.Drawing%><% ////////////////////////////////////////////////////////////////////////////////////////////// // Gentle.NET Business Entity // C# class generation script for MyGeneration // (c) 2005 - Angelo Hulshout // (c) 2006 - Gerhard Junker // // This template script is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License 2.1 or later, as // published by the Free Software Foundation. See the license.txt file included in // the Gentle.NET distribution or the file MyGenTemplate_license.txt in the Gentle.NET // section of the MyGeneration Template Library. If neither of those available // or accessible, the license can be found at http://www.gnu.org/copyleft/lesser.html. // // The most current release of this template can be found at the MyGeneration template // library: http://www.mygenerationsoftware.com/TemplateLibrary // Working copies of new developments in between release versions are kept at the // the Gentle.NET Subversion archive (in the Contributions directory): // http://www.mertner.com/svn/repos/projects/gentle/ // // Revision info: // $LastChangedDate: 2010-08-12 13:45:08 +0100 $ // $LastChangedBy: gjunker $ // // // This template generates a VB class for each user selected table in a user selected database, // deriving each class from Gentle.FrameWork.Persistent class or a user defined class. // ////////////////////////////////////////////////////////////////////////////////////////////// public class GentleNETBusinessEntity : DotNetScriptTemplate { public GentleNETBusinessEntity(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 = "VB.NET"; MyMeta.DbTarget = "DbType"; // Initialize settings object // For convenience, we store it in m_UserScriptSettings here. // Other classes use GetInstance() to get access to settings. m_UserScriptSettings = ScriptSettings.InitInstance(input, MyMeta.Databases, DnpUtils); } private ScriptSettings m_UserScriptSettings; public override void Render() { //Uncomment following line to invoke JIT debugger //System.Diagnostics.Debugger.Launch(); // Generate progress window, to be used during rendering // of tables, relation tables and views Dnp.Utils.ProgressDialog progressDialog = new Dnp.Utils.ProgressDialog(); progressDialog.Show(); // Initialize progress bar for tables progressDialog.ProgressBar.Minimum = 0; progressDialog.ProgressBar.Maximum = m_UserScriptSettings.Tables.Count; progressDialog.ProgressBar.Value = 0; // Keep list of .cs files generated ArrayList csFiles = new ArrayList(); string outputFileName = ""; // Generate code for all selected tables foreach (string tableName in m_UserScriptSettings.Tables) { // Get table info - in order to get access to all properties, // and mainly the Alias. // TODO: replace all refs to table with refs to m_ActiveTable and m_ActiveTable.xxx GentleTable ActiveTable = new GentleTable(MyMeta.Databases[m_UserScriptSettings.DatabaseName].Tables[tableName], output); // Update progress bar progressDialog.Text = "Processing table " + ActiveTable.Name; progressDialog.ProgressBar.Value++; // Filename info outputFileName =m_UserScriptSettings.OutputPath; if (!outputFileName.EndsWith("\\") ) outputFileName += "\\"; outputFileName += ActiveTable.Alias; if(m_UserScriptSettings.PartialClasses) { outputFileName += ".generated"; } outputFileName += ".vb"; // Add file name to list, for display at end of code generation csFiles.Add( outputFileName ); if( m_UserScriptSettings.UsePreservation ) { output.setPreserveSource(outputFileName, "/***", "***/"); } // Render the table ActiveTable.Render(); // Save the results output.save(outputFileName, false); // keep output if only one file generated if(m_UserScriptSettings.Views.Count + m_UserScriptSettings.Tables.Count + m_UserScriptSettings.RelationTables.Count != 1) { output.clear(); } } // Initialize progress bar for tables progressDialog.ProgressBar.Minimum = 0; progressDialog.ProgressBar.Maximum = m_UserScriptSettings.RelationTables.Count; progressDialog.ProgressBar.Value = 0; // Generate code for all relation tables // TODO: This loop is based on an array that is modified in GentleRelation.RenderAsManyToMany // A cleaner solution is desirable!! foreach (string tableName in m_UserScriptSettings.RelationTables) { // Get table info - in order to get access to all properties, // and mainly the Alias. GentleTable ActiveTable = new GentleTable(MyMeta.Databases[m_UserScriptSettings.DatabaseName].Tables[tableName], output); // Update progress bar progressDialog.Text = "Processing relation " + ActiveTable.Name; progressDialog.ProgressBar.Value++; // Filename info outputFileName =m_UserScriptSettings.OutputPath; if (!outputFileName.EndsWith("\\") ) outputFileName += "\\"; outputFileName += ActiveTable.Alias; if(m_UserScriptSettings.PartialClasses) { outputFileName += ".generated"; } outputFileName += ".vb"; // Add file name to list, for display at end of code generation csFiles.Add( outputFileName ); if( m_UserScriptSettings.UsePreservation ) { output.setPreserveSource(outputFileName, "/***", "***/"); } // Render the table ActiveTable.Render(); // Save the results output.save(outputFileName, false); // keep output if only one file generated if(m_UserScriptSettings.Views.Count + m_UserScriptSettings.Tables.Count + m_UserScriptSettings.RelationTables.Count != 1) { output.clear(); } } // Initialize progress bar for views progressDialog.ProgressBar.Minimum = 0; progressDialog.ProgressBar.Maximum = m_UserScriptSettings.Views.Count; progressDialog.ProgressBar.Value = 0; // Generate code for all selected views foreach (string viewName in m_UserScriptSettings.Views) { // Get view info - in order to get access to all properties, // and mainly the Alias. GentleView ActiveView = new GentleView(MyMeta.Databases[m_UserScriptSettings.DatabaseName].Views[viewName], output); // Update progress bar progressDialog.Text = "Processing relation " + ActiveView.Name; progressDialog.ProgressBar.Value++; // Filename info outputFileName =m_UserScriptSettings.OutputPath; if (!outputFileName.EndsWith("\\") ) outputFileName += "\\"; outputFileName += ActiveView.Alias; if(m_UserScriptSettings.PartialClasses) { outputFileName += ".generated"; } outputFileName += ".vb"; // Add file name to list, for display at end of code generation csFiles.Add( outputFileName ); if( m_UserScriptSettings.UsePreservation ) { output.setPreserveSource(outputFileName, "/***", "***/"); } // Render the view ActiveView.Render(); // Save the results output.save(outputFileName, false); // keep output if only one file generated if(m_UserScriptSettings.Views.Count + m_UserScriptSettings.Tables.Count + m_UserScriptSettings.RelationTables.Count != 1) { output.clear(); } } progressDialog.Hide(); if(csFiles.Count == 1) { output.writeln("(Following lines are not part of generated file)" ); } output.writeln("Output directory " +m_UserScriptSettings.OutputPath ); output.writeln("Files generated:" ); foreach( string csFile in csFiles ) { output.writeln( csFile ); } MyMeta.SaveUserMetaData(); } // Render() } // class GeneratedTemplate /// GentleTable class - a utility wrapper around a MyMeta.ITable public class GentleTable { public enum ConstructorParameters { All, AllAutoKeys, AllExceptAutoKeys, NonNullAndNoAutoKeys, PrimaryKeys, None } protected ScriptSettings m_UserScriptSettings; // TODO: replace with getinstance everywhere protected ArrayList m_PrimaryKeys = null; protected MyMeta.ITable m_ITable; protected Zeus.IZeusOutput output; //TODO: replace with m_output public GentleTable( MyMeta.ITable table, Zeus.IZeusOutput outputDest ) { m_ITable = table; m_UserScriptSettings = ScriptSettings.GetInstance(); output = outputDest; } public IList PrimaryKeys { get { if(m_PrimaryKeys != null) { return m_PrimaryKeys; } // Not initialized yet, so fill it first m_PrimaryKeys = new ArrayList(); foreach( Column c in m_ITable.Columns ) { if(c.IsInPrimaryKey ) { m_PrimaryKeys.Add(c.Alias); } } return m_PrimaryKeys; } } public bool HasOnlyAutoKeys { get { foreach( Column c in m_ITable.PrimaryKeys ) { if(!c.IsAutoKey) { return false; } } return true; } } public bool HasAutoKeys { get { foreach( Column c in m_ITable.PrimaryKeys ) { if(c.IsAutoKey) { return true; } } return false; } } public bool HasRelations { get { return m_ITable.ForeignKeys.Count > 0; } } public ITable MyMetaTable { get { return m_ITable; } } public string Alias { get { return m_ITable.Alias.Trim(); } } public string Name { get { return m_ITable.Name.Trim(); } } public string CacheStrategy { get { if (m_ITable.Properties["CacheStrategy"] != null) { return m_ITable.Properties["CacheStrategy"].Value; } return "Temporary"; } } public void Render() { %>'======================================================================== ' This file was generated using the MyGeneration tool in combination ' with the Gentle.NET Business Entity template. '======================================================================== imports System.Collections imports System.Collections.Generic Imports Gentle Imports Gentle.Common imports Gentle.Framework <% if (m_UserScriptSettings.ReferencedNamespace!="") {%> Imports <%=m_UserScriptSettings.ReferencedNamespace%> <% }%> Namespace <%=m_UserScriptSettings.NameSpace %> ''' ''' Instances of this class represent the properties and methods of a row in the table <%= this.Name %>. ''' ", CacheStrategy.<%= this.CacheStrategy%>)> _ <%= m_UserScriptSettings.ClassModifiers %>class <%= StringFormatter.CheckAndSetPascalCasing(this.Alias) %> <%if(m_UserScriptSettings.BaseClass!="") output.write("Inherits");%> <%=m_UserScriptSettings.BaseClass%> <% // Main logic output.tabLevel++; output.tabLevel++; RenderDataMembers(); %> #Region "Constructors"<% //if (m_UserScriptSettings.CreateDefaultConstructor) { %> ''' ''' Create a new instance using the default constructor ''' <% RenderConstructor(ConstructorParameters.None); } //only create PK constructor if table has non autokeys if (m_UserScriptSettings.CreatePKConstructor && !HasOnlyAutoKeys) { %> ''' ''' Create a new instance using primaryKeys ''' <% RenderConstructor(ConstructorParameters.PrimaryKeys); } // If table has nullable items, generate a minimum info constructor. // If it only has nullable items, skip this, because it will likely be a duplicate if( HasNullable ) { %> ''' ''' Create a new object using the minimum required information ''' (all not-null fields except auto-generated primary keys). ''' <% RenderConstructor(ConstructorParameters.NonNullAndNoAutoKeys); } // if table has no autokeys, All and AllExceptNoAutoKeys generate the same // constructor. First check, then generate one or both if (HasAutoKeys || m_UserScriptSettings.GenerateSQLiteOID) { %> ''' ''' Create a new object by specifying all fields (except the auto-generated primary key field). ''' <% RenderConstructor( ConstructorParameters.AllExceptAutoKeys); } %> ''' ''' Create an object from an existing row of data. This will be used by Gentle to ''' construct objects from retrieved rows. ''' <% RenderConstructor( ConstructorParameters.All); output.autoTabLn("#End Region"); output.writeln(""); if (m_UserScriptSettings.ImplementNullPattern) RenderEmptyObject(); // Properties output.autoTabLn("#Region \"Public Properties\""); RenderProperties(); output.autoTabLn("#End Region"); // Debug and test properties //if(m_UserScriptSettings.GenerateDebugCode ) //{ //#Region "Debug Properties" // At present, no debug and test properties are generated by the template //#End Region //} // Instance storage and retrieval output.writeln(""); output.autoTabLn("#Region \"Storage and Retrieval\""); RenderListAllMethod(); RenderRetrieveMethod(); RenderComplexRetrieveMethod(); RenderPersistMethod(); // RenderRemoveMethod is not called right now, since it only reverts to the base class // Will be reintroduced if more code is needed there. RenderRemoveMethod(); output.autoTabLn("#End Region"); // Relations if( this.HasRelations ) { output.writeln(""); output.autoTabLn("#Region \"Relations\""); RenderRelations(); output.autoTabLn("#End Region"); } if( m_UserScriptSettings.UsePreservation ) { output.writeln(""); output.autoTabLn("#Region \"ManualCode\""); output.autoTab(output.getPreserveBlock("MANUAL_CODE")); output.writeln(""); output.autoTabLn("#End Region"); } output.tabLevel--; output.autoTabLn("End Class"); output.tabLevel--; %>End NameSpace <% } public void RenderDataMembers() { output.autoTabLn("#Region \"Members\""); output.autoTab("Private "); output.write(m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""); output.writeln("isChanged as boolean"); if(m_UserScriptSettings.GenerateSQLiteOID) { output.autoTabLn(" _"); output.autoTabLn("protected oid as long ;"); } foreach( Column c in m_ITable.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); currentColumn.RenderAsDataMember(); } output.autoTabLn("#End Region"); } public void RenderProperties() { %> ''' ''' Indicates whether the entity is changed and requires saving or not. ''' public ReadOnly Property IsChanged as Boolean Get Return <%=m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""%>isChanged End Get End Property <%if (m_UserScriptSettings.ImplementNullPattern) { %> public ReadOnly Property IsEmpty as Boolean Get Return Empty.Equals(Me) End Get End Property <% } if( m_UserScriptSettings.GenerateSQLiteOID ) { %> public ReadOnly Property OID as Long Get Return _oid End Get End Property <% } foreach( Column c in m_ITable.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); currentColumn.RenderAsProperty(true); } } private void RenderConstructorParameters(ConstructorParameters cp) { bool first = true; bool printIt; // Special case for SQLite OIDs!! if(cp==ConstructorParameters.All && m_UserScriptSettings.GenerateSQLiteOID) { output.write("ByVal OID as Long"); first = false; } foreach( Column c in m_ITable.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); printIt = false; switch(cp) { case ConstructorParameters.All: printIt = true; break; case ConstructorParameters.AllAutoKeys: if (currentColumn.MyMetaColumn.IsAutoKey) printIt = true; break; case ConstructorParameters.AllExceptAutoKeys: if(!currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.NonNullAndNoAutoKeys: if(!currentColumn.MyMetaColumn.IsNullable && !currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.PrimaryKeys: if (currentColumn.MyMetaColumn.IsInPrimaryKey && !currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; } if (currentColumn.MyMetaColumn.IsComputed) printIt = false; if(printIt) { if (!first) { output.write(", "); } if (currentColumn.Alias.ToLower() == "operator") output.write("ByVal [" + currentColumn.ToParameterName() + "] as " + currentColumn.LanguageType); else output.write("ByVal " + currentColumn.ToParameterName() + " as " + currentColumn.LanguageType); first = false; } } } private void AssignDataMembers( ConstructorParameters cp) { bool printIt; foreach( Column c in m_ITable.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); printIt = false; switch(cp) { case ConstructorParameters.All: printIt = true; break; case ConstructorParameters.AllExceptAutoKeys: if(!currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.NonNullAndNoAutoKeys: if( (!currentColumn.MyMetaColumn.IsNullable || currentColumn.MyMetaColumn.IsAutoKey) && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.PrimaryKeys: if (currentColumn.MyMetaColumn.IsInPrimaryKey && !currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; } if(printIt) { if(currentColumn.MyMetaColumn.IsAutoKey && cp != ConstructorParameters.All) output.autoTabLn(string.Format("{0} = 0", currentColumn.ToMemberName())); else { if (currentColumn.Alias.ToLower() == "operator") output.autoTabLn(string.Format("Me.{0} = [{1}]", currentColumn.ToPropertyName(), currentColumn.ToParameterName())); else output.autoTabLn(string.Format("Me.{0} = {1}", currentColumn.ToPropertyName(), currentColumn.ToParameterName())); } } } } public void RenderEmptyObject() { //bool first = true; %> #Region "Empty Reference Object" Public Shared ReadOnly Empty As <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> = new <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>() #End Region ' Empty Reference Object <% } public void RenderConstructor(ConstructorParameters cp) { if (!m_UserScriptSettings.CreateDefaultConstructor && cp == ConstructorParameters.None) output.autoTab("private "); else output.autoTab("public "); output.write( "Sub New("); output.tabLevel += 2; RenderConstructorParameters(cp); output.tabLevel -= 2; output.writeln(")"); output.tabLevel++; AssignDataMembers(cp); // set isChanged to true for new objects (not retrieved from DB) if (!m_UserScriptSettings.CreateDefaultConstructor && cp == ConstructorParameters.None) { output.autoTab(m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""); output.writeln("isChanged = False"); } else if( cp!=ConstructorParameters.All) { output.autoTab(m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""); output.writeln("isChanged = True"); } else if( cp==ConstructorParameters.All) //Write false, as it will be set to true when the properties are assigned { output.autoTab(m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""); output.writeln("isChanged = False"); } output.tabLevel--; output.autoTabLn("End Sub"); } public bool HasNullable { get { foreach( Column c in m_ITable.Columns ) { if(c.IsNullable) { return true; } } return false; } } public string PrimaryKeyName { get { IColumns keys = m_ITable.PrimaryKeys; if (keys.Count != 0) { return keys[0].Name; } return "(null)"; } } public string PrimaryKeyLanguageType { get { if(this.PrimaryKeyName=="(null)") { return "Object"; } else { GentleColumn c = new GentleColumn(m_ITable.Columns[this.PrimaryKeyName], output); return c.LanguageType; } } } public void RenderRetrieveMethod() { // If table has only one key, generate a simple retrieve function, using // a parameter of the correct language type as key value if(m_ITable.PrimaryKeys.Count > 0) { string tmp = ""; foreach( Column c in m_ITable.Columns ) { if(c.IsInPrimaryKey ) { if (tmp.Length > 0) tmp += ", "; tmp += "ByVal " + c.Alias + " as " + c.LanguageType; } } %> ''' ''' Retrieves an <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity given it's id. ''' Public <%=m_UserScriptSettings.BaseClass.ToLower() == "persistent" ? "Overloads " : ""%>Shared Function Retrieve(<%= tmp %>) as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> Dim pk as new Key(GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>), True) <% foreach( Column c in m_ITable.Columns ) { if(c.IsInPrimaryKey ) { %> pk.Add("<%= c.Name %>", <%= c.Alias %>) <% } } %> Dim tmp as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> = Framework.Broker.TryRetrieveInstance(of <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>)(pk) <% if (m_UserScriptSettings.ImplementNullPattern) { %> If tmp Is Nothing then Return Empty Else Return tmp End If<% } else { %> Return Tmp <% } %> End Function <% return; } // (m_ITable.PrimaryKeys.Count > 0) if(m_ITable.PrimaryKeys.Count<1) { %> ''' ''' Retrieves an <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity given it's id. ''' Public <%=m_UserScriptSettings.BaseClass.ToLower() == "persistent" ? "Overloads " : ""%>Shared Function Retrieve(ByVal id as <%=this.PrimaryKeyLanguageType%>) as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> throw new NotImplementedException("Gentle.NET Business Entity script: Table associated with this class has no primary key, so no simple retrieve function is generated."); End If <% return; } // generate method header and body %> ''' ''' Retrieves an <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity given it's id. ''' Public <%=m_UserScriptSettings.BaseClass.ToLower() == "persistent" ? "Overloads " : ""%>Shared Function Retrieve(ByVal id as <%=this.PrimaryKeyLanguageType%>) as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> <% if(m_ITable.Columns[PrimaryKeyName].IsAutoKey && m_UserScriptSettings.SeedCheck) { string checkCondition = "id<"+m_ITable.Columns[PrimaryKeyName].AutoKeySeed.ToString(); if( m_ITable.Columns[PrimaryKeyName].AutoKeySeed != m_ITable.Columns[PrimaryKeyName].AutoKeyIncrement) { checkCondition = checkCondition + " || id<" + m_ITable.Columns[PrimaryKeyName].AutoKeyIncrement.ToString(); } %> ' Return null if id is smaller than seed and/or increment for autokey If <%=checkCondition%> Then Return Nothing End If <%} %> Dim key as new Key(GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>), true, "<%=PrimaryKeyName%>", id) Dim tmp as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> = Framework.Broker.TryRetrieveInstance(of <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>)(key) <% if (m_UserScriptSettings.ImplementNullPattern) { %> If tmp Is Nothing then Return Empty Else Return tmp End If<% } else { %> Return Tmp <% } %> End Function <% } public void RenderComplexRetrieveMethod() { // generate method header and body %> ''' ''' Retrieves an <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity given it's id, using Gentle.Framework.Key class. ''' This allows retrieval based on multi-column keys. ''' Public <%=m_UserScriptSettings.BaseClass.ToLower() == "persistent" ? "Overloads " : ""%>Shared Function Retrieve(ByVal key as Key) as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> Dim tmp as <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> = Framework.Broker.TryRetrieveInstance(of <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>)(key) <% if (m_UserScriptSettings.ImplementNullPattern) { %> If tmp Is Nothing then Return Empty Else Return tmp End If<% } else { %> Return Tmp <% } %> End Function <% } public void RenderListAllMethod() { %> ''' ''' Static method to retrieve all <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> instances matching the key in one call ''' Public Shared Function ListAll() as iList(of <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>) <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_BeginListAll")); } %> return Framework.Broker.RetrieveList(of <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %>)() <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_EndListAll")); } %> End Function <% } public void RenderPersistMethod() { %> ''' ''' Persists the current <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity if it was never persisted or was changed. ''' Public Overrides Sub Persist() <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_BeginPersist")); } %> if (IsChanged Or (Not IsPersisted)) <%=m_UserScriptSettings.ImplementNullPattern ? "AND (Not IsEmpty)" : ""%> Then MyBase.Persist() <%=m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""%>isChanged = False End If <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( "\t" + output.getPreserveBlock("MANUAL_CODE_EndPersist")); } %> End Sub <% } public void RenderRemoveMethod() { %> ''' ''' Remove the current <%= StringFormatter.CheckAndSetPascalCasing(m_ITable.Alias) %> entity from the database. ''' public Overrides Sub Remove() <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_BeginRemove")); } if (m_UserScriptSettings.ImplementNullPattern) { %> If IsEmpty Then Return End If<% } %> MyBase.Remove() <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( "\t" + output.getPreserveBlock("MANUAL_CODE_EndRemove")); } %> End Sub <% } public void RenderRelations() { for (int k = 0; k < m_ITable.ForeignKeys.Count; k++) { IForeignKey fk = m_ITable.ForeignKeys[k]; bool multiples = false; for (int j = 0; j < m_ITable.ForeignKeys.Count; j++) if ( k != j) { IForeignKey fj = m_ITable.ForeignKeys[j]; if (fk.PrimaryTable.Name == fj.PrimaryTable.Name) if (fk.ForeignTable.Name == fj.ForeignTable.Name) if (fk.PrimaryColumns[0].Name == fj.PrimaryColumns[0].Name) { multiples = true; break; } } GentleRelation CurrentRelation = new GentleRelation( m_ITable, fk, output, multiples); // CurrentRelation.RenderForReporting(); CurrentRelation.Render(); } } } /// GentleTable class - a utility wrapper around a MyMeta.IView public class GentleView { public enum ConstructorParameters { All, AllAutoKeys, AllExceptAutoKeys, NonNullAndNoAutoKeys, } MyMeta.IView m_IView; protected ArrayList m_PrimaryKeys = null; ScriptSettings m_UserScriptSettings; Zeus.IZeusOutput output; public GentleView( MyMeta.IView view , Zeus.IZeusOutput outputDest ) { m_IView = view; m_UserScriptSettings = ScriptSettings.GetInstance(); output = outputDest; } public IView MyMetaView { get { return m_IView; } } public string Alias { get { return m_IView.Alias.Trim(); } } public string Name { get { return m_IView.Name.Trim(); } } private void RenderConstructorParameters(ConstructorParameters cp) { bool first = true; bool printIt; foreach( Column c in m_IView.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); printIt = false; switch(cp) { case ConstructorParameters.All: printIt = true; break; case ConstructorParameters.AllAutoKeys: if (currentColumn.MyMetaColumn.IsAutoKey) printIt = true; break; case ConstructorParameters.AllExceptAutoKeys: if(!currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.NonNullAndNoAutoKeys: if(!currentColumn.MyMetaColumn.IsNullable && currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; } if(printIt) { if (!first) { output.write(", "); } output.write(currentColumn.LanguageType + " " + currentColumn.ToMemberName()); first = false; } } } private void AssignDataMembers( ConstructorParameters cp) { bool printIt; foreach( Column c in m_IView.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); printIt = false; switch(cp) { case ConstructorParameters.All: printIt = true; break; case ConstructorParameters.AllExceptAutoKeys: if(!currentColumn.MyMetaColumn.IsAutoKey && !currentColumn.IsConcurrent) printIt = true; break; case ConstructorParameters.NonNullAndNoAutoKeys: if( (!currentColumn.MyMetaColumn.IsNullable || currentColumn.MyMetaColumn.IsAutoKey) && !currentColumn.IsConcurrent) printIt = true; break; } if(printIt) { string memberName = currentColumn.ToMemberName(); if(currentColumn.MyMetaColumn.IsAutoKey && cp != ConstructorParameters.All) output.autoTabLn(string.Format("{0} = 0;", memberName)); else output.autoTabLn(string.Format("Me.{0} = {0};", memberName)); } } } public void RenderConstructor( ConstructorParameters cp) { // public Employees( output.autoTab("public Sub New ("); output.tabLevel += 2; RenderConstructorParameters(cp); output.tabLevel -= 2; output.writeln(")"); output.tabLevel++; AssignDataMembers(cp); output.tabLevel--; output.autoTabLn("End Sub"); } public void RenderDataMembers() { output.autoTabLn("#Region \"Members\""); foreach( Column c in m_IView.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); currentColumn.RenderAsDataMember(); } output.autoTabLn("#End Region"); } public void RenderProperties() { foreach( Column c in m_IView.Columns ) { GentleColumn currentColumn = new GentleColumn(c, output); currentColumn.RenderAsProperty(false); } } public void RenderListAllMethod() { %> ''' ''' Generate a static method to retrieve all <%= StringFormatter.CheckAndSetPascalCasing(m_IView.Alias) %> instances of a class that are stored in the database ''' public Shared Function ListAll() IList(of <%= StringFormatter.CheckAndSetPascalCasing(this.Alias) %>) <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_BeginListAll")); } %> return Framework.Broker.RetrieveList(of (<%= StringFormatter.CheckAndSetPascalCasing(m_IView.Alias) %>)) <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_EndListAll")); } %> End Function <% } public void Render() { %> '======================================================================== ' This file was generated using MyGeneration in combination with the ' Gentle.NET Business Entity template. '======================================================================== Imports System.Collections Imports System.Collections.Generic Imports Gentle Imports Gentle.Common Imports Gentle.Framework <% if (m_UserScriptSettings.ReferencedNamespace!="") { %> using <%=m_UserScriptSettings.ReferencedNamespace%>; <% } %> namespace <%=m_UserScriptSettings.NameSpace %> { #Region "<%= StringFormatter.CheckAndSetPascalCasing(this.Alias) %>" ''' ''' Instances of this class represent the properties and methods of a row in the view <%= this.Name %>. ''' [TableName("<%= this.Name %>"<%output.write(", CacheStrategy.Never");%>)] <%= m_UserScriptSettings.ClassModifiers %> class <%= StringFormatter.CheckAndSetPascalCasing(this.Alias) %> <%if(m_UserScriptSettings.ViewBaseClass!="") output.write(" : ");%> <%=m_UserScriptSettings.ViewBaseClass%> { <% // Main logic output.tabLevel++; output.tabLevel++; RenderDataMembers(); %> #Region "Constructors" ''' ''' Create an object from an existing row of data. This will be used by Gentle to ''' construct objects from retrieved rows. ''' <% RenderConstructor( ConstructorParameters.All); output.autoTabLn("#End Region"); output.writeln(""); // Properties output.autoTabLn("#Region \"Public Properties\""); output.autoTabLn(""); RenderProperties(); RenderListAllMethod(); output.autoTabLn("#End Region"); // Debug and test properties //if(m_UserScriptSettings.GenerateDebugCode ) //{ //#Region "Debug Properties" //' At present, no debug and test properties are generated by the template //#End Region //} // Instance storage and retrieval // output.writeln(""); // output.autoTabLn("#Region \"Retrieval\""); // RenderRetrieveMethod(); // output.autoTabLn("#End Region"); if( m_UserScriptSettings.UsePreservation ) { output.autoTabLn("#Region \"ManualCode\""); output.autoTab(output.getPreserveBlock("MANUAL_CODE")); output.writeln(""); output.autoTabLn("#End Region"); } output.tabLevel--; output.autoTabLn("}"); %> } #End Region <% } } /// GentleTable class - a utility wrapper around a MyMeta.IView public class GentleColumn { protected MyMeta.IColumn m_IColumn; protected ScriptSettings m_UserScriptSettings; protected Zeus.IZeusOutput output; // TODO: replace with m_output public GentleColumn( MyMeta.IColumn column, Zeus.IZeusOutput outputDest ) { m_IColumn = column; m_UserScriptSettings = ScriptSettings.GetInstance(); output = outputDest; } public IColumn MyMetaColumn { get { return m_IColumn; } } public string Alias { get { return m_IColumn.Alias.Trim(); } } public string Name { get { return m_IColumn.Name.Trim(); } } public bool IsConcurrent { get { return (m_IColumn.Name == m_UserScriptSettings.ConcurrencyColumn); } } public void RenderPropertyAttribute() { string a = " _", foreignKey.PrimaryTable.Name, foreignKey.PrimaryColumns[0].Name); output.autoTabLn(a); } /// Column data type translation - currently only special case for mySQL enums /// LanguageType checks and returns special language types /// RenderLanguageDataType generates special data types like enums public string LanguageType { get { if( m_IColumn.DataTypeName == "ENUM" ) { return m_IColumn.Alias + "_Enum"; } else { return m_IColumn.LanguageType; } } } public void RenderLanguageDataType() { string typeString = ""; if( m_IColumn.DataTypeName == "ENUM" ) { typeString = "public enum " + m_IColumn.Alias + "_Enum{ IsEmpty, "; int start = m_IColumn.DataTypeNameComplete.IndexOf('(') + 1; int length = m_IColumn.DataTypeNameComplete.IndexOf(')') - start; typeString += m_IColumn.DataTypeNameComplete.Substring(start, length); typeString += " };"; typeString = typeString.Replace("'",""); } if( typeString != "" ) { output.autoTabLn( typeString ); } return; } // First character of parameters names is forced to lower case public string ToParameterName() { return StringFormatter.CheckAndSetCamelCasing(this.Alias); } // First character of member variable names is forced to lower case public string ToMemberName() { string tmp = StringFormatter.CheckAndSetCamelCasing(this.Alias); return m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix + tmp : tmp; } // First character of property names and constructor parameters is forced to lower case public string ToPropertyName() { return m_UserScriptSettings.DnpUtils.SetPascalCase(this.Alias); } public void RenderAsDataMember() { if(m_UserScriptSettings.DecorateMembers ) { // Foreign key attribute generation. Check for both IsInForeign and // IsInPrimary, otherwise self references will result in generation // of only Gentle ForeignKey attribute for the primary key if(m_IColumn.IsInForeignKey && !m_IColumn.IsInPrimaryKey) { RenderForeignKeyAttribute(); } else { RenderPropertyAttribute(); } } string defaultValue = ""; if (m_IColumn.HasDefault) { if (LanguageType == "String") { if ((m_IColumn.Default.IndexOf("N'") == 0) && (m_IColumn.Default.Length >= 3)) { defaultValue = string.Format(" = \"{0}\"", m_IColumn.Default.Substring(2, m_IColumn.Default.Length-3)); } else if ((m_IColumn.Default[0] == '\'') && m_IColumn.Default.Length > 1) { defaultValue = string.Format(" = \"{0}\"", m_IColumn.Default.Substring(1, m_IColumn.Default.Length-2)); } else if (m_IColumn.Default.ToLower() == "suser_sname()") { defaultValue = " = CStr(IIF(Environment.UserDomainName = String.empty, Environment.UserName ,Environment.UserDomainName & \"\\\" & Environment.UserName))"; } else { defaultValue = m_IColumn.Default; } if (defaultValue.Length == 0) { defaultValue = " = String.Empty"; } } else if (LanguageType == "Boolean") { bool defaultBool = (m_IColumn.Default == "1"); if (m_IColumn.Default == "1") { defaultValue = " = true"; } else { defaultValue = " = false"; } } else if (m_IColumn.DataTypeName == "ENUM") { defaultValue = string.Format(" = {0}.{1}",LanguageType,m_IColumn.Default); } else { defaultValue = string.Format(" = {0}", m_IColumn.Default); } } // If it was one of the follwing types, do not use a default except for some cases if (LanguageType == "DateTime") { if (m_IColumn.Default.ToLower() == "getdate()") defaultValue = " = now()"; } if (m_UserScriptSettings.ProtectedDataMembers) { output.autoTabLn("Protected " + ToMemberName() + " as " + LanguageType + defaultValue); } else { output.autoTabLn("Private " + ToMemberName() + " as " + LanguageType + defaultValue); } } public void RenderAsProperty(bool writable) { // Generate column specific datatype RenderLanguageDataType(); output.writeln(""); output.autoTabLn("''' "); output.autoTabLn("''' Property relating to database column "+this.Name); output.autoTabLn("''' "); if( !m_UserScriptSettings.DecorateMembers ) // if members not decorated, decorate properties { // Foreign key attribute generation. Check for both IsInForeign and // IsInPrimary, otherwise self references will result in generation // of only Gentle ForeignKey attribute for the primary key if(m_IColumn.IsInForeignKey && !m_IColumn.IsInPrimaryKey) { RenderForeignKeyAttribute(); } else { RenderPropertyAttribute(); } } output.autoTab("Public "); output.write(writable ? "" : "ReadOnly"); output.write("Property "); output.write(this.Alias.ToLower() == "operator" ? "[" + ToPropertyName() + "]" : ToPropertyName()); output.writeln(" as " + LanguageType); output.tabLevel++; output.autoTabLn("Get"); output.tabLevel++; string memberName = ToMemberName(); if( LanguageType == "string" && m_UserScriptSettings.TrimStrings) { if (m_IColumn.IsNullable) { %> <%=string.Format("If String.IsNullOrEmpty({0}) = False Then", memberName)%> <%=string.Format("Return {0}.TrimEnd()", memberName)%> Else <%=m_UserScriptSettings.ReturnEmptyStrings ? "Return String.Empty" : "Return Nothing"%> End If <% } else { output.autoTabLn(string.Format("Return {0}.TrimEnd()", memberName)); } } else { output.autoTabLn(string.Format("Return {0}", memberName)); } output.tabLevel--; output.autoTabLn("End Get"); if( (!writable) || (m_UserScriptSettings.DecorateMembers && (m_IColumn.IsAutoKey || m_IColumn.IsComputed))) // Do not generate set for readonly props { // No set{} method is generated if any of the following is true: // writable = false // attribute decoration is on members, and the key is database generated } else { %> Set (ByVal value as <%=LanguageType%>) <% if (m_UserScriptSettings.ImplementNullPattern) { %> If IsEmpty Then Return End If <% } %> If <%=memberName%> <> value Then <%=m_UserScriptSettings.UsePrefixedMemberNames ? m_UserScriptSettings.MemberPrefix : ""%>isChanged = True <%=memberName%> = value End If End Set <% } output.tabLevel--; output.autoTabLn("End Property"); } public void Render() { output.autoTabLn( "Column: " + this.Name ); } } //============================================================================= // Utility classes //============================================================================= /// Utility class for string formatting public class StringFormatter { public static string CamelCasing(string str) { if (str.Length > 0) { if (str.Length == 1) { return str.ToLower(); } else { return Char.ToLower(str[0]).ToString() + str.Substring(1); } } return string.Empty; } public static string PascalCasing(string str) { if (str.Length > 0) { if (str.Length == 1) { return str.ToUpper(); } else { return Char.ToUpper(str[0]).ToString() + str.Substring(1); } } return string.Empty; } public static string CheckAndSetCamelCasing(string myString) { ScriptSettings m_UserScriptSettings; m_UserScriptSettings = ScriptSettings.GetInstance(); if (m_UserScriptSettings.UsePascalStyle) { return m_UserScriptSettings.DnpUtils.SetCamelCase(myString); } else { return myString; } } public static string CheckAndSetPascalCasing(string myString) { ScriptSettings m_UserScriptSettings; m_UserScriptSettings = ScriptSettings.GetInstance(); if (m_UserScriptSettings.UsePascalStyle) { return m_UserScriptSettings.DnpUtils.SetPascalCase(myString); } else { return myString; } } } public class ScriptSettings { private IZeusInput m_Input = null; private MyMeta.IDatabases m_Databases = null; private ArrayList m_RelationTables; private Dnp.Utils.Utils m_DnpUtils; static private ScriptSettings _instance = null; protected ScriptSettings( IZeusInput i, MyMeta.IDatabases dbs, Dnp.Utils.Utils dnp ) { m_Input = i; m_Databases = dbs ; m_RelationTables = new ArrayList(); m_DnpUtils = dnp; } public static ScriptSettings GetInstance() { return _instance; } public static ScriptSettings InitInstance( IZeusInput i, MyMeta.IDatabases dbs, Dnp.Utils.Utils dnp ) { if( _instance == null ) { _instance = new ScriptSettings(i, dbs, dnp ); } return _instance; } 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 { return m_Input["lstTables"] as ArrayList; } } public ArrayList RelationTables { get { return m_RelationTables; } set { m_RelationTables = value; } } public ArrayList Views { get { return m_Input["lstViews"] 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 CreatePKConstructor { get { return (bool)m_Input["cbCreatePKConstructor"]; } } 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 += "NotInheritable "; } if(this.AbstractClasses) { modifiers += "MustInherit "; } if(this.PartialClasses) { modifiers += "Partial "; } return modifiers; } } public bool ReturnEmptyStrings { get { return (bool)m_Input["cbReturnStringEmpty"]; } } public string OutputPath { get { return m_Input["txtPath"].ToString(); } } 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 ImplementNullPattern { get { return (bool)m_Input["cbNullObjectPattern"]; } } 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 class GentleRelation { private IForeignKey m_ForeignKey; private ITable m_ReferenceTable; private bool m_AllFksArePks; private bool m_ForeignTableHasRequiredFields; private Zeus.IZeusOutput output; private ScriptSettings m_UserScriptSettings; private bool m_Multiple; public GentleRelation( ITable r, IForeignKey f, Zeus.IZeusOutput outputDest, bool Multiple ) { // The main sources of evil m_ForeignKey = f; m_ReferenceTable = r; m_Multiple = Multiple; // Output and settings output = outputDest; m_UserScriptSettings = ScriptSettings.GetInstance(); // A helper member to optimize speed of analysis m_AllFksArePks = true; for(int j = 0; j < m_ForeignKey.ForeignColumns.Count; j++) { IColumn fkColumn = m_ForeignKey.ForeignColumns[j]; IColumn pkColumn = m_ForeignKey.PrimaryColumns[j]; if (!fkColumn.IsInPrimaryKey || !pkColumn.IsInPrimaryKey) { m_AllFksArePks = false; } } // Another helper to optimize speed m_ForeignTableHasRequiredFields = false; for (int j = 0; j < m_ForeignKey.ForeignTable.Columns.Count; j++) { IColumn column = m_ForeignKey.ForeignTable.Columns[j]; if (!column.IsInPrimaryKey && !column.HasDefault && !column.IsComputed) { m_ForeignTableHasRequiredFields = true; break; } } } public bool IsMultiple { get { return m_Multiple; } } public ITable ForeignTable { get { return m_ForeignKey.ForeignTable; } } public ITable PrimaryTable { get { return m_ForeignKey.PrimaryTable; } } public string Alias { get { return m_ForeignKey.Alias; } } public string Type { get { return m_ForeignKey.Alias; } } public bool IsSelfReference { get { return m_ForeignKey.PrimaryTable.Name == m_ForeignKey.ForeignTable.Name; } } public bool IsOneToOne { get { // TODO: document the rationale of the if statement below if(!IsSelfReference && m_AllFksArePks && m_ReferenceTable.PrimaryKeys.Count == m_ForeignKey.ForeignTable.PrimaryKeys.Count ) { return true; } else { return false; } } } public bool IsZeroToMany { get { bool result = (m_ForeignKey.PrimaryTable.Name == m_ReferenceTable.Name) && (m_ForeignKey.ForeignTable.Name != m_ReferenceTable.Name); // TODO: document the rationale of the if statements below if(m_AllFksArePks && m_ReferenceTable.PrimaryKeys.Count == m_ForeignKey.ForeignTable.PrimaryKeys.Count ) { result = false; } if(IsSelfReference) { result = true; } return result; } } public bool IsManyToOne { get { bool result = (m_ForeignKey.ForeignTable.Name == m_ReferenceTable.Name) && (m_ForeignKey.PrimaryTable.Name != m_ReferenceTable.Name); // TODO: document the rationale of the if statements below if(m_AllFksArePks && m_ReferenceTable.PrimaryKeys.Count == m_ForeignKey.ForeignTable.PrimaryKeys.Count ) { result = false; } if(IsSelfReference) { result = true; } return result; } } public bool IsManyToMany { get { // TODO: document the rationale of the if statement below if(m_AllFksArePks && m_ReferenceTable.PrimaryKeys.Count < m_ForeignKey.ForeignTable.PrimaryKeys.Count ) { return true; } else { return false; } } } public bool ForeignTableHasRequiredFields { get { return m_ForeignTableHasRequiredFields; } } public bool IsCrossReference { get { return (!m_ForeignTableHasRequiredFields && IsManyToMany); } } public ITable CrossReferenceTable { get { if( IsCrossReference ) { for (int j = 0; j < m_ForeignKey.ForeignTable.ForeignKeys.Count; j++) { IForeignKey fk = m_ForeignKey.ForeignTable.ForeignKeys[j]; if ((fk.PrimaryTable.Name != m_ReferenceTable.Name) && (fk.PrimaryTable.Name != m_ForeignKey.ForeignTable.Name)) { if (fk.ForeignColumns[0].IsInPrimaryKey) { return fk.PrimaryTable; } } } } return null; } } public void Render() { // ManyToMany // if( IsManyToMany ) { RenderAsManyToMany(); return; } else { // ZeroToMany, ManyToOne and OneToOne for now result in identical code // This is probably not as bad as it seems, since it makes relations // bi-directional, at the slight drawback that a OneToOne returns a list RenderAsOneToMany(); return; } } public void RenderAsManyToMany() { // First of all, let's make sure code for the XRef table is generated, // by checking the main list of tables (and extending if necessary) if( !m_UserScriptSettings.Tables.Contains(m_ForeignKey.ForeignTable.Name) && !m_UserScriptSettings.RelationTables.Contains(m_ForeignKey.ForeignTable.Name)) { ArrayList tmp = m_UserScriptSettings.RelationTables; tmp.Add(m_ForeignKey.ForeignTable.Name); m_UserScriptSettings.RelationTables = tmp; } // Get foreign keys from the XRef table // Iterate over them and generate a referenced method for each one // Usually, n:m results in 1 loop (relation table has 2 fk's, but this // loop allows for ternary or worse as well foreach( IForeignKey rfk in m_ForeignKey.ForeignTable.ForeignKeys ) { string otherTableName; string otherTableAlias; if( rfk.ForeignTable.Name == m_ForeignKey.ForeignTable.Name ) { otherTableName = rfk.PrimaryTable.Name; otherTableAlias = rfk.PrimaryTable.Alias; } else { otherTableName = rfk.ForeignTable.Name; otherTableAlias = rfk.ForeignTable.Alias; } if( otherTableName != m_ReferenceTable.Name ) // skip self reference! { %> ''' ''' Return list of referenced objects from n:m relation with ''' table "<%=otherTableName%>", using relation "<%=rfk.Name%>" to Table "<%=m_ForeignKey.ForeignTable.Name%>" ''' public Function Referenced<%= StringFormatter.CheckAndSetPascalCasing(otherTableAlias) %>Using<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>() as IList <%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( output.getPreserveBlock("MANUAL_CODE_Begin"+StringFormatter.CheckAndSetPascalCasing(otherTableAlias))); } %> Return New GentleList(GetType(<%= StringFormatter.CheckAndSetPascalCasing(otherTableAlias) %>), Me, GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>))<%= if( m_UserScriptSettings.UsePreservation ) { output.autoTab( "\t" + output.getPreserveBlock("MANUAL_CODE_End"+StringFormatter.CheckAndSetPascalCasing(otherTableAlias))); } %> End Function <% } } } private string CplxName() { return "Using" + StringFormatter.CheckAndSetPascalCasing(this.Alias); } public void RenderAsOneToMany() { // If we are on the 'foreign' side of the relation (ManyToOne) // generate a key function returning the object we reference if( m_ForeignKey.ForeignTable.Name == m_ReferenceTable.Name ) //(ManyToOne) { %> ''' ''' Retrieve an single <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %> entity referenced from the current entity. ''' <% if (IsMultiple) { %> Public Function Referenced<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %><%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignColumns[0].Alias) %>() as <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %> <% } else // (!IsMultiple) { %> Public Function Referenced<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %>() as <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %> <% } // ISMultiple if (m_ForeignKey.ForeignColumns.Count == 1) { %> Dim tmp as <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %> = <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %>.Retrieve(<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignColumns[0].Alias) %>) <% } else // (m_ForeignKey.ForeignColumns.Count > 1) { %> Dim key as New Key(GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %>), True) <% for (int i = 0; i < m_ForeignKey.ForeignColumns.Count; i++) { %> key.Add("<%= m_ForeignKey.PrimaryColumns[i].Alias %>", <%= m_ForeignKey.ForeignColumns[i].Alias %>) <% } %> Dim tmp as <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %> = <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %>.Retrieve(key) <% } // (m_ForeignKey.ForeignColumns.Count > 1) if (m_UserScriptSettings.ImplementNullPattern) { %> If tmp Is Nothing then Return <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.PrimaryTable.Alias) %>.Empty Else Return tmp End If<% } else { %> Return Tmp <% } %> End Function <% } //(ManyToOne) // If we are on the 'primary' side of the relation (ZeroToMany, OneToOne) // generate a key function returning an IList containing all objects pointing // to ours if ( m_ForeignKey.PrimaryTable.Name == m_ReferenceTable.Name ) //(ZeroToMany, OneToOne) { %> ''' ''' Get a list of <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %> referring to the current entity. ''' <% if (IsMultiple) { %> public Function Referring<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %><%= CplxName() %>() as IList <% } else // (IsMultiple) { %> public Function Referring<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>() as IList(Of <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>) <% } // end (IsMultiple) %> 'select * from 'foreigntable' Dim sb as SqlBuilder = new SqlBuilder(StatementType.Select, GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>)) ' where foreigntable.foreignkey = ourprimarykey <% for (int i = 0; i < m_ForeignKey.ForeignColumns.Count; i++) { %> sb.AddConstraint([Operator].Equals, "<%=m_ForeignKey.ForeignColumns[i].Name%>", <%=m_ReferenceTable.PrimaryKeys[i].Name.ToString()%>) <% } %> ' passing true indicates that we'd like a list of elements, i.e. that no primary key ' constraints from the type being retrieved should be added to the statement Dim stmt as SqlStatement = sb.GetStatement(true) ' execute the statement/query and create a collection of User instances from the result set return ObjectFactory.GetCollection(Of <%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>)( stmt.Execute()) ' TODO In the end, a GentleList should be returned instead of an arraylist 'return new GentleList(GetType(<%= StringFormatter.CheckAndSetPascalCasing(m_ForeignKey.ForeignTable.Alias) %>), this ); End Function <% } // end ( m_ForeignKey.PrimaryTable.Name == m_ReferenceTable.Name ) } //RenderAsOneToMany() public void RenderForReporting() { output.writeln("\r\n/*\r\n *\tTable " + m_ReferenceTable.Name + "\tRelation " + this.Alias ); if( this.IsCrossReference ) output.writeln( " *\tcross reference" ); if( this.IsSelfReference ) output.writeln( " *\tself reference" ); if( this.IsOneToOne ) output.writeln( " *\tone to one" ); if( this.IsManyToOne ) output.writeln( " *\tmany to one" ); if( this.IsZeroToMany ) output.writeln( " *\tzero to many" ); if( this.IsManyToMany ) output.writeln( " *\tmany to many" ); if( this.IsMultiple ) output.writeln( " *\tmultiple references" ); output.writeln(" */\r\n"); } } %> ##|BODY_END