Skip to content

MOGLiCC Tutorial Part C

iks github user edited this page Apr 4, 2016 · 29 revisions

C) Applying the ClassBasedFileMaker: Separating class specific output

Let's assume that the requirements exist, that 1. not only one big sql statement is needed but that 2. for each database table an insert.sql is required bundling all insert statements of the respective table and that 3. a mechanism is needed to exclude selectively individual classes (i.e. database table) from generation. To realize these two new features, one could use the ModelBasedLineInserter, but for each model class a separate input artefact would be necessary. This solution is very inefficient. Therefore, we will apply the ClassBasedFileMaker which is much smarter in this case!

1 - The very first thing to do now is to create a new template file for the ClassBasedFileMaker. For this purpose create the file ./input/VelocityClassBasedFileMaker/BundledInsertSQLScripts/Main.tpl with the following content:

@TargetFileName $classDescriptor.name.sql
@NameOfValidModel InsertSQL
@CreateNew true

#set( $tableName = $classDescriptor.getMetaInfoValueFor("tableName") )
INSERT INTO $tableName ($commaSeparatedListOfAttributes) VALUES ($commaSeparatedListOfTableValues);

The content of the BundledInsertSQLScripts folder represents the input artefact for the VelocityClassBasedFileMaker. Delete all other folders in files in ./input/VelocityClassBasedFileMaker - we don't need this stuff in this tutorial.

2 - After executing MOGLiCC, several observations are worth making. Firstly, the generation report tells us that the FileMaker plugin has been active. Unfortunately, the file name is faulty. Secondly, since no property @targetDir is provided in the template header, the generation result is only present in the plugin's output directory ./input/VelocityClassBasedFileMaker/BundledInsertSQLScripts. Thirdly, the content of the generated file contains only one line and the used Velocity variables could obviously not be replaced. What we do now is, that we correct the value of the @TargetFileName property. Velocity allows two syntax alternatives for using a variable:

# this alternative is more readable, 
# but requires a space or linebreak before and behind it
$firstSyntaxForCallingAVelocityVariable    

# this alternative is less readable, 
# but appropriate to embed its use into a sequence of chars
${secondSyntaxForCallingAVelocityVariable}

To get along in our situation we apply the second alternative:

@TargetFileName ${classDescriptor.name}.sql

3 - After rerunning MOGLiCC, for each class in the model file a sql file has been generated in ./input/VelocityClassBasedFileMaker/BundledInsertSQLScripts:

ORDER.sql
REMITTER.sql

It is good practise to use filenames read from metainfos, however, since you have learned to do so in a previous tutorial part, we skip that here. For the ongoing tutorial you should skip that too, in order to avoid deviations from later tutorial parts. Instead, we care now and here about the file contents.

Go back to the Main.tpl of the VelocityModelBasedLineInserter and view the template body. It contains an outer foreach loop for the file descriptors. Copy all the content within this loop (all lines between #foreach and #end) and replace the existing template body of the Main.tpl of the FileMaker by this copy. Note, that the FileMaker is implemented to be ClassBased. It does not need the whole model, instead its templates can address the classDescriptors directly! Having started MOGLiCC you find that all FileMaker made output files contain the correct content and the first goal of the tutorial part (bundled generation of table specific sql scripts) is already attained.

4 - In order to suppress a single class, the FileMaker offers the helpful artefact property SkipGeneration. To use this property, we add the following line to the template header of the FileMaker's main template:

@SkipGeneration $classDescriptor.getMetaInfoValueFor("skip")

If we run MOGLiCC after this modifaction we get the error "MetaInfo unkown to the model: !MetaInfo FOR 'skip' NOT FOUND!". The SkipGeneration property expects true or false. There are three ways around this problem:

  1. Adding the metainfo skip to all classes (we don't do that - no metainfo should mean "use default").
  2. Adding the following artefact property:
@CheckMissingMetaInfos false

We don't do that, because we want to be warned if that happens. 3. We modify the SkipGeneration expression like that:

@SkipGeneration $classDescriptor.doesHaveAnyMetaInfosWithName("skip")

There is a disadvantage of this solution which we will see soon. Running MOGLiCC gives the same result. Now we test the skip mechanism by adding

metainfo skip true

to one of the two classes in our model file. 5 - Rerun MOGLiCC and you see that only one Bundled SQL file has been created. Ok, that's good. Now set the skip metainfo to false. Rerun MOGLiCC and see that this setting does not work. Instead we have to remove the skip metainfo or to commit it out. To make that clear, we write a comment in the model file:

metainfo skip true   # ATTENTION: setting skip to false won't work, instead remove this metainfo or comment it out

6 - What is still missing? - Well, we have to introduce the skip mechanism in the big sql file. For this purpose, we have to modify the Main.tpl of the LineInserter. The body of this template file should look like that:

#set( $classDescriptorList = $model.getClassDescriptorList() )
#foreach( $classDescriptor in $classDescriptorList )
    #if( ! $classDescriptor.doesHaveAnyMetaInfosWithName("skip") )

        ...     all the lines here remain the same, but are enclosed by the new if clause

    #end	
#end

7 - Restart MOGLiCC and see that both the bundled SQL files and the big SQL file contain only the class (e.g. the database table) without the skip metainfo. To have all classes again included in the out put, we set in the model file

**#**metainfo skip true   # ATTENTION: setting skip to false won't work, instead remove this metainfo or comment it out

8 - In the very end, we want to have all output artefacts in one target directory. For that purpose we modify the template headers of the three input artefacts like that:

Modify in VelocityModelBasedLineInserter/InsertSQL/Main.tpl:

@TargetDir <applicationRootDir>/InsertSQL

Add to VelocityClassBasedFileMaker/InsertSQL/Main.tpl:

@TargetDir <applicationRootDir>/InsertSQL/singleStatements

Add to VelocityClassBasedFileMaker/BundleSQL/Main.tpl:

@TargetDir <applicationRootDir>/InsertSQL/bundledStatements

Ideally, the name of the target directory should be defined once as metainfo of the model in the model file. Here it is hard coded and would have to be changed thrice if required. Anyway, rerun MOGLiCC and have a look into the new target directory. We have it!

Back to the tutorial main page

Next tutorial part

Clone this wiki locally