sany_ok

aulix.com/nhgen

Aug 23rd, 2014
587
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ' ========== THE AULIX nHibernate Generator (NHGen) - MyGeneration Extender for Aulix.Common7 framework ==========
  2. 'The AUTHOR of this file is Alexander Borisovich Prokopyev, Kurgan, Russia
  3. 'More info can be found at the AUTHOR's website:
  4. '   http://aulix.com/nhgen
  5. '   http://aulix.com/resume
  6. 'Contact: alexander.prokopyev at aulix dot com
  7. 'Copyright (c) Alexander Prokopyev, 2008
  8. 'All materials contained in this file are protected by copyright law.
  9. 'Nobody except the AUTHOR may alter or remove this copyright notice from copies of the content.
  10. 'This is a proprietary software
  11. 'The AUTHOR explicitly prohibits to use this source code by any method without a prior
  12. 'written hand-signed permission of the AUTHOR.
  13. ' ===========================================================
  14. ' This is a library to be used from http://www.mygenerationsoftware.com tool
  15. ' This extender generates a domain specific extension over generic Aulix.Common7.BL classes
  16. ' ===== An example of ZEUS template for aulix.com/adbm =====
  17. '<%#REFERENCE Aulix.NHGeneratorLib.dll%><%
  18. 'Public Class GeneratedTemplate
  19. '    Inherits DotNetScriptTemplate
  20. '    Public Sub New(ByVal context As ZeusContext)
  21. '        MyBase.New(context)
  22. '    End Sub
  23. '    '---------------------------------------------------
  24. '    ' Render() is where you want to write your logic    
  25. '    '---------------------------------------------------
  26. '    Public Overrides Sub Render()
  27. '        MyMeta.Connect("SQL", "Provider=sqloledb;Data Source=server_host,1433;Initial Catalog=DatabaseManager;User Id=sa;Password=xxx;")
  28. '        Dim CommandLine As String = _
  29. '         " -OutputDir1 Z:\Projects\Aulix\DatabaseManager\Src\NH\ -OutputName1 DatabaseManagerObjects " & _
  30. '         " -Namespace1 Aulix.DatabaseManager -Level1Class1 $1:^(.*)$:aulix_.* "
  31. '        Dim ML As New Aulix.NHGeneratorLib.MainClass
  32. '        ML.Process(MyMeta, CommandLine)
  33. '    End Sub
  34. 'End Class
  35. '%>
  36.  
  37.  
  38.  
  39. Imports Aulix.Common7.Utils
  40.  
  41. 'Level of inheritance may be in the range of 0..9
  42. 'The program is capable to produce several levels of inheritance provided the arguments for each level are numbered:
  43. '/OutputDirX= the directory where resulting files are placed
  44. '/NamespaceX=
  45. 'where X is a level number
  46. '   Class to table mapping is defined by: -LevelXClassY [ClassName]:TableName[(FieldRange)][:ExceptTableName]
  47. 'TableName and ExceptTableName can be specified by a regex with only single match possible
  48. '"*" can be used in the ClassName and then the actual matching value from TableName is substitued to the generated name of class.
  49. 'But mask use is allowed only for the classes without inheritance. All inherited classes require to be
  50. 'explicitelly defined by corresponding separated -LevelXClassY construct.
  51. 'FieldRange can be specified in two formats:
  52. '   as an actual range like: Field1..FieldN
  53. '   or as an enumeration like: Field1, Field2, Field3, FieldN
  54. 'Example:
  55. ' 1) Following is a TestClass2 which inherits TestClass1 and both of them share the same table TestTable1
  56. '       -Level1Class1 [TestClass1]:TestTable1(Id..SomeField1)
  57. '       -Level2Class1 [TestClass2]:TestTable1(SomeField2..SomeField3)
  58. ' 2) Following is a group of Aulix classes those do not participate in inheritance (all except aulix_User table):
  59. '       -Level1Class2 Aulix*:aulix_*:aulix_User
  60. 'in the above example generated classes will look like: AulixConfiguration, AulixProperty, etc.
  61. 'The program is also capable of generating DevExpress grid layout using Description dynamic field taken from MSSQL
  62. 'Generation is done for each class and is placed into the same directory where class definition is placed.
  63. 'The name of generated layout file looks like: ClassName & "Layout.xml" and is generated for all levels of inherited classes
  64. 'Such layout includes columns for related many-to-one columns as combo-box controls.
  65. 'This let make development of GUI really RAD.
  66.  
  67. Public Class MainClass
  68.     Public ShouldDebug As Boolean = False
  69.     Public Function Process(ByVal MyMeta_ As MyMeta.dbRoot, ByVal CommandLine_ As String, ByVal DB_ As MyMeta.IDatabase)
  70.         If ShouldDebug Then
  71.             System.Diagnostics.Debugger.Launch()
  72.         End If
  73.         MyMeta = MyMeta_
  74.         CommandLine = CommandLine_
  75.         DB = DB_
  76.         Main()
  77.     End Function
  78. End Class
  79.  
  80. Module MainModule
  81.     'Public ZeusContext As Zeus.ZeusContext
  82.    Public MyMeta As MyMeta.dbRoot
  83.     Public CommandLine As String
  84.  
  85.     Class ClassDef
  86.         Public Const MaxLevelNumber As Int32 = 9
  87.         Public Const MaxClassNumber As Int32 = 9
  88.         Public ClassName, TableName, ExceptTableName As String
  89.         Public TableNameRX, ExceptTableNameRX As Text.RegularExpressions.Regex
  90.         Public TableNameMatch, ExceptTableNameMatch As Text.RegularExpressions.Match
  91.  
  92.         Public Function RealClassName(Optional ByVal RealTableName_ As String = "") As String
  93.             If RealTableName_ = "" Then
  94.                 RealTableName_ = RealTableName
  95.             End If
  96.             RealClassName = TableNameRX.Replace(RealTableName_, ClassName)
  97.         End Function
  98.  
  99.         Public RealTableName As String
  100.         Public FromFieldName, ToFieldName As String
  101.         Public FieldList As String
  102.         Public ParentClassDefinition As ClassDef
  103.         Public IsInherited As Boolean
  104.         Public LevelNumber, ClassNumber As Int32
  105.         Public TableDef As MyMeta.ITable
  106.         Public ColumnDef As MyMeta.IColumn
  107.         Public Shared LevelCount As Int32
  108.         Public Shared Items(MaxLevelNumber, MaxClassNumber) As ClassDef
  109.     End Class
  110.  
  111.     Const AlwaysExcludeTables As String = "dtproperties_, sysconstraints_, syssegments_"
  112.     Dim OutputDir(ClassDef.MaxLevelNumber) As String
  113.     Dim OutputName(ClassDef.MaxLevelNumber) As String
  114.     Dim [Namespace](ClassDef.MaxLevelNumber) As String
  115.     Dim HBM_TS, VB_TS, FirstTime_VB_TS, LayoutTS As Scripting.TextStream
  116.     Public DB As MyMeta.IDatabase
  117.  
  118.  
  119.     Sub Main()
  120.         'DB = MyMeta.DefaultDatabase
  121.        Dim PS As New ParameterString(" " & CommandLine, " -", " ")
  122.         Dim I, J As Int32
  123.         For I = 1 To ClassDef.MaxLevelNumber
  124.             OutputDir(I) = PS.Value("OutputDir" & I)
  125.             If IsBlank(OutputDir(I)) Then
  126.                 If I = 1 Then
  127.                     Console.Write("Please specify the required parameter: -OutputDir1")
  128.                     Exit Sub
  129.                 Else
  130.                     ClassDef.LevelCount = I
  131.                 End If
  132.             End If
  133.  
  134.             OutputName(I) = PS.Value("OutputName" & I)
  135.             If IsBlank(OutputName(I)) Then
  136.                 If I = 1 Then
  137.                     OutputName(I) = DB.Name
  138.                 Else
  139.                     ClassDef.LevelCount = I
  140.                 End If
  141.             End If
  142.  
  143.             [Namespace](I) = PS.Value("Namespace" & I)
  144.             If IsBlank([Namespace](I)) Then
  145.                 If I = 1 Then
  146.                     Console.Write("Please specify the required parameter: -Namespace1")
  147.                     Exit Sub
  148.                 Else
  149.                     ClassDef.LevelCount = I
  150.                 End If
  151.             End If
  152.  
  153.             For J = 1 To ClassDef.MaxClassNumber 'All classes on this level
  154.                Dim LBS As String = PS.Value("Level" & I & "Class" & J)
  155.                 If IsBlank(LBS) Then
  156.                     ClassDef.Items(I, J) = Nothing
  157.                 Else
  158.                     Dim LBSParts() As String = Split(LBS, ":", 3)
  159.                     ClassDef.Items(I, J) = New ClassDef
  160.                     With ClassDef.Items(I, J)
  161.                         Select Case LBSParts.Length
  162.                             Case 1
  163.                                 .TableName = LBSParts(0)
  164.                                 .ClassName = .TableName & "_"
  165.                             Case 2, 3
  166.                                 .TableName = LBSParts(1)
  167.                                 .ClassName = LBSParts(0)
  168.                                 If LBSParts.Length = 3 Then
  169.                                     .ExceptTableName = LBSParts(2)
  170.                                 End If
  171.                         End Select
  172.                         'Postprocessing
  173.                        If .TableName <> "" Then
  174.                             Dim StartingBracketPos As Int32 = InStr(.TableName, "[", CompareMethod.Text)
  175.                             Dim EndingBracketPos As Int32 = InStr(.TableName, "]", CompareMethod.Text)
  176.                             If StartingBracketPos > 0 And EndingBracketPos > 0 Then
  177.                                 Dim FieldRange As String = Mid(.TableName, StartingBracketPos + 1, EndingBracketPos - StartingBracketPos - 1)
  178.                                 'Currently only from..to is implemented
  179.                                Dim FieldRangeParts() As String = Split(FieldRange, "..")
  180.                                 .FromFieldName = FieldRangeParts(0)
  181.                                 .ToFieldName = FieldRangeParts(1)
  182.                                 .TableName = Left(.TableName, StartingBracketPos - 1)
  183.                             End If
  184.                             .TableNameRX = New Text.RegularExpressions.Regex(.TableName, _
  185.                                 Text.RegularExpressions.RegexOptions.IgnoreCase And _
  186.                                 Text.RegularExpressions.RegexOptions.Singleline And _
  187.                                 Text.RegularExpressions.RegexOptions.ECMAScript)
  188.                             If IsBlank(.ExceptTableName) Then
  189.                                 .ExceptTableName = "Table name exclusion is not defined"
  190.                             End If
  191.                             .ExceptTableNameRX = New Text.RegularExpressions.Regex(.ExceptTableName, Text.RegularExpressions.RegexOptions.IgnoreCase And Text.RegularExpressions.RegexOptions.Singleline)
  192.                             .LevelNumber = I
  193.                             .ClassNumber = J
  194.                             If I > 0 And Not IsNothing(ClassDef.Items(I - 1, J)) Then
  195.                                 .ParentClassDefinition = ClassDef.Items(I - 1, J)
  196.                                 .IsInherited = True
  197.                             Else
  198.                                 .IsInherited = False
  199.                             End If
  200.                         End If '.TableName <> ""
  201.                    End With
  202.                 End If 'Not IsBlank(LBS)
  203.            Next
  204.         Next
  205.  
  206.         Dim FSO As New Scripting.FileSystemObject
  207.         For I = 1 To ClassDef.LevelCount
  208.             If Not LevelIsEmpty(I) Then
  209.                 HBM_TS = FSO.OpenTextFile(ConcatenatePathParts(OutputDir(I), OutputName(I) & ".hbm.xml"), Scripting.IOMode.ForWriting, True)
  210.                 VB_TS = FSO.OpenTextFile(ConcatenatePathParts(OutputDir(I), OutputName(I) & "_.vb"), Scripting.IOMode.ForWriting, True)
  211.                 FirstTime_VB_TS = FSO.OpenTextFile(ConcatenatePathParts(OutputDir(I), OutputName(I) & "FirstTime.vb"), Scripting.IOMode.ForWriting, True)
  212.                 HBM_TS.WriteLine("<?xml version=""1.0"" encoding=""utf-8"" ?>")
  213.                 HBM_TS.WriteLine("<hibernate-mapping xmlns=""urn:nhibernate-mapping-2.2"" default-access=""field"" assembly=""" & [Namespace](I) & """ namespace=""" & [Namespace](I) & """>")
  214.                 For Each T As MyMeta.ITable In DB.Tables 'where table_name<>'sysdiagrams'
  215.                    If Not (InStr(AlwaysExcludeTables, T.Name, CompareMethod.Text) > 0) Then
  216.                         Dim CD As ClassDef = FindTableClassDef(I, T.Name)
  217.                         If Not IsNothing(CD) Then
  218.                             ' ------------ Actual file generation
  219.                            CD.TableDef = T
  220.                             If CD.IsInherited Then
  221.                                 HBM_TS.WriteLine("  <subclass name=""" & CD.RealClassName & """ lazy=""false""  discriminator-value=""" & CD.RealClassName & """ extends=""" & _
  222.                                     [Namespace](I - 1) & "." & CD.ParentClassDefinition.RealClassName & "," & [Namespace](I - 1) & """>")
  223.                             Else
  224.                                 HBM_TS.WriteLine("  <class name=""" & CD.RealClassName(T.Name) & """ table=""" & T.Name & """ lazy=""false"">")
  225.                             End If
  226.                             VB_TS.WriteLine("Public Class " & CD.RealClassName(T.Name) & "_")
  227.                             If CD.IsInherited Then
  228.                                 VB_TS.WriteLine("   Inherits " & CD.ParentClassDefinition.RealClassName(T.Name))
  229.                             Else
  230.                                 VB_TS.WriteLine("   Inherits NHObject")
  231.                             End If
  232.                             FirstTime_VB_TS.WriteLine("Public Class " & CD.RealClassName(T.Name) & _
  233.                                 vbNewLine & "  Inherits " & CD.RealClassName(T.Name) & "_")
  234.                             Dim FieldRangeStarted, FieldRangeEnded As Boolean
  235.                             FieldRangeStarted = False
  236.                             FieldRangeEnded = False
  237.                             Dim ColNumber As Int32 = 0
  238.                             LayoutTS = FSO.OpenTextFile(ConcatenatePathParts(OutputDir(I), OutputName(I) & "_DXLayout_" & T.Name & ".xml"), Scripting.IOMode.ForWriting, True)
  239.                             LayoutTS.WriteLine("<XtraSerializer version=""1.0"" application=""View"">")
  240.                             LayoutTS.WriteLine("    <property name=""Columns"" iskey=""true"" value=""" & CD.TableDef.Columns.Count & """>")
  241.                             For Each CD.ColumnDef In CD.TableDef.Columns
  242.                                 ColNumber += 1
  243.                                 LayoutTS.WriteLine("        <property name=""Item" & ColNumber & """ isnull=""true"" iskey=""true"">")
  244.                                 Dim FieldDescription As String
  245.                                 If CD.ColumnDef.Name = "Id" Then
  246.                                     FieldDescription = "Id"
  247.                                 Else
  248.                                     FieldDescription = GetExtendedProperty(CD.ColumnDef, "MS_Description")
  249.                                 End If
  250.                                 LayoutTS.WriteLine("            <property name=""Caption"">" & FieldDescription & "</property>")
  251.                                 LayoutTS.WriteLine("            <property name=""ColumnEditName"" />")
  252.                                 LayoutTS.WriteLine("            <property name=""FieldName"">" & CD.ColumnDef.Name & "</property>")
  253.                                 LayoutTS.WriteLine("            <property name=""Visible"">true</property>")
  254.                                 LayoutTS.WriteLine("            <property name=""Name"">" & Replace(CD.ColumnDef.Name, " ", "") & "Col</property>")
  255.                                 LayoutTS.WriteLine("            <property name=""VisibleIndex"">" & ColNumber - 1 & "</property>")
  256.                                 LayoutTS.WriteLine("        </property>")
  257.                                 If CD.ColumnDef.Name = CD.FromFieldName Or CD.FromFieldName = "" Then
  258.                                     FieldRangeStarted = True
  259.                                 End If
  260.                                 If FieldRangeStarted And Not FieldRangeEnded Then
  261.                                     If CD.ColumnDef.IsInPrimaryKey Then
  262.                                         ProcessProperty(CD, PropertyProcessingType.Id)
  263.                                     ElseIf CD.ColumnDef.IsInForeignKey Then
  264.                                         ProcessProperty(CD, PropertyProcessingType.ManyToOne)
  265.                                     ElseIf Right(CD.ColumnDef.Name, 4) = "_EID" Then
  266.                                         ProcessProperty(CD, PropertyProcessingType.EnumID)
  267.                                     ElseIf CD.ColumnDef.Name = "NHDiscriminator" Then
  268.                                         ProcessProperty(CD, PropertyProcessingType.Discriminator)
  269.                                     Else
  270.                                         Dim CustomType As String = GetExtendedProperty(CD.ColumnDef, "CustomType")
  271.                                         If Not IsBlank(CustomType) Then
  272.                                             ProcessProperty(CD, PropertyProcessingType.CustomType, CustomType)
  273.                                         Else
  274.                                             ProcessProperty(CD, PropertyProcessingType.General)
  275.                                         End If
  276.                                     End If
  277.                                 End If
  278.                                 If CD.ColumnDef.Name = CD.ToFieldName Then
  279.                                     FieldRangeEnded = True
  280.                                 End If
  281.                             Next 'Each CD.ColumnDef In CD.TableDef.Columns
  282.                            LayoutTS.WriteLine("</property></XtraSerializer>")
  283.                             LayoutTS.Close()
  284.                             FirstTime_VB_TS.WriteLine("End Class")
  285.                             VB_TS.WriteLine("End Class")
  286.                             If CD.IsInherited Then
  287.                                 HBM_TS.WriteLine("  </subclass>")
  288.                             Else
  289.                                 HBM_TS.WriteLine("  </class>")
  290.                             End If
  291.                             Console.WriteLine("Generated class for table: " & T.Name)
  292.                             ' ------------------------------------
  293.                        End If 'Not IsNothing(CD)
  294.                    End If ' Not InStr(AlwaysExcludeTables,...)
  295.                Next ' For Each T
  296.                HBM_TS.WriteLine("</hibernate-mapping>")
  297.                 FirstTime_VB_TS.Close()
  298.                 VB_TS.Close()
  299.                 HBM_TS.Close()
  300.             End If 'Not LevelIsEmpty(I)
  301.        Next
  302.     End Sub
  303.     Function LevelIsEmpty(ByVal ClassLevel As Integer) As Boolean
  304.         For I As Integer = 1 To ClassDef.MaxClassNumber
  305.             If Not IsNothing(ClassDef.Items(ClassLevel, I)) Then
  306.                 LevelIsEmpty = False
  307.                 Exit Function
  308.             End If
  309.         Next
  310.         LevelIsEmpty = True
  311.     End Function
  312.     Function GetExtendedProperty(ByVal S As MyMeta.Single, ByVal PropertyName As String) As String
  313.         Dim EP As MyMeta.KeyValueCollection = S.DatabaseSpecificMetaData("ExtendedProperties")
  314.         Dim VP As MyMeta.KeyValuePair
  315.         Do While EP.MoveNext()
  316.             VP = EP.Current
  317.             If StrComp(VP.Key, PropertyName, CompareMethod.Text) = 0 Then
  318.                 GetExtendedProperty = VP.Value
  319.                 Exit Do
  320.             End If
  321.         Loop
  322.     End Function
  323.  
  324.     'Writes each property to class file based on previously collected information
  325.    Function ProcessProperty(ByVal CD As ClassDef, ByVal PPT As PropertyProcessingType, Optional ByVal Info As String = "")
  326.         Dim PropertyName As String = CD.ColumnDef.Name
  327.         Dim PropertyTypeName As String = CD.ColumnDef.LanguageType
  328.         Select Case PPT
  329.             Case PropertyProcessingType.Id
  330.                 HBM_TS.WriteLine("      <id name=""" & CD.ColumnDef.Name & """ column=""" & CD.ColumnDef.Name & """ type=""" & CD.ColumnDef.LanguageType & """ unsaved-value=""0""><generator class=""native""/></id>")
  331.             Case PropertyProcessingType.EnumID
  332.                 PropertyTypeName = Left(CD.ColumnDef.Name, Len(CD.ColumnDef.Name) - 4) & "Enum"
  333.                 HBM_TS.WriteLine("      <property name=""" & CD.ColumnDef.Name & """/>")
  334.             Case PropertyProcessingType.CustomType
  335.                 PropertyTypeName = Info
  336.                 HBM_TS.WriteLine("      <property name=""" & CD.ColumnDef.Name & """/>")
  337.             Case PropertyProcessingType.General
  338.                 If InStr(CD.ColumnDef.LanguageType, "DateTime", CompareMethod.Text) > 0 Then
  339.                     PropertyTypeName &= " = #1/1/1900#"
  340.                 End If
  341.                 HBM_TS.WriteLine("      <property name=""" & CD.ColumnDef.Name & """/>")
  342.             Case PropertyProcessingType.Discriminator
  343.                 PropertyName = ""
  344.                 HBM_TS.WriteLine("      <discriminator column=""NHDiscriminator"" type=""String""/>")
  345.             Case PropertyProcessingType.ManyToOne
  346.                 Dim FK As MyMeta.IForeignKey = CD.ColumnDef.ForeignKeys(0)
  347.                 Dim RelatedTable As MyMeta.ITable = FK.PrimaryTable
  348.                 Dim TableClassDef As ClassDef = FindTableClassDef(CD.LevelNumber, RelatedTable.Name, True)
  349.                 If IsNothing(TableClassDef) Then
  350.                     VB_TS.WriteLine("'Error! : TableClassDef corresponding to " & RelatedTable.Name & " has not been found.  PropertyProcessingType has been changed to General. ")
  351.                     ProcessProperty(CD, PropertyProcessingType.General)
  352.                     Exit Function
  353.                 Else
  354.                     PropertyTypeName = TableClassDef.RealClassName(RelatedTable.Name)
  355.                     If StrComp(Right(CD.ColumnDef.Name, 2), "Id", CompareMethod.Text) = 0 Then
  356.                         PropertyName = Left(CD.ColumnDef.Name, Len(CD.ColumnDef.Name) - 2)
  357.                     End If
  358.                     HBM_TS.WriteLine("      <many-to-one name=""" & PropertyName & """ column=""" & CD.ColumnDef.Name & """ class=""" & PropertyTypeName & """ />")
  359.                 End If
  360.         End Select
  361.         If PropertyName <> "" And PPT <> PropertyProcessingType.Id Then
  362.             VB_TS.WriteLine("   Public [" & PropertyName & "] As " & PropertyTypeName)
  363.         End If
  364.     End Function
  365.  
  366.     Enum PropertyProcessingType
  367.         Id
  368.         General
  369.         Discriminator
  370.         ManyToOne
  371.         EnumID
  372.         CustomType
  373.     End Enum
  374.  
  375.     'Finds a class corresponding to a table at a specific inheritance level
  376.    Function FindTableClassDef(ByVal LevelNumber As Int32, ByVal TableName As String, Optional ByVal IncludeLowerLevels As Boolean = False) As ClassDef
  377.         For J As Int32 = 1 To ClassDef.MaxClassNumber
  378.             If Not IsNothing(ClassDef.Items(LevelNumber, J)) Then
  379.                 With ClassDef.Items(LevelNumber, J)
  380.                     .TableNameMatch = .TableNameRX.Match(TableName)
  381.                     .ExceptTableNameMatch = .ExceptTableNameRX.Match(TableName)
  382.                     If .TableNameMatch.Success And Not .ExceptTableNameMatch.Success Then
  383.                         If .IsInherited Then
  384.                             .RealTableName = TableName
  385.                             .ParentClassDefinition.RealTableName = TableName
  386.                         End If
  387.                         FindTableClassDef = ClassDef.Items(LevelNumber, J)
  388.                         Exit Function
  389.                     End If
  390.                 End With
  391.             End If
  392.         Next
  393.         If IsNothing(FindTableClassDef) And LevelNumber > 1 And IncludeLowerLevels Then
  394.             FindTableClassDef = FindTableClassDef(LevelNumber - 1, TableName, True)
  395.         End If
  396.     End Function
  397. End Module
Advertisement
Add Comment
Please, Sign In to add comment