What next?

My regular followers for which there are many. I am pleased to say that I have over 100 unique visitors per month visiting the blog and the number is increasing. If have dabbled with a mixture of real life stories and content, technical 2e content, management styles, observations about software development and a couple of other stories related to me and my experiences as long as there is a loose IT twist.

I have spent much of the last two months writing more about 2E. I plan to finish off my posts in this area over the coming months and years. I certainly have plenty of material left.

Finish 2e Development Standards
Model Management
Database Administration Guides
Advanced Development Techniques
Model Tidy
Modernisation Options for 2E generated systems
Plex Development

........ are all blog series candidates in their own right.

I thought that I'd take a week off this week and ask you the readership what you would like to see. The hits to date make it a worthwhile exercise for me to put this content on the web. If you have any content you wish to share, requests for additional coverage then place a comment on the blog and I'd be happy to start doing some of this for you.

So.

Let me know. I reckon I have a year or two left in me looking at my current roadmap. A little more now won't hurt.

I look forward to hearing from you.

Thanks for reading the
Synon 2E and Plex Emporium by Lee Dare (A developer blog). 
Lee.

Synon 2e Development Standards - (Composite Functions) CRTOBJ/CHGOBJ

Synon 2E Development Standards CRTOBJ CHGOBJ


Update: 05/12/2025 - I have created a page for all standards related posts.
Today's topic is composite functions.

I have said before that there are many ways to skin a cat and with development regardless of tools and languages used, it is no different.

To date I have concentrated on the generic principles of development and also on the CA 2E tool from Computer Associates. I have put quite a few posts in place around 2E with many many more to go. To be honest I am less than 20% through what I intend to post from the technical perspective and I have barely touched the Plex product. Still good things come to those who wait.

http://www.dictionary.com/ has the definition of 'composite' as "made up of disparate or separate parts or elements". In 2E terms it means the linking of two or more functions to serve a business purpose. For example to clear a file using 2e function types you may either call a EXCUSRPGM and use the operating system or you may chose to use a RTVOBJ with no restrictor/positioner keys and then call a DLTOBJ for each record in the file. You could also call a SQL routine, embed the OS400 command in a message etc etc etc. You get my point. The composite in this example is the RTVOBJ/DLTOBJ combination.

There are other composite types that are more often encountered. Especially around creating or changing records in a database file (table for the SQLites amongst you).

I have created functions named CRT/CHG or CHG/CRT to solve a common problem of what do do if the record does or does not already exist in the database.

This lead me to consider is there is a preferred default method and are there any variations. Once again a big thanks to Ray for his contributions here.

CHG/CRT v CRT/CHG

There are times when if a CRTOBJ fails due to the record already being in existence or a CHGOBJ fails because the record does not exist. To solve these issues we generally create combination functions named either CRT/CHG or CHG/CRT. Or if you follow my recommended standards and if these are default functions then they would be named *CRT/CHG or *CHG/CRT.

In general you should select the one that is most likely to succeed, so depending on your knowledge of the environment and the data being processed, if the record is likely to not be there then you need to use the CRT/CHG combo.

There are some performance considerations over and above the availability or otherwise of the underlying record.

A CHGOBJ that contains a CRTOBJ if a record does not exist is inefficient as it generates the following code. This is particularly true for SQL generation.

Pseudo SQL Code

DECLARE CURSOR FOR UPDATE
FETCH
UPDATE if record found
INSERT if no record found
CLOSE CURSOR

Pseudo RPG Code

CHAIN
UPDATE if record found
SETLL & INSERT if no record found

An alternative coding style with a CRTOBJ calling a CHGOBJ if record already exists will generate the following code. The CHGOBJ must be an 'update style' that does not use a cursor.

Pseudo SQL Code

SELECT by key
INSERT if record not found
UPDATE if record exists

Pseudo RPG Code

SETLL
WRITE if record not found
CHAIN & UPDATE if record exists

A CHGOBJ with a little bit of grunt.

To create an 'Update style' CHGOBJ:-

For performance reasons we need to omit the prior SELECT generated for SQL CHGOBJs. This is mainly for CHGOBJs called repeatedly in batch type processing. But it can only be done if there is no requirement to read existing DB1 context fields. To do an immediate update we need to create a special version of a CHGOBJ called an UPDATE function. This will have following characteristics:-

1 - Ensure that there is no coding inside the CHGOBJ. Commonly we must transfer the timestamp coding from inside the CHGOBJ to input parameters and setting the timestamp fields directly on the CHGOBJ call.

2 - Ensure that the CHGOBJ parameters are defined in the default way using the UPD ACP structure. Fields that do not need to be changed should be made NEITHER parameters.

