This is an occasional blog about IET's use of CA Gen for internal development as well as thoughts, tips and techniques on using CA Gen for application development. It is aimed at the CA Gen development professional, so please excuse the jargon and assumed level of knowledge about CA Gen. Reference will also be made to our products to put the development into context, so if you are not familiar with these, please visit the IET web site by clicking on the company logo.
Wednesday, 13 January 2010
Mapping Group Views
However the view match remains intact even if you then subsequently change the cardinality of the sending view to a value that is greater than the receiving view, so you could end up with a sending view that is larger than the receiving view, which could then cause unexpected results, like loss of data without a runtime error. In this case, you could not establish the view match again, but the existing view match is still 'valid' in the model.
If the group view sizes were initially the same, the developer might not think that they need to add in any extra validation logic, but a subsequent change to one of the group views might then cause problems.
A new check in VerifIEr allows a quick check for differing group view cardinalities with a warning if they differ but are valid and an error if they differ and are invalid.
Monday, 21 December 2009
Discovering hidden errors
The initial checks were primarily aimed at standards enforcement, for example, object names, CBD architecture enforcement, use (or abuse) of various properties (e.g. READ properties), etc.
More recently however we have developed a number of checks for customers that are aimed at improving code quality by detecting errors that might be otherwise difficult to find.
We have run these checks on our own products (which are developed with Gen) and have been surprised at the number of potential errors that have been encountered. Usually the more serious errors are detected during testing, but sometimes not!
Examples of the checks that we have found especially useful include:
- Local views that are referenced but never set to a value, indicating that either the local views need to be populated or the code is no longer required;
- Hidden fields (for example fields on a GUI that are placed above the top border) that are not read-only (the user could therefore tab to the field and change its value);
- Export views not fully mapped to an import view on a screen or window;
- Checking the tab sequence for GUI windows and dialog boxes;
These sorts of errors are notoriously difficult to spot via code inspection and can also be missed during testing.
Wednesday, 9 December 2009
Gen r8 Beta Testing
We have started our beta testing of the next Gen release (r8). There are a large number of new and changed features that will keep us busy with the development of the 8.0 release of our products that will support Gen r8.
A number of customers have asked about the availability of IET products to support their beta testing of Gen r8. Unfortunately we have only been able to start development of Release 8.0 of our products with the start of the beta programme and hence cannot offer a beta version of our products until this development work is complete.
Thursday, 22 October 2009
Unused and Duplicate Prompts
Apart from having a large number of redundant prompts in the models, it can also make the selection of prompts in the window/screen designer tedious because the large lists of unused and duplicate prompts makes locating the desired prompt harder.
There is a Gen function in the toolset to delete unused prompts, but this requires the model to be downloaded, and ours are too big. It will also not get rid of duplicates.
We have therefore written a new genIE function to both delete unused and consolidate duplicate prompts.
The result is faster downloads because you are not downloading extra prompts and also easier selection of existing prompts in the window/screen designer.
Thursday, 1 October 2009
RI Trigger Impact Analysis
The Gen model does contain associations between action blocks and RI triggers (using IMPUSE associations if you are familiar with the Gen schema), but the important point to note is that these associations are maintained by the code generators. This means that if you change the data model, the IMPUSE association data in the model is not accurate until you have regenerated the affected code, which makes it useless in helping you understand what you need to regenerate!
We faced this issue when developing the impact analysis process that GuardIEn performs when it detects data model changes. To work out what RI triggers are directly affected by a data model change is straight forward, but the consequential impact on other triggers and action block / procedure steps involves a complex navigation though the data model, following cascade delete chains for example. It is also affected by the choice of generated or DBMS enforced RI rules.
Tuesday, 29 September 2009
RI Triggers
In many cases, users think that they only need to regenerate the RI triggers once they have made their data model changes. Unfortunately it is more complex than that.
The correct process is:
1) Implement any changes to table or column names in the data structure
2) Run the Ref. Integrity Process (accessed from the toolset Design menu) to synchronise the technical design RI constraints with the data model
3) Generate the affected RI triggers
4) Re-generate all action blocks that call the re-generated RI triggers
5) Install re-generated code
Steps (1) and (2) can either be performed separately or accomplished using the Retransformation tool.
The reason why you need to regenerate the action blocks that call the RI triggers is that the code generated for a DELETE, DISASSOCIATE, TRANSFER, etc. depends on the RI rules in the model. If these rules change (for example changing a relationship from cascade delete to pendent delete), then the action blocks require regeneration as well as the RI triggers.
Tuesday, 22 September 2009
Where is your source code?
- External Action Blocks
- OLE files
- Bitmaps, icons
- DDL
- Documentation
- etc.
Unfortunately we often come across projects that do not adequately manage the non-Gen source code, probably because they do not have this issue with the Gen code. There are cases of projects where they have lost their EAB source code and do not even have documentation for what the EAB did apart from the stubs in the Gen model.
Another common instance is where you use an OCX control in a GUI design. Gen creates a .ole file in the local workstation model sub-directory which contains properties for the OCX control. However this is not uploaded to the model, so if you delete the local model directory and have not saved the .ole files elsewhere, they are lost!
You should therefore take care that all project source code is properly managed. This could be as basic as ensuring that the files are stored centrally in a place where they will not be deleted, either accidentally or as part of a housekeeping routine.
Even better, the external code should be properly versioned controlled. There are many tools for this, ranging from simple and free source code control tools to more sophisticated products. Our own XOS tool has been designed specifically for managing Gen externals, including support for automatically versioning .ole files when a subset is uploaded to the encyclopaedia.
Wednesday, 26 August 2009
An unexpected feature of Object Migration
An unexpected feature of the CA Gen object migration utility that sometimes catches us out is when you migrate an action block and the view matching of action blocks that use it is also affected.
Consider the example where AB1 uses AB2. If you add a new import view to AB2 and view match it to an existing view in AB1:
AB1:
USE AB2
IMPORTS: temp xxx to in xxx
and then migrate just AB2 to another model, if the view temp xxx in AB1 has common ancestry between the two models, then the view match is also migrated, which in effect modifies AB1 even though this had not been selected for migrate. However AB1 does not get a modified timestamp, so it looks like AB1 has not changed even though its view matching has.
This may not necessarily create a problem, but it does sometimes cause confusion.
Friday, 14 August 2009
Gen and null columns
A recent posting on the Duick forum regarding NULL column support lead to a discussion on the Gen qualifier IS EQUIVALENT TO and a potential misinterpretation of the way that this works.
As a bid of background information, it is important to understand how a nullable column containing a NULL value behaves. Consider a table with a nullable column and these rows:
Id opt_column
1 ' ' (column has a value of spaces)
2 NULL(column is NULL
3 'X' (column has a value of X)
If you want a value of NULL to be equivalent to SPACES, and you want to read rows that have a space or null in the opt_column, then if your SQL was:
SELECT * FROM table WHERE opt_column = ' ';
would return just row 1 but
SELECT * FROM table WHERE opt_column = ' ' OR opt_column IS NULL;
would return rows 1 and 2
If you want to read rows that do not have ‘X’:
SELECT * FROM table WHERE opt_column != 'X';
would return just row 1 but
SELECT * FROM table WHERE opt_column != 'X' OR opt_column IS NULL;
would return rows 1 and 2
Once you understand the need for the IS NULL or IS NOT NULL qualifier in the SQL, you can write the READ qualifiers in the action diagram code.
The confusion arises over the use of the IS EQUIVALENT TO clause since it is likely that this does not work the way you expect!
For example, if an optional column has no value, then I think of SPACES & NULL as the same, so you would code:
READ table WHERE opt_column = SPACES OR opt_column IS NULL
However the statement READ table WHERE opt_column IS EQUIVALENT TO SPACES
gives the following SQL which is not the same:
SELECT opt_column FROM table
WHERE (opt_column = ' ' AND opt_column IS NOT NULL)
This means that if the column is NULL it will not return a row, which is the opposite of what I think you want.
IS EQUIVALENT TO
READ table WHERE opt_column = ‘X’ AND opt_column IS NOT NULL
Is the same as READ table WHERE opt_column IS EQUIVALENT TO ‘X’
which gives the following SQL:
SELECT opt_column FROM table
WHERE (opt_column = 'X' AND opt_column IS NOT NULL)
IS NOT EQUIVALENT also gives the desired result for a specific value but not for SPACES:
READ table WHERE opt_column NOT = ‘X’ OR opt_column IS NULL
and READ table WHERE opt_column IS NOT EQUIVALENT TO ‘X’ gives:
SELECT opt_column FROM table
WHERE (opt_column <> 'X' OR opt_column IS NULL)
But if you want a row where the column is not spaces, you would code:
READ table WHERE opt_column NOT = SPACES AND opt_column IS NOT NULL
but READ table WHERE opt_column IS NOT EQUIVALENT TO SPACES gives:
SELECT opt_column FROM table
WHERE (opt_column <> ' ' OR opt_column IS NULL)
In summary, it is best not to use EQUIVALENT with SPACES unless you want the behaviour that the generated code gives you. You would also need to be careful with a view that might have a value of spaces.
Thursday, 13 August 2009
Documenting Changes
A customer recently complemented us on the quality of our release notes and asked whether we generated them from a database.?
Unfortunately there wasn’t a magic solution. We cut and paste the descriptions of each change into a Word document and then generate the PDF file from that. That part is simple though. The harder part is to ensure that each change is documented properly and is not accidentally omitted from the release notes. We therefore document the changes using the following process:
1) Each change must be documented in a form that will make sense to the end user, explaining the business reason for the enhancement or requirement for a fix. The documentation is in the long description of the Change Request (CR) in GuardIEn.
2) Each CR should address a single problem or enhancement. You should avoid CRs that span multiple requirements (the worst cases being a single CR that has all changes in it or a CR for changes made by a developer that is not linked to the actual requirements.
3) If a new requirement is found whilst changing some code, a new CR should be created for it and the temptation to ‘hide’ the new requirement within the scope of the existing CR avoided.
4) Once the CR has been completed and tested, the description should be reviewed for accuracy and any changes in behaviour noted.
5) The Release Notes should be updated with the CR and user documentation reviewed and updated as necessary. We have a separate state in the CR life-cycle to indicate that the documentation has been updated.