This is the second of a 10-part series of articles about MANASYS Jazz. Click here to see the previous article, What is MANASYS Jazz?
Jazz
programs are concise, typically 1/20th as many lines of code as the
resulting COBOL. In this extreme
case dialogs produced 2500 lines of COBOL and 1000 lines of C# from 21
lines of Jazz data definition. How is
this done?
With “What, not How”, Chris Date identified the key concept that drives our software, inspiring the way Jazz defines data. Complete data definitions largely eliminate the need for procedural code to access, format, and validate data. Jazz data definitions allow you to fully define record and field properties, making MANASYS very powerful.
This article shows how data is defined, and how these definitions are used by MANASYS. For a quick introduction, see the first two minutes of the Initial Demonstration video.
Import from COBOL, from SQL, or from Easytrieve gives a quick start, but these only give a record layout – a list of fields and formats. They may tell you nothing about the file, nothing about data relationships, and minimal information about data validity and display. By adding this missing information, we won’t have to supply this missing information in the traditional way, which is writing procedural code in COBOL (or Java or …) in each relevant program.
Here are 2 definitions, initially created with Import-From-COBOL and Import-From-SQL, and then edited as highlighted.
*# Last Updated by JAZZUSR at 29/10/2021 2:04:01 PM COPY Types; COPY FR; DEFINE CustF VSAM DATA( Account PIC '999999' KEY, Region DECIMAL(3) EXISTS FR.Region, District DECIMAL(3) RANGE(1:10), Name CHAR(30) CAPS DKEY 'jazzuser.vsam.custf1' GENERIC, SalesThisMonth MONEY(7,2), SalesYTD MONEY(7,2), Billingcycle LIKE Types.Month, DateCommenced DATE DPIC 'dd mmm yyyy') DSNAME 'JAZZUSER.VSAM.CUSTF'; |
COPY Department; DEFINE EMPLOYEE
SQL DATA( EMPNO CHAR(6) PIC '999999'
REQUIRED KEY, FIRSTNME
VARCHAR(12) REQUIRED, MIDINIT CHAR (1), LASTNAME
VARCHAR(15) REQUIRED, WORKDEPT
CHAR(3) CAPS DKEY 'XEMP2' EXISTS DEPARTMENT.DEPTNO, PHONENO CHAR(4) PIC '9999', HIREDATE
DATE, JOB CHAR(8), EDLEVEL SMALLINT REQUIRED, SEX CHAR(1) CAPS CODES(M:Male, F:Female), BIRTHDATE
DATE, SALARY MONEY(9,2) MIN 0, … DEPTMGR BOOLEAN); |
Most importantly, we’ve described the file type. CustF has type VSAM, located through DSNAME 'JAZZUSER.VSAM.CUSTF'. It’s unique key is Account, it has a duplicate (generic) key on Name, accessed through alternate index 'jazzuser.vsam.custf1'. EMPLOYEE is an SQL record (table).
MANASYS now knows how to open the file, and what GET and PROCESS need to do read records. Programs using Custf will Open the file and use READ and WRITE statements, or CICS equivalents. Programs using Employee will connect to the database and use EXEC SQL statements.
DATA is followed by fields, each with a name, type, [and other properties]. Any COBOL layout can be expressed in Jazz, but it will look different: -
· Level numbers are not used, instead GROUP/END GROUP denotes lower-level fields. GROUPs may contain GROUPs.
· Type names are more like SQL than COBOL. For example, DECIMAL and MONEY are COBOL COMP-3 fields.
· EXISTS FR.Region and EXISTS DEPARTMENT.DEPTNO specify inter-record relationships. Thus a CustF.Region value is only valid if an FR record can be found with its value. FR.Region must be the primary key of FR.
Changing field types can unlock Jazz features.
· CustF.SalesThisMonth, CustF.SalesYTD and EMPLOYEE.SALARY were changed from DECIMAL to MONEY: now they will print with $
· CustF.Billingcycle and EMPLOYEE.SEX are defined with CODES, specifying particular values and their meanings.
· EMPLOYEE.SEX may have value M meaning Male or F meaning Female Other values are invalid and meaningless
· CustF.Billingcycle is defined LIKE Types.Month, referring to
DEFINE Types SYSTEM DATA(
Month TINYINT CODES(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec),
SYSTEM definitions are templates: you can use them to define your data types.
Month is a one-byte binary number with values 1 meaning Jan, to 12 meaning Dec
· CustF.DateCommenced was changed from INTEGER to DATE because it contains a date value. Now the value is validated, formatted, and handled in calculations according to DATE rules.
· EMPLOYEE.DEPTMGR was changed from CHAR(1) to BOOLEAN because it carried a value Y meaning true, anything else meaning false.
Click here to see a full description of data types.
With these simple edits we’ve documented important information about our data schema. But it’s more than just documentation!
Whenever data is read from a potentially-invalid source ACCEPT is used to check that it is valid for the target field. Here is the update logic generated for program JSPG2, a web service that updates Employee records: -
WHEN (Update);
ACCEPT (EMPLOYEE.EMPNO=IJSPG2.EMPNO) MESSAGE OJSPG2.Error;
GET EMPLOYEE KEY(EMPLOYEE.EMPNO) UPDATE CHECKSUM IJSPG2.JZ-EMPLOYEE.Checksum;
ACCEPT (IJSPG2.JZ-EMPLOYEE.*) EXCEPT(EMPLOYEE.EMPNO) MESSAGE OJSPG2.Error;
END GET EMPLOYEE UPDATE RESPOND OJSPG2;
The first ACCEPT checks that a valid EMPNO value has been supplied. The second validates the other 15 fields in the input message. Each field is checked individually to see that it is valid for assignment to its target field, first by the default checks implied by the data type, then by the checks written into the definition with properties like EXISTS, RANGE, CODES, etc. Validation is thorough and easy because it’s just a matter of defining appropriate properties.
Data is automatically converted to its display format when it is printed
or placed on a screen. For example,
PRINT
(CustF.Account,CustF.Region, FR.Name,CustF.District,CustF.Name,CustF.SalesYTD SUM,CustF.Billingcycle,
CustF.DateCommenced)
;
produces: -
Account Region *------Region Name-------* District *------------Name------------* *----SalesYTD---* Billingcycle DateCommenced
000141 1 New Zealand 2 ORR, Myra Dorothy $41,985.00 Jun 28 Feb 2018
Each data type has a default display format, so Region and District are printed as numbers, and SalesYTD is printed with $, comma, and decimal point. Billingcycle is printed as its code value, not as a TINYINT number. DateCommenced has an explicit Display Picture (DPIC), so the date value is printed as 28 Feb 2018.
DEFINE is the most important
statement in the Jazz language, and the source of its power. The productivity from implementing Date’s
concept, “What, not How” are immense. Because EMPLOYEE has type SQL MANASYS knows to use EXEC SQL statements,
not EXEC CICS READ, to read and update data.
And because the Employee record has been well defined, this single Jazz
line: -
ACCEPT (IJSPG2.JZ-EMPLOYEE.*)
EXCEPT(EMPLOYEE.EMPNO) MESSAGE OJSPG2.Error;
generates
474 lines of COBOL, plus 80+ lines of shared routines generated for checking CODES values and DATE fields!
But
that’s only the start! Your data is now defined in a simple, easy
way that you can guarantee is accurate, it isn’t just documentation that might
not have been implemented correctly. Changes are easy: if a policy
decision changes the data definitions you only have to edit its definition and
regenerate the program(s) for this to take effect. For example, another
possible value is easily added to EMPLOYEE.SEX: -
SEX
CHAR(1) CAPS CODES(M:Male, F:Female, G:'Gender Diverse'),
Capturing the meaning of your data by preparing Jazz definitions is not only the key to easy Jazz programming, it is also a great way of capturing the knowledge of your retiring COBOL staff before it’s too late.
See our web page if you want more information. Contact us if you have any questions, or connect with us on LinkedIn. Download a free evaluation copy if you want to try it out.