3 - The CHGOBJ function option for Null Update Suppression should be = No. This ensures that there is no attempt to perform an image check.

4 - UPD style CHGOBJs should ideally only have the attributes that are being changed. This is particularly important when calling a CHGOBJ from inside a RTVOBJ over the same file. Passing in DB1 context for those filed not being changed is not conducive to performance since the optimiser cannot differentiate between changed & non changed attributes.

Thoughts, opinions, concerns or fanmail gratefully accepted. Cash donations to charity please.

Thanks for reading the
Synon 2E and Plex Emporium by Lee Dare (A developer blog). 
Lee.

Synon 2e Development Standards - (Hints and Tips DLTOBJ)

Synon 2E Development Standards DLTOBJ


Update: 05/12/2025 - I have created a page for all standards related posts.

The humble DLTOBJ is the topic of this weeks post. This finishes of the series on the main 2e internal function types. I have covered the RTVOBJ, CRTOBJ and CHGOBJ so far. Next weeks post will be about the mertis of using a CRT/CHG or CHG/CRT combination function.

Following that I will be blogging about standards for EXCUSRSRC, EXCUSRPGM and the EXCINTFUN/EXCEXTFUN function types before moving on to a series on the screen function types.

So plenty to get though over the next few weeks. For those of you following the series, bare with me as I get these completed and published.

Back to today's topic. The delete object (DLTOBJ).

General considerations.

Only one DLTOBJ, the default (*DLT), should be present on any file. It will have no action diagram coding added.

If other associated files must be deleted or updated at the same time as the DLTOBJ. An EXCINTFUN or RTVOBJ should be created as a standard wrapper and named *DLT (Cascade).

You can use a DLTOBJ to clear an array. Simply create the DLTOBJ function over the array and remove all keys. Note this technique is not applicable for files. You should prefix the array clearing delete with CLR. I.e. "CLR Standards Sample" dropping the ARY prefix from the actual array. Note: If using the Cobol generator then this is inefficient and you are better to use the traditional RTVOBJ/DLTOBJ approach.

Auditing at record level. Remember that you no not need to add auditing records for any entry you are deleting.

Gotcha's

It is not possible to suppress the error message if the record to be deleted does not exist. Therefore if the DLTOBJ is conditional it should be called from a RTVOBJ based over the same file. Note: If called directly then the *Return code must be set to *Normal as deleting a record that is no there is generally not considered and trapped as an error.

Thanks for reading the
Synon 2E and Plex Emporium by Lee Dare (A developer blog). 
Lee.

Synon 2e Development Standards - (Hints and Tips CHGOBJ)

Synon 2E Development Standards - CHGOBJ


Update: 05/12/2025 - I have created a page for all standards related posts.

Another post about some of the finer points for the internals functions available in the 2e tool. I have covered off the RTVOBJ and CRTOBJ in some detail. I have left the obvious stuff for the user manuals and am really covering off best practices and gotchas in these sections.

Any observations and comments are gratefully received and a big shout out to Ray Weekes who passed on many of these in these sections from his experience.

The default CHGOBJ will have all parameters open except for Time Stamp and any other derived attributes which will all be made NEITHER. Action diagram coding added will only be for Time Stamp and derived data i.e. Audit records or calculated values.

Further CHGOBJ functions may be created where only subsets of attributes are to be changed or where special processing is applicable. All CHGOBJs should replicate the standard support for Time Stamp and derived data where appropriate.

Structuring your parameters. There are 2 methods for defining a CHGOBJ where only subsets of attributes are to be changed. The default method uses the UPD ACP RCD defined over the first parameter block line as the input parameter list. Database attributes not to be automatically changed from input parameter fields are set to NEITHER.

The second method uses the UPD ACP KEY as the first input parameter list line. The UPD ACP RCD is then optionally used on the second parameter line. This second approach suppresses any automatic update to the DB1 context and therefore requires a *MOVE ALL PAR to DB1 to be added to USER:After DBF Read. This KEY method has the advantage that no NEITHER parameters need be defined and no unnecessary coding is generated for NEITHER parameters.

It also protects the CHGOBJ from the effects of future attributes being added to the file.

The default RCD method of a defining CHGOBJ is sufficient for most small files or where most attributes are being replaced. The KEY method is preferred for large files where only a few attributes are being changed. It is also the preferred method on any file where existing database attributes are being incremented rather than replaced with new parameter input values since it makes the action diagram coding simpler. E.g. A CHGOBJ designed to get the next surrogate# to be used.

General pointers.

It is possible to suppress the default error message if the record does not exist by setting PGM.*Return Code = *Normal in USER:Record Not Found. Alternatively you may add a call to a CRTOBJ over the same file. But if the CRTOBJ is conditional then still set PGM.Return Code = *Normal where CRTOBJ is not called.

