• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 745
  • Last Modified:

How to compare objects across libraries to ensure they came from the same source.

I want to compare files and programs in various libraries on an IBM i5 to make sure they all came from the same source compiled at the same time.  For instance, if I compiled my file on a development machine and then moved it to another machine into different libraries, how can I check to make sure they were all compiled at the same time from the same source?  The problem our shop is facing is that developers do not always remember to copy the objects they've installed into production into other libraries which emulate production.  The file structures should be the same even if the data in one comes from production and the data in the others are a subset of productions.  Likewise, I need to check programs for the same reasons.  I ran the DSPOBJD command on a file in various libraries and although they may have the same creation date, the file levels are different for all of them when I run the DSPFD command.  I would have expected them to be  the same if they were compiled around the same time using the same source.  Am I doing something wrong or is my logic faulty using the file level and creation date?

Thank you!
5 Solutions
When a file is created, the system assigns a format level identifier based on the file attributes, including field names, sizes, types, etc. It does not matter when the file is created, if its attributes are the same then the format level identifier is the same. In your case, if the format level identifiers are different, then the files are somehow different.

Here is a snippet from the IBM infocenter that describes how format level identifers are created:

The server assigns a unique level identifier for each record format when it creates the associated file. The server uses the following information to determine the level identifier:
Record format name
Field name
Total length of the record format
Number of fields in the record format
Field attributes (for example, length and decimal positions)
Order of the field in the record format

This is a piece of a DSPFD output, just to ensure we are talking about the same thing:
Record Format List                                          
                       Record  Format Level                  
 Format       Fields   Length  Identifier                    
 OUTFM            77     1452  3EB4DE5D2D6FB                
   Text . . . . . . . . . . . . . . . . . . . :              
 Total number of formats  . . . . . . . . . . :           1  
 Total number of fields . . . . . . . . . . . :          77  
 Total record length  . . . . . . . . . . . . :        1452  

The next step would be to use DSPFFD output to outfile of both versions of the file, and compare them to see what is different.

If you have any questions, post back!
I seam to recall that the CCSID can change the file level id.

that could account for the file difference - check the format level id's

running the DSPOBJD command with DETAIL(*SERVICE) will show you the exact source file and member, as well as the source member timestamp during the object creation.
2 programs in different libraries may have different creation dates, but if the source is exactly the same then the programs are very likely to be the same.

You will have to create a smart report showing irregularities in the production environment:
Programs created from invalid source libraries.
Source version mismatch between production and test.
When source information is not available, different creation times.
etc... whatever suites your particular needs.

Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

Important note... ILE *PGM objects aren't created from source, but rather from *MODULE objects. Therefore, DSPOBJD *SERVICE against the programs won't help. Use DSPPGM DETAIL(*MODULE) to see the list of modules in an ILE program; then use DSPOBJD DETAIL(*SERVICE) against each module to see source info.

Also, DSPPGM DETAIL(*MODULE) only outputs to the screen or to a printer file. In order to get useful module info, I use the QBNLPGMI API to list modules into a user space. I process the list and pass extracted values into an SQL insert to build a quick table of modules for query purposes.

Added note... DSPPGMREF can output record format IDs for database files referenced in a program.

Added note... I've put a basic ILE CL source at http://pastebin.com/666287 that extracts some module info and INSERTs it into a simple table in QGPL (or wherever you create it; a sample CREATE TABLE is in a comment). It calls a proc named someDYNSQL which isn't included, but numerous dynamic SQL functions are available on the 'net in almost every programming language -- just google, download one and change the CALLPRC to whatever's appropriate.

Two parms come in -- the first names a library, all *PGMs in this library are run through the QBNLPGMI API; the second controls whether a user space is created or the previous is reused.

It's a very basic tool, but might help illustrate getting source info from ILE *PGMs.


Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now