Any UPD ACP RCD parameter field defined as OUPUT or BOTH will be automatically moved from DB1 context to PAR context after the database update. This allows a CHGOBJ to also function like a RTVOBJ GET and to return current database values.

When using a CHGOBJ to increment values on a database remember to move the current DB1 values to a holding field as the PAR to DB1 move will overwrite the original values. Then in the Process before Update you do the *ADD arithmetic. A good standard could be to prefix the function like UPD nnnnnnnnnnnnnn.

Null update suppression is the preferred choice for all CHGOBJs. Model value YNLLUPD=*AFTREAD. This means that an image check takes place after USER:After DBF Read. The USER: Before DBF Update is only executed if the record image has been changed. Time Stamp logic and other derived processing must therefore be in USER: Before DBF Update.

In general do not use a CHGOBJ to change the primary key. Although this technique works in RPG it causes problems in COBOL. However, it may be used in RPG & SQL. SQL CHGOBJ requires the key fields to be set to MAP to force them into the SET clause.

Gotcha's

You must never *QUIT from a CHGOBJ since this may leave a lock on the record. Use PGM.*Record Changed = *Yes if any conditional processing is required inside the CHGOBJ.

Do not use a CHGOBJ or DLTOBJ over a PHY ACP because of a bug in the 2E SQL generator.
Next time the DLTOBJ.

Thanks for reading the
Synon 2E and Plex Emporium by Lee Dare (A developer blog). 
Lee.

Synon 2e Development Standards - (Hints and Tips CRTOBJ)

Synon 2E Development Standards - CRTOBJ


Update: 05/12/2025 - I have created a page for all standards related posts.

Here we go again. Another in the series around 2e development standards. Today I thought I'd cover the CRTOBJ function type and share what I have gathered on the road over the years.

Cutting straight to the point.

Keep numbers to a minimum. In general there should only be one CRTOBJ, i.e. The default (*CRT), per file. This will have all or most parameters open and will not contain any complex processing. This makes the function reusable. The exception being surrogates that are generated inside the function and control fields like audit stamps.

These will generally be set to NEITHER and primed inside the function.

The exception to one per file would be for files that are archived or image copied. But this would not in general usage be the default *CRT. I.e. CRT Archive Image.

Shielding developers from the parameters. For simple files where records are only created under standard application control then time stamp fields may be set as NEITHER parameters and the DB1 context primed inside the CRTOBJ. Similarly, where an internal surrogate number is generated as part of the primary key then an appropriate function call over another file may be inserted. The surrogate number will normally be NEITHER, but it may be OUTPUT or BOTH if required for lower level files.

Wrappering the CRTOBJ with an internal. In some cases there may be a hierarchy of EXCINTFUN calls. Each call then performing some specific function at one level before calling the next level. This may be necessary, for example, because associated files have to be updated when a new record is created. Each main line request to create a new record will call the EXCINTFUN appropriate to the level of complexity required. If requiring just an image copy then it will call the CRTOBJ direct.

An EXCINTFUN designed to participate in the create process should have its parameters defined using the UPD ACP RCD, similar to a CRTOBJ.

Be aware of the probability of a records existence. Where it is not clear whether a record exists for a given primary key then it may be necessary to define a special CRTOBJ i.e. CRT/CHG, which suppresses the error condition and optionally changes the record. I will post a CHG/CRT v CRT/CHG vs RTV/CHG or RTV/CRT debate once I have covered off the intricacies of each of the four main internal function types.

Gotchas

To suppress the error message & error condition if a record already exists then a CRTOBJ may be created where the PGM.*Return Code is set to *Normal in USER:Record Already Exists.

Alternatively if a record already exists and it is appropriate to change attributes then a call to a CHGOBJ may be inserted in USER:Record Already Exists. In this case it is important to ensure that the parameters passed to the CHGOBJ are PAR and not DB1 context.

It is very important in any CRTOBJ to ensure that the DB1 context for any fields not directly input by parameters are initialised or primed with data inside the CRTOBJ. (They will not be input if they are set to NEITHER or if the parameter definition is changed to KEY). There is no automatic move from PAR to DB1 for NEITHER parameters and the DB1 context may contain old data from previous database functions.

By default a SQL CRTOBJ will not check for duplicate records if there is no coding in any action diagram user point other than ‘Processing Before Data Update’. However, there are times when you must or it would be better if you did check. This is accomplished by inserting code, such as comments, in ‘Processing if Record Exists’. This also suppresses the error message if the row already exists.
Next up. The CHGOBJ.

Thanks for reading the
Synon 2E and Plex Emporium by Lee Dare (A developer blog). 
Lee.