This file was written in 1989 as an overview document for the BSDE (Bionic Systems Development Environment)
class taught at Amoco by the IT Training Department.  BSDE had an online manual, but it was thought that
programmers would benefit from a generalized step-by-step recipe to help them develop their first BSDE
application after the class was completed.  The original document was an IBM DCF Script document to be
displayed on IBM 3278 terminals or printed on a line-printer, which explains the funny looking formatting
codes in the document.  It is best to view this file with a fixedsys or courier font so that the line-printer
graphics align properly.

.fo off
.tm 5
.in 5
.ud on 40
.pn off
.pl 65










                    B S D E   L I F E   C Y C L E



                                 By

                           Steve Johnston

                           November 1989
                            August  1990
















.pn on
.pa 1
.us
The BSDE Life Cycle

BSDE is a software development and maintenance tool which covers the
entire systems development life cycle from data modeling through
installation and documentation and can be used on systems both new and
old.  BSDE can dramatically boost a programmer's productivity whenever he
is working on a system which uses any of the following products on
either VM/CMS or MVS:

   ISPF Dialog Manager
   REXX
   PL/I
   COBOL
   SQL/DS or DB2

BSDE is a very flexible tool which may be used in many different ways to
improve a programmer's productivity and generate well structured systems
which are easy to maintain.  Because BSDE is so flexible, programmers new
to BSDE frequently do not know where to begin. I hope this step-by-step
guide to writing systems with BSDE will help. This is a cookbook
approach to systems with a recipe that works.

Before starting, I would like to issue a warning.  BSDE will generate
code for you that works.  When it is necessary for you to supply code
which is specific to your problem, BSDE will place @@@@@@@ characters in
the generated code where you should add code.  Beyond that, I would
recommend that you refrain from making arbitrary changes to the
generated code.  I strongly recommend that you only change code when it
is absolutely necessary.  Do not make unnecessary changes to generated
code such as indentation changes or renaming of variables.  Only change
code when it is necessary to fulfill a required function.  Also, try to
build systems the "BSDE way". Use the default PFKEY and screen layouts
provided by BSDE. BSDE follows a standard for screens and PFKEY settings
which should prove adequate for your purposes.  Refrain from arbitrary
screen formats and PFKEY settings which are really not important to the
function of your system.

There are reasons for this approach:

1. Whenever you make a change to a piece of software the odds are that
   you will introduce an error.  Arbitrary code changes will introduce
   arbitrary errors in your system.

2. BSDE will steer you clear of many pitfalls which may not be initially
   evident.  If you make unnecessary changes to the code, you may find
   that you have painted yourself into a corner when the system goes
   into production.

3. One of the goals of BSDE is to produce systems using standard
   reusable parts that follow the same basic standards for all supported
   languages (REXX, PL/I, and COBOL).  This makes it easier for a
   programmer to go from a BSDE generated REXX program to a BSDE
   generated PL/I program within a system because they will look very
   similar.  It also makes it easier for a programmer to move from one
   BSDE generated system to another BSDE generated system because all of
   the systems will look similar internally.

4. Externally your system will operate much like all of the other BSDE
   generated systems.  This makes it easier for clients to move from one
   application to another because the systems will all have the same
   external appearance.

Try not to think of following a standard approach as stifling your
creativity.  Channel your creativity into how you put the parts of a
system together rather than on refinishing already machined parts.

.us
References to BSDE Options

In this paper, references to locations of options will be made relative
to the Master Menu.  For example, Option 2.2.3 describes the path you
have to navigate relative to the Master Menu to get to the desired
option.

   Master                 Data Definition        Entity Relationship
   Menu                   Menu                   Menu
   +---------------+      +---------------+      +---------------+
   |1. Utilities   |      |1. Utilities   |      |1. Utilities   |
   |2. Data Def    +----->|2. Entity      +--+   |2. Edit ER     |
   |3. Function Def|      |3. Data Element|  +-->|3. Print ER    |
   |4. Interactive |      |4. Retrieve    |      |               |
   +---------------+      +---------------+      +---------------+

However, because BSDE is an amalgam of many IBM products, you cannot
always get to a particular option using the shortcut method found in
ISPF.  This means entering things like:

   COMMAND ===> 1.2.1

   COMMAND ===> =3.1.1

may or may not work depending on where you are in BSDE.  The best bet is
to try the shortcut and if it doesn't work, go to the option manually.


.us
Suggested Approach

Let's go through the steps I would recommend in developing a system
called AM99.

1. Set up your infrastructure first.  You will need to set up a
    VM/CMS ID on CTSVMD called:

    AM99DEV

    with about 10 - 30 cylinders.  AM99DEV will be your development ID
    which will be used to develop the AM99 system and maintain it after
    AM99 goes into production.  This is true for both VM and MVS
    systems.  After AM99 goes into production, AM99DEV will be used to
    hold a mirror image of the AM99 production system complete with test
    data.

    You should contact your DBA and tell him about your plans for the
    AM99 system.  Be sure to work closely with your DBA right up front.
    He is here to help you.

    Arrange for a small personal DBSPACE at this time with your DBA (128
    pages should do).  We shall assume that this DBSPACE is called
    AM99TEST.  AM99TEST will be used to do your initial database
    modeling.  You will use AM99TEST to experiment with an initial data
    base design for AM99.  Once the initial design is complete you
    should contact your DBA again and have him build corresponding
    SQL/DS tables owned by him in a DBSPACE owned by the DBA.  These
    tables will be used during the development of the AM99 system.

2. Go into BSDE and on the Project Directory screen and make an entry
    for project AM99.  Once the AM99 project has been defined to BSDE,
    all files generated for the AM99 system will begin with the
    characters AM99.

    Note: BSDE checks for all files that have a filetype of ERDIAG and a
          four character filename to determine what projects exist on
          your ID.  AM99 ERDIAG will contain the Entity-Relation (E-R)
          diagram for the AM99 system which will be the starting point
          for the AM99 system.

    When in BSDE, you will find that PFKEYS PF13 - PF24 will be set to
    the standard ISPF set (HELP, SPLIT, END, etc.) and that PF01 - PF12
    will perform other functions such as generating SQL code.  If you
    are using a PC with only 12 PFKEYS, you will find it more convenient
    to FLIP your PFKEYS so that PF01 <--> PF13, PF02 <--> PF14.  This
    will decrease your usage of PF13 - PF24, since you will be able to
    scroll files with PF07 and PF08 and can leave screens with PF03.  To
    FLIP your PFKEYS, just type:

       COMMAND ===> FLIP

    on the command line anytime you are in ISPF edit of a file while in
    BSDE.  Your PFKEYS will remain flipped from session to session
    unless you FLIP them again.

    Now that you are in BSDE, note that you can use the command line of
    any BSDE screen to do many useful things. Just enter CMS followed by
    what you want to do.

       COMMAND ===> CMS PROFS
       COMMAND ===> CMS X PROFILE EXEC
       COMMAND ===> CMS FILEL AM99* EXEC
       COMMAND ===> CMS COPY JUNK DATA A JUNK SAVE A
       COMMAND ===> CMS HELP REXX

    To go into CMS subset enter:

       COMMAND ===> CMS SUBSET

    To return to BSDE enter:

       RETURN

    while in CMS subset.

    Remember that once you are in XEDIT of a file or you are in PROFS
    you can also chain off of the command line.  In this way it is
    possible to edit many files at the same time and get to any
    information or tool you may need while using BSDE. This can really
    boost your productivity and I strongly recommend that you get used
    to working in this mode.

3. You then need to build a Control File for the AM99 system called
    AM99 CONTROL.  AM99 CONTROL will contain genes for all of the
    tables that the AM99 system will be dealing with.  Much of the
    subsequent BSDE code generation will rely on the genes in AM99
    CONTROL.

    Sample gene:

    CREATE TABLE AM99DEV.AM99_CONT_SKILL
        (CONTRACTOR_ID                   CHAR(4) NOT NULL,
         SKILL_ID                        CHAR(4) NOT NULL,
         YEARS                           DECIMAL(3,1),
         SKILL_LEVEL                     DECIMAL(3,1),
         LAST_USED                       CHAR(2))
         IN SOCONSV2;

    The genes in the Control File are used to:

     - Analyze the database
     - Create the database
     - Grant user access to the database
     - Generate ISPF Dialog Manager Screens
     - Generate SQL program code (REXX, PL/I, or COBOL)
     - Generate report program code
     - Generate disaster recovery software for the database
     - Unload the tables to sequential files, edit the files, and load
       them back

4. If SQL/DS tables already exist which cover the data requirements of
    the AM99 system, you can retrieve the genes for the tables from
    the SQL/DS catalog tables (SYSTEM.SYSDBSPACES, SYSTEM.SYSCOLUMNS,
    SYSTEM.SYSINDEXES, etc.)  using Option 2.4.  For example, to
    retrieve a gene for a table from the Application Portfolio
    system and all of the genes for the tables from the SEEK system
    you would enter:

       CHIDBA01.SZ42R010 <-- Application Portfolio base table
       CHIDBA01.SEEK% <-- % indicates a wild-card for all SEEK tables

    The genes would then be added to the file AM99 CONTROL.

    If you will be installing the AM99 system on MVS and will be using
    DB2 tables, you can retrieve genes for existing DB2 tables by
    using DCLGEN on MVS.  Go into Option D.1.2 of ISPF on MVS.  Run a
    DCLGEN for the DB2 tables you are interested in.  The output of the
    DCLGEN can be easily edited to conform to the syntax of a BSDE
    gene as shown above.  When all of the DCLGEN's have been run,
    log onto BSDE on VM and use Option 1.8.6 to bring over the DCLGEN
    output files from MVS to VM.  Use Option 1.8.7 to read the
    transmitted files into the AM99 CONTROL file.

    If you plan to use existing tables which do not already "belong" to
    a system you support, be sure to get permission from those
    individuals who currently "own" the tables.  Your DBA and supervisor
    can be of assistance here.

5. If additional SQL/DS tables are required or none exist in the first
    place, you can use BSDE to create control file genes from an E-R
    diagram with Option 2.2.2.  This option will put you into ISPF edit
    of a file called AM99 ERDIAG and will turn on the graphics settings
    for PFKEYS PF01 - PF12.  You then proceed to create an E-R diagram
    by using the graphics primitives available under PF01 - PF12.  BSDE
    uses line printer graphics technology so any IBM terminal can be
    used.  Your E-R diagram should include existing tables from
    other systems which will be accessed by your system.

    Listed below are the graphics primitives available under BSDE.

    To make a BOX use PF01.

    Put Your Cursor Here -->+---------------+
    and Press PF01 To       |               |
    Make a BOX.  Press      |               |
    PF11 to Erase the       |               |
    BOX.                    |               |
                            +---------------+
.pa
    To draw lines lay out a number trail and press PF02.

    Before:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |          4          5               |
    |               |                     |               |
    |               |                     |               |
    +------1--------+                     +---------------+





           2                   3

    After PF02:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |          +----------+               |
    |               |          |          |               |
    |               |          |          |               |
    +------+--------+          |          +---------------+
           |                   |
           |                   |
           |                   |
           |                   |
           |                   |
           +-------------------+

    To erase lines lay out a number trail and press PF12.

    Before:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |          4----------5               |
    |               |          |          |               |
    |               |          |          |               |
    +------1--------+          |          +---------------+
           |                   |
           |                   |
           |                   |
           |                   |
           |                   |
           2-------------------3
.pa
    After PF12:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |                     |               |
    |               |                     |               |
    |               |                     |               |
    +---------------+                     +---------------+

    When you erase lines from a diagram, your diagram may begin to get
    holes in it.  To mend the holes press PF03

    Before:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |          +--   -- --+               |
    |               |          |          |               |
    |               |                     |               |
    +------+--------+          |          +---------------+
           |                   |

                               |
           |                   |
           +-- -- ----- --- ---+

    After PF03:

    +---------------+                     +---------------+
    |               |                     |               |
    |               |          +----------+               |
    |               |          |          |               |
    |               |          |          |               |
    +------+--------+          |          +---------------+
           |                   |
           |                   |
           |                   |
           |                   |
           +-------------------+

    To shrink diagrams horizontally enter the number of columns
    you want the diagram to shrink by and press PF05.
.pa
    Before:

    +---------------+                     +---------------+
    |               |                     |               |
    |               | 7        +----------+               |
    |               |          |          |               |
    |               |          |          |               |
    +------+--------+          |          +---------------+
           |                   |
           |                   |
           |                   |
           |                   |
           |                   |
           +-------------------+

    After PF05:

    +---------------+              +---------------+
    |               |              |               |
    |               |   +----------+               |
    |               |   |          |               |
    |               |   |          |               |
    +------+--------+   |          +---------------+
           |            |
           |            |
           |            |
           |            |
           |            |
           +------------+

    To stretch it back again enter the number of columns you want to
    stretch it by and press PF04.

    Before:

    +---------------+              +---------------+
    |               |              |               |
    |               |12 +----------+               |
    |               |   |          |               |
    |               |   |          |               |
    +------+--------+   |          +---------------+
           |            |
           |            |
           |            |
           |            |
           |            |
           +------------+
.pa
    After PF04:

    +---------------+                          +---------------+
    |               |                          |               |
    |               |               +----------+               |
    |               |               |          |               |
    |               |               |          |               |
    +------+--------+               |          +---------------+
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           +------------------------+

    To stretch the diagram vertically use the Repeat (R) line command
    of ISPF edit.

    Before:

    +---------------+                          +---------------+
    |               |                          |               |
    |               |               +----------+               |
    |               |               |          |               |
    |               |               |          |               |
    +------+--------+               |          +---------------+
           |                        |
           |                        |
           |                        |
           +------------------------+

    After:

    +---------------+                          +---------------+
    |               |                          |               |
    |               |               +----------+               |
    |               |               |          |               |
    |               |               |          |               |
    +------+--------+               |          +---------------+
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           +------------------------+

    To shrink the diagram vertically use the Delete (D) line command
    of ISPF edit.

    Before:

    +---------------+                          +---------------+
    |               |                          |               |
    |               |               +----------+               |
    |               |               |          |               |
    |               |               |          |               |
    +------+--------+               |          +---------------+
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           |                        |
           +------------------------+

    After:

    +---------------+                          +---------------+
    |               |                          |               |
    |               |               +----------+               |
    |               |               |          |               |
    |               |               |          |               |
    +------+--------+               |          +---------------+
           |                        |
           |                        |
           |                        |
           +------------------------+


    To "hide" numbers on your diagram so that you can lay out number
    trails without confusing BSDE with numbers elsewhere on the diagram
    press PF08

    Before:

        0123456789

    After PF08:

        !~³#›`ª\{}

    To "find" numbers press PF10.

    Using these graphics primitives complete your E-R diagram in file
    AM99 ERDIAG.  Use the following conventions for relationships:
.pa
    +-----------+  One to One

    +-----------M  One to Many

    M-----------M  Many to Many

    +-----------0  One to possibly none

    +----------0M  One to possibly none or possibly many

    Sample E-R diagram:

    +---------------+              +---------------+
    | AM99          |              | AM99          |
    | PRODUCT       |              | CUSTOMER      |
    |               |              |               |
    |               |              |               |
    +------+--------+              +---------------+
           |                               M
           |                               |
           |                               |
           |                               |
           M                               |
    +---------------+                      |
    | AM99_GAS      |                      |
    | STATION       |0---------------------+
    |               |
    |               |
    +---------------+

    Your diagram can be 255 characters wide by as many records long
    as desired.

    Note:
    Most BSDE code generation is based on the genes in the AM99
    CONTROL file.  The E-R diagram is used only to create skeleton
    genes and as a graphical aid to the programmer.

6. Pressing PF07 will add skeleton genes to the AM99 CONTROL file.
    A gene will be added for each box on the E-R diagram unless the
    gene already exists in the AM99 CONTROL file.  The skeleton
    gene contains example columns for each data type allowed by SQL.
    Below are the skeleton genes which BSDE created from the above
    E-R diagram.

    Skeleton BSDE AM99 CONTROL file genes:
.pa
CREATE TABLE AM99DEV.AM99_PRODUCT                               gene
    (FIELD_1                         CHAR(  8) NOT NULL,     <--start-->
     FIELD_2                         CHAR( 10) NOT NULL,
     FIELD_3                         VARCHAR(254),
     FIELD_4                         SMALLINT,
     FIELD_5                         INTEGER,
     FIELD_6                         DECIMAL(5,2),
     FIELD_7                         FLOAT,
     FIELD_8                         DATE,
     FIELD_9                         TIME,
     FIELD_10                        TIMESTAMP,
     PRIMARY KEY (FIELD_1, FIELD_2) PCTFREE = 10,
     FOREIGN KEY K1 (FIELD_4, FIELD_5)
     REFERENCES AM99DEV.@@@@@@@@ ON DELETE RESTRICT)             gene
     IN @@@@;                                                <---end--->

CREATE UNIQUE INDEX INDEX_AM99_PRODUCT ON AM99DEV.AM99_PRODUCT
    (FIELD_5, FIELD_6)   PCTFREE = 10;

CREATE TABLE AM99DEV.AM99_CUSTOMER                              gene
    (FIELD_1                         CHAR(  8) NOT NULL,     <--start-->
     FIELD_2                         CHAR( 10) NOT NULL,
     FIELD_3                         VARCHAR(254),
     FIELD_4                         SMALLINT,
     FIELD_5                         INTEGER,
     FIELD_6                         DECIMAL(5,2),
     FIELD_7                         FLOAT,
     FIELD_8                         DATE,
     FIELD_9                         TIME,
     FIELD_10                        TIMESTAMP,
     PRIMARY KEY (FIELD_1, FIELD_2) PCTFREE = 10,
     FOREIGN KEY K1 (FIELD_4, FIELD_5)
     REFERENCES AM99DEV.@@@@@@@@ ON DELETE RESTRICT)            gene
     IN @@@@;                                                <---end--->

CREATE UNIQUE INDEX INDEX_AM99_CUSTOME ON AM99DEV.AM99_CUSTOMER
    (FIELD_5, FIELD_6)   PCTFREE = 10;

CREATE TABLE AM99DEV.AM99_GAS_STATION                           gene
    (FIELD_1                         CHAR(  8) NOT NULL,     <--start-->
     FIELD_2                         CHAR( 10) NOT NULL,
     FIELD_3                         VARCHAR(254),
     FIELD_4                         SMALLINT,
     FIELD_5                         INTEGER,
     FIELD_6                         DECIMAL(5,2),
     FIELD_7                         FLOAT,
     FIELD_8                         DATE,
     FIELD_9                         TIME,
     FIELD_10                        TIMESTAMP,
     PRIMARY KEY (FIELD_1, FIELD_2) PCTFREE = 10,
     FOREIGN KEY K1 (FIELD_4, FIELD_5)                          gene
     REFERENCES AM99DEV.@@@@@@@@ ON DELETE RESTRICT)         <---end--->
     IN @@@@;

CREATE UNIQUE INDEX INDEX_AM99_GAS_STA ON AM99DEV.AM99_GAS_STATION
    (FIELD_5, FIELD_6)   PCTFREE = 10;

7. Next split your screen with PF14.  Keep the E-R diagram on the top
    screen and go into Option 2.3 on the bottom screen (ISPF edit of
    AM99 CONTROL).  With the help of your client, fill in the skeleton
    genes with column names and data types of the data the AM99
    system will be processing.  You should have your DBA participate in
    this process also.  Try to make sure your tables will be normalized.
    If you don't know what a normalized database is, see your DBA and
    take a course in database normalization.

    To establish joins between tables, just copy the join column
    from one table to the table you wish to join to.

CREATE TABLE AM99DEV.AM99_PRODUCT
    (PRODUCT_ID                      CHAR(  8) NOT NULL,
     PRODUCT_NAME                    CHAR( 10),
     VOL_ON_HAND                     INTEGER,
     PRICE                           DECIMAL(5,2))
     IN AM99TEST;

CREATE UNIQUE INDEX INDEX_AM99_PRODUCT ON AM99DEV.AM99_PRODUCT
    (PRODUCT_ID)   PCTFREE = 10;


CREATE TABLE AM99DEV.AM99_CUSTOMER
    (CUSTOMER_ID                     CHAR(  8) NOT NULL,  -----------+
     CUST_NAME                       CHAR( 25),                      |
     CREDIT_LIMIT                    DECIMAL(5,2),                   |
     CREDIT_EVAL_DATE                TIMESTAMP)                      |
     IN AM99TEST;                                                    |
                                                                     |
CREATE UNIQUE INDEX INDEX_AM99_CUSTOME ON AM99DEV.AM99_CUSTOMER      |
    (CUSTOMER_ID)   PCTFREE = 10;                                    |
                                                           Use editor|
                                                           to copy   |
CREATE TABLE AM99DEV.AM99_GAS_STATION                      join      |
    (STATION_ID                      CHAR(  8) NOT NULL,   columns   |
     CUSTOMER_ID                     CHAR(  8) NOT NULL,  <----------+
     LOCATION                        CHAR( 10),
     PRODUCT_ID                      CHAR(  8) NOT NULL,
     PRODUCT_NAME                    CHAR( 10))
     IN AM99TEST;

CREATE UNIQUE INDEX INDEX_AM99_GAS_STA ON AM99DEV.AM99_GAS_STATION
    (STATION_ID)   PCTFREE = 10;

    Your tables and columns can have names which are 18 characters long.
    Use long descriptive names with underscores rather than short mystic
    names.  Your system acronym, AM99 in our example, should be the
    first 4 characters of the table name.  Be sure to use the same
    column names in tables if the columns mean the same thing.  Don't
    use DEPART_NUM in one table and DEPART_ID in another if they mean
    the same thing.  Using the same name throughout will make it easier
    to JOIN tables in ad hoc queries and in your system programs.

    Caution:
       Relational tables should not be thought of as glorified
       sequential files.  If you are converting a system from some other
       access method such as VSAM, do not carry over the file structure
       of the old system and create tables which emulate the files used
       by the original system.  You should totally rethink how your data
       is being stored because you will now be using a relational
       database.

8. Once the initial definition of the system tables is complete, BSDE
    can analyze your database.  Run Option 2.5.2 to produce a report
    listing all of the binary joins in the AM99 CONTROL file.

.us
      Table 1             Table 2             Join Column

      AM99_PRODUCT        AM99_GAS_STATION    PRODUCT_ID
      AM99_PRODUCT        AM99_GAS_STATION    PRODUCT_NAME

      AM99_CUSTOMER       AM99_GAS_STATION    CUSTOMER_ID

      AM99_GAS_STATION    AM99_CUSTOMER       CUSTOMER_ID
      AM99_GAS_STATION    AM99_PRODUCT        PRODUCT_ID
      AM99_GAS_STATION    AM99_PRODUCT        PRODUCT_NAME

    Option 2.5.4 of BSDE creates a report listing all of the tables which
    have a common column.  These are likely foreign keys in the
    database.

    Likely Foreign Keys
.us
    Column              Tables

    CUSTOMER_ID         AM99_GAS_STATION
    CUSTOMER_ID         AM99_CUSTOMER

    PRODUCT_ID          AM99_PRODUCT
    PRODUCT_ID          AM99_GAS_STATION

    PRODUCT_NAME        AM99_PRODUCT
    PRODUCT_NAME        AM99_GAS_STATION

9. If you need to add a table to the E-R diagram just flip up to your
    E-R diagram by pressing PF21.  You then can stretch the diagram if
    necessary and add another box.

       +---------------+                        +---------------+
       | AM99          |                        | AM99          |
       | PRODUCT       |M---------+             | CUSTOMER      |
       |               |          |             |               |
       |               |          |             |               |
       +------+--------+          |             +---------------+
              |                   |                     M
              |                   |                     |
              |           +-------+-------+             |
              |           | AM99          |             |
              |           | REFINERY      |             |
              |           |               |             |
              |           |               |             |
              |           +---------------+             |
              |                                         |
              |                                         |
              M                                         |
       +---------------+                                |
       | AM99_GAS      |                                |
       | STATION       |0-------------------------------+
       |               |
       |               |
       +---------------+

    In our case, pressing PF07 will add a skeleton gene for the
    AM99_REFINERY table.

10. Option 2.2.3 of BSDE will let you print the E-R diagram. The E-R
    diagram can be sent to the 3800 laser printer or it can be sent to
    any printer in the corporation.  When the E-R diagram is sent to the
    3800 all of the -'s and +'s are converted to smooth lines and boxes.

    Line printers can print across fan folds, but the 3800 laser printer
    cannot.  Therefore, if you send your diagram to the 3800, you should
    force page breaks at records 61, 121, 181 .... by typing PAGE as the
    first 4 characters of these records.  This will indicate to BSDE to
    do a page break on these records.  The PAGE string will not appear
    on the printed diagram.

    When using BSDE in a JAD, it is recommended that a local printer be
    close at hand to provide quick turn around of diagram hard copies.

11. Once the data model has been defined in the AM99 CONTROL file, use
    Option 2.6 to create the database.

    Use Option 2.7 to issue GRANTS on the AM99 tables to your clients so
    that they can access the database.  When you run Option 2.7, BSDE
    will check to see if an AM99 GCONTROL file exists.  If it does not,
    it will use the genes on the AM99 CONTROL file to build a GRANT
    statement for each table on the Control File and put you into edit
    of the AM99 GCONTROL file.  Modify the GRANT statements to give
    authorities to your clients.

                    +------ Delete unwanted privileges
                    |
                    V
    GRANT SELECT, INSERT, UPDATE, DELETE ON AM99DEV.AM99_PRODUCT TO
    ZAAA01, ZBBB01, ZCCC01;  <--- Change to your clients' userids

12. The next step is to populate your newly created tables with test
    data.  Use Option 1.7 (QMF) to insert at least one row into each
    table.  After getting into QMF press PF6.  On the QMF command line
    enter the name of the table you wish to draw like this:

    COMMAND ===> AM99_PRODUCT (T=I

    and then press PF6.  QMF will then generate an INSERT command for
    the table because you specified a TYPE = INSERT (T= I).  Fill in the
    data being sure to put CHAR data in quotes and then press PF02 to
    perform the INSERT.  Leave QMF and then use Option 1.3 to
    automatically perform DATAUNLOADs of the system tables.  Under
    Option 1.3 a screen will appear listing all of the tables in the
    AM99 CONTROL file.  Just choose the tables you want to unload and
    BSDE will build a DATAUNLOAD statement for each chosen table based
    on the gene for the table in the AM99 CONTROL file.

       DATAUNLOAD
       SELECT * FROM AM99DEV.AM99_PRODUCT;
          PRODUCT_ID         0001-0008
          PRODUCT_NAME       0010-0019          NULL POS(0021) = '?'
          VOL_ON_HAND        0023-0033          NULL POS(0035) = '?'
          PRICE              0037-0047          NULL POS(0049) = '?'
       OUTFILE (PRODUCT) <-- The unloaded rows will be written to
       COMMIT WORK;          file PRODUCT UNLOAD

    Use Option 1.3 to unload the single row from each table to a
    sequential file.  Then use Option 1.4 to FILELIST all of the unload
    files (the above table would unload to PRODUCT UNLOAD).  Using XEDIT
    under FILELIST, edit the PRODUCT UNLOAD file.  Replicate the single
    unloaded row about 20 times and alter the data in each row slightly.
    This data will be the test data for your rough database design.
    Use Option 1.5 to DATALOAD the test data into the system tables.
    For the AM99_PRODUCT table, BSDE would build the following DATALOAD
    statement.
.pa
       DELETE FROM AM99DEV.AM99_PRODUCT;

       DATALOAD TABLE (AM99DEV.AM99_PRODUCT)
           PRODUCT_ID         0001-0008
+------>  PRODUCT_NAME       0010-0019          NULL POS(0021) = '?'
|         VOL_ON_HAND        0023-0033          NULL POS(0035) = '?'
|         PRICE              0037-0047          NULL POS(0049) = '?'
| +-> INFILE (PRODUCT)
| |
| |   UPDATE STATISTICS FOR TABLE AM99DEV.AM99_PRODUCT;
| |
| |   COMMIT WORK;
| |
| |
+-|---- These are the default columns to which the data was unloaded.
   |     Change to the columns in your UNLOAD file if you wish to use
   |     a different file.
   |
   +---- The rows will be loaded from a file called PRODUCT UNLOAD.
         Change this name if you wish to load a different UNLOAD file.

13. Option 1.7 will let you run QMF under BSDE. Use QMF to help validate
    the data model of the system.  Enlist your client and DBA to write
    ad hoc queries against the newly formed tables which have been
    populated with test data.  If your database design can meet the
    client's ad hoc query requirements and is normalized then most
    likely the database design is viable.

    Note that you can use ISQL and RXSELECT from the command line
    of any BSDE screen to examine tables.

       COMMAND ===> CMS ISQL
       COMMAND ===> CMS RXSELECT * FROM AM99_PRODUCT

    You can also get online information about bad SQLCODES:

       COMMAND ===> CMS RXSQLHLP -551  <-- To check what SQLCODE = -551
                                           means

14. Option 3.2 can be used to create Function Decomposition diagrams if
    desired.  The Function Decomposition diagrams can be used to produce
    an overall picture of the proposed system.  This is an optional
    step.  The Functional Decomposition diagram as well as all of the
    E-R diagrams are only graphical aids to the programmer. BSDE does not
    use the diagrams for code generation.  All of the code generation
    for the AM99 system will stem from the table genes in the AM99
    CONTROL file.  The diagrams are merely for reference.

    A decomposition STEM is generated by typing the number of boxes
    you want on your diagram file and then pressing PF06.


             + <-- Put a 3 Here and Press PF06 to create the stem below.
             |
             |        +---------------+
             |        |               |
             +--------+               |
             |        |               |
             |        |               |
             |        +---------------+
             |
             |        +---------------+
             |        |               |
             +--------+               |
             |        |               |
             |        |               |
             |        +---------------+
             |
             |        +---------------+
             |        |               |
             +--------+               |
                      |               |
                      |               |
                      +---------------+


    With the other graphics primitives mentioned above, you can
    create very complex diagrams.

+---------------+
| MASTER        |
| MENU          |
|               |
|               |
+-------+-------+
        |
        |        +---------------+
        |        | UPDATE        |
        +--------+ SOMETHING     |<----------------------------------------+
        |        |               |                                         |
        |        |               |                                         |
        |        +-------+-------+                                         |
        |                |                                                 |
        |                |                                                 |
        |                |        +---------------+                        |
        |                |        | GET IT        |                        |
        |                +--------+               |<----------+            |
        |                         |               |           |            |
        |                         |               |           |            |
        |                         +-------+-------+           |            |
        |                                 |                   |            |
.pa
        |                                 |                   |            |
        |                         +-------+-------+           |            |
        |                         | CHANGE IT     |           |            |
        |                         |               |           |            |
        |                         |               |           |            |
        |                         |               |           |            |
        |                         +-------+-------+           | No         | Yes
        |                                 |                   |            |
        |                         +-------+-------+           |            |
        |                         | PUT IT BACK   |           |            |
        |                         |               +-----------+------------+
        |                         |               |           Entry = Last ?
        |                         |               |
        |                         +---------------+
        |
        |        +---------------+
        |        | UTILITIES     |
        +--------+               |
        |        |               |
        |        |               |
        |        +-------+-------+
        |                |
        |                |        +---------------+
        |                |        | ISPF          |
        |                +--------+ MASTER MENU   |
        |                |        |               |
        |                |        |               |
        |                |        +---------------+
        |                |
        |                |        +---------------+
        |                |        | QMF           |
        |                +--------+               |
        |                |        |               |
        |                |        |               |
        |                |        +---------------+
        |                |
        |                |        +---------------+
        |                |        | DBEDIT        |
        |                +--------+               |
        |                         |               |
        |                         |               |
        |                         +---------------+
        |
        |
        |
        |        +---------------+
        |        | ADMINISTRATIVE|
        +--------+ FUNCTIONS     |
                 |               |
                 |               |
                 +---------------+

15. Now that you have a rough database design and your tables will not
    be changing drastically, have your DBA do a final review of your
    tables and then build a set of development tables owned by your DBA.
    Simply change the high level name of the tables to your DBA's ID and
    give him a copy of the AM99 CONTROL file to run.

       AM99DEV.AM99_PRODUCT --->  CHIDBA01.AM99_PRODUCT

    Have your DBA give you SELECT, INSERT, UPDATE, and DELETE authority
    on the development tables so that you will be able to write programs
    which can use the tables via Access Modules.

16. Now it is time to begin roughing out the AM99 system.  Use Option 4
    of BSDE to create an embryo AM99 system. The AM99 embryo is an
    immature version of the AM99 system which will already perform many
    standard functions.  The AM99 embryo will consist of 50 screens, 20
    REXX programs, and 32 standard error messages.  It will already have
    these functions:

    - An AM99 EXEC to start up the AM99 system
    - An Introduction Screen
    - A Master Menu Screen
    - Access to ISPF from a submenu
    - Access to QMF from a submenu
    - Access to DBEDIT from a submenu
    - Access to PROFS from a submenu
    - Allows the DBA to perform GRANTS.
    - DATAUNLOADS and DATALOADS the system tables by choosing
      tables from a screen
    - Allows the system administrator to edit the unloaded tables.
    - Allows the system administrator to issue batch SQL commands.
    - Allows system administrator to generate disaster recovery software
      for the system.
    - System can be used in split screen so that the user can be in
      two parts of the system at the same time
    - Online manual covering the functions of the AM99 system.

    Your job will be to add functions to AM99 which do not yet exist.

    However, you are not limited to generating code for embryos only.
    BSDE can be used to generate code for any system so long as a Control
    File with the desired table genes for code generation exists.

17. When you enter Option 4 of BSDE for the first time, BSDE will check to
    see if a MACLIB called AM99PNL MACLIB exists.  This is the MACLIB
    which holds the ISPF Dialog Manager panels (screens) for the AM99
    system.  If one does not exist, BSDE will build an AM99 embryo
    consisting of the following files:
.pa
    AM99     EXEC     <- Driver EXEC To Start Up AM99
    AM99QMF  EXEC     <- An EXEC Called By AM99 EXEC To Set Up QMF
    AM99PNL  MACLIB   <- A MACLIB With ISPF Panels For AM99
    AM99MSG  MACLIB   <- A MACLIB With ISPF Messages
    AM99SQLM MACLIB   <- A MACLIB With ISPF SQL Error Messages
    AM99TLIB MACLIB   <- A MACLIB To Hold ISPF Tables (not SQL/DS)
    AM99TXT  TXTLIB   <- A MACLIB To Hold TEXT which ISPF loads
    AM99     CONTROL  <- Already Existing Control File
    IESP0001 EXEC
    ~~~~~~~~ ~~~~     <- 21 REXX EXECs which perform the functions
    ~~~~~~~~ ~~~~        listed above
    IESP0021 EXEC

    BSDE will then activate the AM99 system. The next time you enter
    Option 4, BSDE will simply activate the already existing AM99
    system.

    Once AM99 has been created, use BSDE to create ISPF Dialog Manager
    screens, and REXX, PL/I, or COBOL programs in a split screen mode.
    With AM99 running under Option 4, press PF14 to split your screen.
    Use Option 1.1.2 on the lower screen to run ISPF edit.  To flip back
    and forth between the lower and upper screens, use PF21.

18. I recommend that you use REXX to run your system dialog (manage the
    interaction of the client with the system screens and menus) and use
    PL/I or COBOL to do reports which cannot be done with QMF.  On
    VM/CMS you can use REXX to do online transactions to your SQL/DS
    tables.  On MVS you will need to use PL/I or COBOL to do DB2 online
    transactions because there is no REXX-DB2 interface yet.

    Following the steps listed below, use BSDE to interactively rough out
    the dialog for your system using REXX and ISPF Dialog Manager with
    the system running on the upper screen.  The roughed out version of
    AM99 should include all of the necessary menus and input screens as
    well as MOCKUPs of the desired output reports (see below).  Verify
    fields with ISPF Dialog Manager or REXX.  Add HELP screens where
    needed.  It's a good idea to build an online user manual for the
    system at this point (see below) to detail the functions that the
    final AM99 system will provide.

    The roughed out version of the AM99 system should be considered the
    user requirements document for AM99.  Have your client try out and
    approve the roughed out version before proceeding.  Document
    requested changes to the roughed out version of AM99 as they occur
    as part of change management.

19. To generate programs for AM99, follow these steps using these
    standards for program names:

    AM99001 EXEC   <-- For REXX programs
    AM99001 PLI    <-- For PL/I programs not using SQL/DS or DB2
    AM99001 COBOL  <-- For COBOL programs not using SQL/DS or DB2

    AM99001 PLISQL <-- For PL/I programs using SQL/DS or DB2
    AM99001 COBSQL <-- For COBOL programs using SQL/DS or DB2

    Use your system acronym as the first 4 characters of the program
    name followed by 3 additional characters.  BSDE will not generate code
    for you if you don't follow the standards.

    For example, to create a PL/I program called AM99001 PLISQL go into
    ISPF edit of the file on your lower screen using Option 1.1.2.
    Press PF01 to get the reusable code menu.  Enter option "P" for the
    program skeleton menu and then enter "1" for the first program
    skeleton.  BSDE will copy in a 150 line boiler plate PL/I program
    skeleton.

    Sample PL/I program skeleton:

1/*********************************************************************/
/*                                                       * @@@@@@@   */
/*  P R O P R I E T A R Y  ~ ~ ~ ~ ~ ~                   *************/
/*                 TO BE MAINTAINED IN CONFIDENCE                    */
/*                 AMOCO  CORPORATION                                */
/*                                                                   */
/*********************************************************************/
/*                                                                   */
/*                                                                   */
/* PURPOSE: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* INPUT: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* OUTPUT: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* CALLING ENTITIES: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* ENTITIES CALLED: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* HISTORY: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*********************************************************************/
/*                                                                   */
/*                     WRITTEN BY:                                   */
/*                                                                   */
/*                    @@@@@@@@@@@@@@                                 */
/*                                                                   */
/*                      JAN 1987                                     */
/*                                                                   */
/*********************************************************************/
@@@@@@@: PROC OPTIONS(MAIN) REORDER;
/*                                                                   */
/* SQL VARIABLES                                                     */
/*                                                                   */
EXEC SQL BEGIN DECLARE SECTION;
0DCL IND                             FIXED BIN(15) INIT(0);
EXEC SQL END DECLARE SECTION;
/*                                                                   */
/* PROGRAM VARIABLES                                                 */
/*                                                                   */
0DCL SQLERR                          FILE STREAM;
0DCL ISPLINK                         EXTERNAL ENTRY
                                     OPTIONS(ASM INTER RETCODE);
0DCL PLIRETV                         BUILTIN;
0DCL ADDR                            BUILTIN;
0DCL SUBSTR                          BUILTIN;
0DCL STRING                          BUILTIN;
0DCL DATE                            BUILTIN;
0DCL TIME                            BUILTIN;
0DCL ONCHAR                          BUILTIN;
0DCL ONSOURCE                        BUILTIN;
0DCL VERIFY                          BUILTIN;
0DCL 1 TODAY_DATE                    CHAR(  6) INIT(' ');
0DCL 1 DATE_STRUC,
       2 MM                          CHAR(  2) INIT(' '),
       2 SLASH1                      CHAR(  1) INIT('/'),
       2 DD                          CHAR(  2) INIT(' '),
       2 SLASH2                      CHAR(  1) INIT('/'),
       2 YY                          CHAR(  2) INIT(' ');
0DCL 1 TDATE                         CHAR(  8) INIT(' ');
0DCL TIME_STRING                     CHAR(  9) INIT(' ');
0DCL 1 NOW_TIME,
       2 HOURS                       CHAR(  2) INIT(' '),
       2 COLON1                      CHAR(  1) INIT(':'),
       2 MINUTES                     CHAR(  2) INIT(' '),
       2 COLON2                      CHAR(  1) INIT(':'),
       2 SECONDS                     CHAR(  2) INIT(' ');
0DCL 1 NTIME                         CHAR(  8) INIT(' ');
0DCL ERRCODE                         PIC '~~~9' INIT(0);
0DCL SQLMSG                          CHAR( 80) VAR INIT(' ');
0DCL L4                              FIXED BIN(31) INIT(4);
0DCL I                               FIXED BIN(31) INIT(0);
ON CONV
BEGIN;
    IF ONCHAR = ' '
    THEN
       ONSOURCE = '0';
END;
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLWARNING CONTINUE;
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL COMMIT WORK;
OPEN FILE(SQLERR) OUTPUT;
TODAY_DATE = DATE;
DATE_STRUC.YY = SUBSTR(TODAY_DATE,1,2);
DATE_STRUC.MM = SUBSTR(TODAY_DATE,3,2);
DATE_STRUC.DD = SUBSTR(TODAY_DATE,5,2);
TDATE = STRING(DATE_STRUC);
/*                                                                   */
/* VGET AND VPUT ARE ONLY REQUIRED WHEN COMMUNICATING WITH THE ISPF  */
/* SHARED POOL ~ YOU MAY DROP THE ROUTINES IF YOU ARE NOT USING      */
/* ISPF OR IF YOU ARE ONLY COMMUNICATING WITH THIS PROGRAM'S         */
/* FUNCTION POOL.                                                    */
/*                                                                   */
CALL VDEFINE;
CALL VGET;
/*                                                                   */
/* START PROGRAMMING HERE   |                                        */
/*                          V                                        */





CALL VPUT;
/*********************************************************************/
/*                                                                   */
/* PROC VDEFINE ~ MAP THE PLI PROGRAM VARIABLES TO ISPF VARIABLES    */
/*                IN THE SHARED POOL                                 */
/*                                                                   */
/*********************************************************************/
VDEFINE: PROC;
CALL ISPLINK('VDEFINE','ERRCODE ',ERRCODE             ,'CHAR',L4);
END VDEFINE;
/*********************************************************************/
/*                                                                   */
/* PROC VGET ~ GET VALUES FROM THE ISPF SHARED POOL                  */
/*                                                                   */
/*********************************************************************/
VGET: PROC;
END VGET;
/*********************************************************************/
/*                                                                   */
/* PROC VPUT ~ PUT VALUES TO THE ISPF SHARED POOL                    */
/*                                                                   */
/*********************************************************************/
VPUT: PROC;
END VPUT;
/*********************************************************************/
/*                                                                   */
/* PROC SQL_ERROR ~ PERFORM ERROR ESCAPE IF A BAD SQLCODE IS RETURNED*/
/*                                                                   */
/*********************************************************************/
SQL_ERROR: PROC;
CALL GET_TIME;
SQLMSG = TDATE || ' ' || NTIME || ' ' || SQLMSG || ' ' || ERRCODE;
PUT FILE(SQLERR) SKIP LIST(SQLMSG);
CALL ISPLINK('VPUT','ERRCODE ','SHARED ');
CALL ISPLINK('SETMSG','BSD001T ');
EXEC SQL ROLLBACK WORK;
CALL EXIT;
END SQL_ERROR;
/*********************************************************************/
/*                                                                   */
/* PROC GET_TIME ~ GET THE CURRENT TIME                              */
/*                                                                   */
/*********************************************************************/
GET_TIME: PROC;
TIME_STRING = TIME;
NOW_TIME.HOURS = SUBSTR(TIME_STRING,1,2);
NOW_TIME.MINUTES = SUBSTR(TIME_STRING,3,2);
NOW_TIME.SECONDS = SUBSTR(TIME_STRING,5,2);
NTIME = STRING(NOW_TIME);
END GET_TIME;
/*********************************************************************/
/*                                                                   */
/* PROC FCONV ~ CONVERT A FIXED DECIMAL NUMBER TO CHARACTER          */
/*                                                                   */
/*********************************************************************/
FCONV:PROC(NUM) RETURNS(CHAR(30));
0DCL NUM                          CHAR(30);
0DCL FIXED_CHAR                   CHAR(30) INIT(' ');
FIXED_CHAR = SUBSTR(NUM,VERIFY(NUM,' '));
RETURN(FIXED_CHAR);
END FCONV;
/*********************************************************************/
/*                                                                   */
/* PROC EXIT ~ SHUT DOWN THE PROGRAM AND EXIT                        */
/*                                                                   */
/*********************************************************************/
EXIT: PROC;
EXIT;
END EXIT;
END @@@@@@@;

    You can add other skeletons to the above program by positioning your
    cursor in the code where you want to insert a skeleton and then
    pressing PF01.

    Sample code which could be inserted into the above skeleton:

/*********************************************************************/
/*                                                                   */
/* PROC @@@@@@@@                                                     */
/*                                                                   */
/*********************************************************************/
@@@@@@@@: PROC;

CALL ISPLINK('SETMSG','SYS00@@ ');   <-- This is a message skeleton

CALL ISPLINK('DISPLAY','@@@@@@@ ');  <-- This is a display screen
IF PLIRETV() = 8                         skeleton
THEN
    CALL EXIT;

SELECT;                                             <---+
    WHEN (@@@@@@@@@@@@@@@@@@@@@@@) I = @@@@@@@@@@;       |
    WHEN (@@@@@@@@@@@@@@@@@@@@@@@) CALL @@@@@@@@@@;      |
    WHEN (@@@@@@@@@@@@@@@@@@@@@@@)                       |
    DO;                                                  |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
    END;                                                 |
    WHEN (@@@@@@@@@@@@@@@@@@@@@@@)                       | A SELECT
    DO;                                                  | skeleton
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
    END;                                                 |
    OTHERWISE                                            |
    DO;                                                  |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
       @@@@@@@@;                                         |
    END;                                                 |
END;                                                <---+

END @@@@@@@@;


    To add messages to AM99, edit the AM99MSG MACLIB file.  This maclib
    will initially contain two members - BSD00 and SYS00.  The BSD00
    member contains messages used by BSDE reusable code modules and
    should not be changed.  Add your messages to the SYS00 member.
    The initial SYS00 member will look like:

SYS001A 'SQL ERROR &SQLCODE' .ALARM=YES
'AN SQL ERROR HAS OCCURRED - CONTACT YOUR SYSTEMS ADMINISTRATOR'

SYS001B 'PUT SHORT MESSAGE HERE' .ALARM=YES
'START ADDING MESSAGES HERE WITH MESSAGE SYS001B; INCREMENT AS BELOW'

SYS001C 'PUT SHORT MESSAGE HERE' .ALARM=YES
'PUT LONG MESSAGE HERE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

SYS001D 'PUT SHORT MESSAGE HERE' .ALARM=YES
'PUT LONG MESSAGE HERE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

    As you need to add messages to the AM99 system, just edit the SYS00
    member and add messages to it.  Use this convention:

    SYS001A
    SYS001B
    SYS001C
    ~~~~~~~
    ~~~~~~~
    SYS002A
    SYS002B
    ~~~~~~~
    ~~~~~~~
    SYS003A
    SYS003B
    ~~~~~~~
    ~~~~~~~

    You may also add other message members to AM99MSG MACLIB similar to
    the BSD00 and SYS00 members.  For example, you might add a UPD00
    member which containes messages that start with the string UPD00
    such as UPD001A, UPD001B, etc.

    If you are editing a file and wish to quickly edit a member in the
    AM99MSG MACLIB, you can enter:

       COMMAND ===> MSG

    on the command line and then select the member you wish to edit.
    You can also specify a specific member as well:

       COMMAND ===> MSG SYS00

    To insert SQL code into AM990001 PLISQL, position your cursor to the
    desired line and press PF03.  BSDE will list all of the table
    genes in AM99 CONTROL.  If your program will be getting data
    from or putting data to screens, use the ISPF VARIABLE NAMES and
    WITH ZVARS options.  Specify a table and the type of SQL statement
    you desire, press ENTER, and BSDE will then generate all of the
    necessary code.  When generating a SELECT statement for several
    tables via a JOIN, just put a non-blank character next to each table
    in the JOIN.  BSDE will declare all of your host variables and will
    VDEFINE, VPUT, and VGET the host variables in the appropriate
    subroutines within the program skeleton.  Note, if you are working
    with an old program which was not originally generated by BSDE,
    rename your subroutines to follow the BSDE convention (e.g. for PL/I
    VDEFINE: VGET: VPUT:).  In this way, BSDE will be able to find a
    place to add code.  If these routines are missing, BSDE will just
    skip over that part of the code generation.  Once the SQL statement
    has been inserted into your source code, modify the SQL statement if
    necessary.  Supply the WHERE clause at the position indicated by the
    @@@@@@@ characters.  Delete out any columns you do not need in the
    generated SQL code and then press PF08.  BSDE will remove any dead
    code referencing the host variable no longer being used.

    Below is a BSDE generated PL/I SELECT statement for table
    AM99_PRODUCT.

~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*                                                                   */
/* SQL VARIABLES                                                     */
/*                                                                   */
EXEC SQL BEGIN DECLARE SECTION;
/* TABLE AM99DEV.AM99_PRODUCT                                        */
0DCL PRODUCTI                        CHAR(  8) INIT(' ');
0DCL PRODUCTN                        CHAR( 10) INIT(' ');
0DCL VOLONHAN                        FIXED BIN(31) INIT(0);
0DCL PRICE                           FIXED DEC(5,2) INIT(0);
0DCL IND                             FIXED BIN(15) INIT(0);
EXEC SQL END DECLARE SECTION;
/*                                                                   */
/* PROGRAM VARIABLES                                                 */
/*                                                                   */
0DCL C_PRICE                         CHAR(  7) INIT(' ');

~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

EXEC SQL SELECT
       PRODUCT_ID,
       PRODUCT_NAME,
       VOL_ON_HAND,
       PRICE
INTO :PRODUCTI:IND,
      :PRODUCTN:IND,
      :VOLONHAN:IND,
      :PRICE:IND
FROM AM99DEV.AM99_PRODUCT
WHERE @@@@@@@ = :@@@@@@@@;

IF SQLCODE ª= 0
THEN DO;
    SQLMSG = ' AM99001-1 ERROR AM99DEV.AM99_PRODUCT SQLCODE = ';
    ERRCODE = SQLCODE;
    CALL SQL_ERROR;
END;
EXEC SQL COMMIT WORK;

C_PRICE = FCONV(PRICE);

~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ Other Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CALL VPUT;
/*********************************************************************/
/*                                                                   */
/* PROC VDEFINE - MAP THE PLI PROGRAM VARIABLES TO ISPF VARIABLES    */
/*                IN THE SHARED POOL                                 */
/*                                                                   */
/*********************************************************************/
VDEFINE: PROC;
CALL ISPLINK('VDEFINE','PRODUCTI',PRODUCTI            ,'CHAR',L8);
CALL ISPLINK('VDEFINE','PRODUCTN',PRODUCTN            ,'CHAR',L10);
CALL ISPLINK('VDEFINE','VOLONHAN',VOLONHAN            ,'FIXED',L4);
CALL ISPLINK('VDEFINE','PRICE   ',C_PRICE             ,'CHAR',L7);
CALL ISPLINK('VDEFINE','ERRCODE ',ERRCODE             ,'CHAR',L4);
END VDEFINE;
/*********************************************************************/
/*                                                                   */
/* PROC VPUT - PUT VALUES TO THE ISPF SHARED POOL                    */
/*                                                                   */
/*********************************************************************/
VPUT: PROC;
CALL ISPLINK('VPUT','PRODUCTI','SHARED ');
CALL ISPLINK('VPUT','PRODUCTN','SHARED ');
CALL ISPLINK('VPUT','VOLONHAN','SHARED ');
CALL ISPLINK('VPUT','PRICE   ','SHARED ');
END VPUT;

    Notice that BSDE will not add redundant code to your program.
    For example, if declaration statements already exist for host
    variables, BSDE will not add redundant declaration statements
    since this would cause a compilation error.

    To PREP the program, type "P" on the command line and press ENTER.

    COMMAND ===> P

    BSDE will first perform a SAVE of your source code file and will then
    apply the appropriate PREP utility for the language your program is
    written in.

    To compile the program, type "CO" on the command line and press
    ENTER.

    COMMAND ===> CO

    BSDE will first perform a SAVE of your source code file and will then
    compile the program with the appropriate compiler.  Note that in
    this case BSDE would compile AM99001 PLI which is the output source
    generated by the PREP of AM99001 PLISQL.  BSDE only compiles programs
    with filetypes of PLI or COBOL.

    REXX is handled a little differently because it is not compiled.
    For example, when you PREP a program called AM99001 EXEC, BSDE
    creates two output files:

    AM99001 EXEC --> AM99001P EXEC <-- This EXEC you run
                     AM99001A EXEC <-- This EXEC creates your
                                       SQL/DS Access Module

    The AM99001P EXEC is the program that the AM99 system should run.
    The AM99001A EXEC is used by BSDE to create your Access Module. BSDE
    does not erase AM99001A EXEC in case you wish to install your system
    at a location which does not have BSDE. Running the "A" EXECs will
    create all of your Access Modules at the other location.

    To UNPREP a REXX "P" EXEC, go into ISPF edit of the "P" EXEC and
    type "U" on the command line.

    COMMAND ===> U

    In the above example, BSDE would create a new AM99001 EXEC from the
    AM99001P EXEC.  This is very useful since you can debug the AM99001P
    EXEC without having to do compiles or PREPs.  You can change any
    code in the AM99001P EXEC which is not in the "funny comment"
    section and then immediately try it out from your system running on
    the upper screen.
.pa
    Sample:
    Do not change any code in the "funny comment" section  ---+
                                                              |
/*@     'RXSQL XPREP AM99DEV.AM99001                          |       */
/*@      SELECT                                               |       */
/*@        PRODUCT_ID,                                        |       */
/*@        PRODUCT_NAME,                                  <---+       */
/*@        VOL_ON_HAND,                                               */
/*@        PRICE                                                      */
/*@      FROM AM99DEV.AM99_PRODUCT                                    */
/*@      WHERE PRODUCT_ID = ?'                                        */

'RXSQL DECLARE C1 CURSOR FOR 1 IN AM99DEV.AM99001'
'RXSQL OPEN C1 PRODUCTI'           A
                                   |

'RXSQL FETCH C1',              <-- Any of this code can be immediately
'PRODUCTI',                        changed in AM99001P EXEC without the
'PRODUCTN',                        need of a PREP
'VOLONHAN',
'PRICE'                            |
                                   |
IF SQLCODE ª= 0                   V
THEN DO
    SQLMSG = DATE(U) TIME() 'AM99001-1' ERROR AM99DEV.AM99_PRODUCT,
             SQL_CODE '=' SQLCODE
    ADDRESS CMS 'EXECIO 1 DISKW SQL ERRORS A ( STRING' SQLMSG
    ADDRESS ISPEXEC 'VPUT (SQLCODE) SHARED'
    ADDRESS ISPEXEC 'SETMSG MSG(SYS001A)'
    RXSQL ROLLBACK
    EXIT
END
'RXSQL CLOSE C1'
'RXSQL COMMIT'

    Once AM99001P EXEC is operating properly, you can UNPREP it to get
    original source back.

    When your program has been PREPed and compiled (if necessary) flip
    up to the AM99 system with PF21 and test the program.  Try to get
    used to programming on the fly while your system is executing on the
    top screen and then testing the results of the new software on your
    system immediately.  The tight feedback loop between software
    generation and execution is a key component to the BSDE productivity
    boost.  With BSDE, you can achieve a round trip feedback loop of
    several seconds or less.

    While programming, it is useful to periodically SAVE and backup
    files in case VM/CMS goes down.  To do a quick SAVE type:

    COMMAND ===> S

    on the command line when you are in ISPF edit.  To do a quick backup
    type:

    COMMAND ===> B

    on the command line.  For example, if you were editing a file called
    AM99001 EXEC and you entered a "B" on the command line, BSDE would do
    the following:

       SAVE all changes to AM99001 EXEC
       COPY AM99001 EXEC A AM99001 EXEC2 A (REPLACE

    Notice that it copies the file to a file with filetype EXEC2 with
    the REPLACE option.  This gives you a quick way of protecting
    yourself during development.

    To leave a trail of programs behind as you develop a program, type:

    COMMAND ===> V

    on the command line.  In the above example, BSDE would copy the file
    to AM99001 EXEC3, EXEC4, EXEC5 .... etc., using the next available
    filetype.

20. To identify existing screens in the AM99 system type:

    COMMAND ===> PANELID

    on the command line of the AM99 system while it is running under
    option 4.  You will then find the name of the screen member in the
    upper left part of the system screen.  Use Option 1.1.2 (ISPF edit)
    on your lower screen to to modify the AM99PNL MACLIB member.

    If you are editing a file and quickly want to edit the screens in
    the AM99PNL MACLIB, you can enter:

       COMMAND ===> PNL

    on the command line and then select the member you wish to edit.
    You can also specify a specific member:

       COMMAND ===> PNL MASTER

    To add screens to AM99, go into edit of a new member in AM99PNL
    MACLIB.  Press PF01 and a screen will appear listing reusable screen
    skeletons.  Enter the number of the screen type you want (usually
    you want skeleton 4) and press ENTER.  BSDE will then insert the
    skeleton into the new member.

    To add input fields to the screen, position your cursor to where the
    fields should begin and press PF02.  A screen will appear listing
    all of the genes in the AM99 CONTROL file.  Use the ZVARS
    option, choose the desired table and press ENTER.  BSDE will insert
    input fields into the screen with the proper field sizes and the
    ISPF variables will match those generated by BSDE in your programs.
    Below is a sample screen generated for the AM99_PRODUCT table.

)ATTR
DEFAULT(@ª_)
ª TYPE(TEXT) INTENS(LOW) SKIP(ON) COLOR(GREEN)
# TYPE(OUTPUT) INTENS(HIGH)
_ PAD(_)
)BODY
@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SCREEN TITLE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@COMMAND =>_ZCMD                                                               ª


  PRODUCT ID:_Z       ª                <= BSDE generated input fields
  PRODUCT NAME:_Z         ª               for table PRODUCT
  VOL ON HAND:_+Z         ª              "+" signs indicate numeric
  PRICE:_+Z     ª                         fields














ªPress@ENTER:ªContinue         @PF1/PF13:ªHelp    @PF3/PF15:ªPrevious Screen
ª     @PF4/PF1ª:ªMenu
)INIT
  .ZVARS = '(PRODUCTI PRODUCTN VOLONHAN PRICE)' <= BSDE generated
                                                   variables for the screen
                                                   will match those
                                                   generated for programs

    If you want to add fields from other tables, just repeat the above
    procedure.

    To size the screen to fit on a given terminal, enter SC on the
    command line followed by the number of lines you want the screen to
    be (24 is standard).

    COMMAND ===> SC 24

    BSDE will remove or add blank lines to the screen to make it 24 lines
    long.

    Now you can move the fields around on the screen as you please.  Add
    other text to the screen as needed.

    When you press PF01, you will notice that there is an S option on
    the screen.  This option will get you to a menu of reusable
    verification skeletons which can be added to the )PROC section of
    ISPF Dialog Manager panels.  Below is a reusable code skeleton
    which verifies that a variable called @@@@@@@@ on your screen
    is in the YY/MM/DD format for a date.  It checks for the proper
    number of days in the year and even works with leap years.

)PROC

&DATE = &@@@@@@@@
VER(&DATE PICT '99/99/99')
&MM = TRUNC(&DATE '/')
&A = .TRAIL
&DD = TRUNC(&A '/')
&YY = .TRAIL

VER(&MM RANGE 1 12 MSG=BSD001M )
VER(&DD NUM)
VER(&YY NUM)

IF(&MM = 01,03,05,07,08,10,12)
  VER(&DD,NB,RANGE,1,31,MSG=BSD001N)
IF(&MM = 04,06,09,11)
  VER(&DD,NB,RANGE,1,30,MSG=BSD001O)
IF(&MM = 02)
  IF(&YY = 00 04 08 12 16 20 24 28 32 36 40 44 48 52 56 60 64 66 68 +
           72 76 80 84 88 92 96)
    VER(&DD,NB,RANGE,1,29,MSG=BSD001P)
  IF(&YY ª= 00 04 08 12 16 20 24 28 32 36 40 44 48 52 56 60 64 66 +
           68 72 76 80 84 88 92 96)
    VER(&DD,NB,RANGE,1,28,MSG=BSD001Q)

    I don't recommend using the )PROC section of your ISPF Dialog
    Manager panels for heavy duty data verification.  It is very good
    for light duty work, but because of the limitations of the language,
    you can paint yourself into a corner.  Use the )PROC section to do
    easy things and rely on the program displaying the screen,
    preferably a REXX program, to do the heavy duty work.

21. As you generate code for the AM99 system, you will discover flaws in
    your original data model for the system.  This means that you will
    have to modify the AM99 tables.  An easy way to do this is to create
    modified tables on your AM99TEST DBSPACE with Option 1.2 and overlay
    the old table genes with the new table genes in the AM99
    CONTROL file.  Once the new tables have stabilized on AM99TEST, have
    your DBA build corresponding tables on the development DBSPACE with
    his high-level name.

       +--- Modified table      +------------------------+
       |                        |                        |
       V                        V                        |
    AM99DEV.AM99_PRODUCT --> CHIDBA01.AM99_PRODUCT       |
                                                         |
                                             After you feel good about
                                             the new table design, have
                                             your DBA DROP the old table
                                             and rebuild the new one.

    Do a global high-level change in your source code and you're back in
    business.

22. System reports are created by BSDE via Report MOCKUPS. For example,
    use Option 5.2 to layout the structure of a report in a file called
    AM99100 MOCKUP.  Precede the variable fields on the report with an @
    sign as an indicator.  Numeric fields should be entered in the
    desired PIC format (e.g. Z,ZZZ.99).  BSDE will then take the MOCKUP
    file and create a REXX, PL/I, or COBOL program that generates the
    report.  The program will contain all of the necessary I/O
    structures and data formatting logic to create the report.  Then use
    BSDE to generate SELECT statements in the reverse engineered program
    to extract data from the database for the report.
.pa
    Sample PL/I MOCKUP:

ª@1= TODAY_DATE;
ª@2= PAGE_COUNT;
1DATE@1~~~~~~~                                                  PAGE@ZZZ


                       UNIVERSAL BUSINESS FORMS, INC.
                         PRO~FORMA INCOME STATEMENT
                               BY DISTRICT
ª@1 = YEAR;
                             FIRST_QUARTER,@1~~~

                                                              TOTAL
DISTRICT                         JAN        FEB        MAR   1ST QTR.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ª@1 = DISTRICT_NAME;
ª@2 = JAN_SALES;
ª@3 = FEB_SALES;
ª@4 = MAR_SALES;
ª@5 = TOTAL_1ST_QUARTER;
@1~~~~~~~~~~~~~~~~~~~~~~~~  @$ZZZ,ZZ9  @$ZZZ,ZZ9  @$ZZZ,ZZ9  @$ZZZ,ZZ9

    PL/I code generated from the above MOCKUP.

1/*********************************************************************/
/*                                                       * @@@@@@@   */
/*  P R O P R I E T A R Y  ~ ~ ~ ~ ~ ~                   *************/
/*                 TO BE MAINTAINED IN CONFIDENCE                    */
/*                 AMOCO  CORPORATION                                */
/*                                                                   */
/*********************************************************************/
/*                                                                   */
/*                                                                   */
/* PURPOSE: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* INPUT: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* OUTPUT: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* CALLING ENTITIES: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* ENTITIES CALLED: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     */
/*                                                                   */
/*                                                                   */
/* HISTORY:                                                          */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*********************************************************************/
/*                                                                   */
/*                     WRITTEN BY:                                   */
/*                                                                   */
/*                    @@@@@@@@@@@@@@                                 */
/*                                                                   */
/*                      JAN 1987                                     */
/*                                                                   */
/*********************************************************************/
@@@@@@@: PROC OPTIONS(MAIN) REORDER;
/*                                                                   */
/* SQL VARIABLES                                                     */
/*                                                                   */
EXEC SQL BEGIN DECLARE SECTION;
0DCL IND                             FIXED BIN(15) INIT(0);
EXEC SQL END DECLARE SECTION;
/*                                                                   */
/* PROGRAM VARIABLES                                                 */
/*                                                                   */
0DCL SQLERR                          FILE STREAM;
0DCL ISPLINK                         EXTERNAL ENTRY
                                     OPTIONS(ASM INTER RETCODE);
0DCL PLIRETV                         BUILTIN;
0DCL ADDR                            BUILTIN;
0DCL SUBSTR                          BUILTIN;
0DCL STRING                          BUILTIN;
0DCL DATE                            BUILTIN;
0DCL TIME                            BUILTIN;
0DCL ONCHAR                          BUILTIN;
0DCL ONSOURCE                        BUILTIN;
0DCL VERIFY                          BUILTIN;
0DCL 1 TODAY_DATE                    CHAR(  6) INIT(' ');
0DCL 1 DATE_STRUC,
       2 MM                          CHAR(  2) INIT(' '),
       2 SLASH1                      CHAR(  1) INIT('/'),
       2 DD                          CHAR(  2) INIT(' '),
       2 SLASH2                      CHAR(  1) INIT('/'),
       2 YY                          CHAR(  2) INIT(' ');
0DCL TDATE                           CHAR(  8) INIT(' ');
0DCL TIME_STRING                     CHAR(  9) INIT(' ');
0DCL 1 NOW_TIME,
       2 HOURS                       CHAR(  2) INIT(' '),
       2 COLON1                      CHAR(  1) INIT(':'),
       2 MINUTES                     CHAR(  2) INIT(' '),
       2 COLON2                      CHAR(  1) INIT(':'),
       2 SECONDS                     CHAR(  2) INIT(' ');
0DCL 1 NTIME                         CHAR(  8) INIT(' ');
0DCL ERRCODE                         PIC '~~~9' INIT(0);
0DCL SQLMSG                          CHAR( 80) VAR INIT(' ');
0DCL L4                              FIXED BIN(31) INIT(4);
0DCL J                               FIXED BIN(31) INIT(0);
0DCL LINE_COUNT                      FIXED BIN(31) INIT(0);
0DCL PAGE_COUNT                      PIC 'ZZZ9' INIT(1);
/*********************************************************************/
/*                                                                   */
/* NOTE: THE @ SIGNS DEMARK SAMPLE CODE WHICH SHOULD BE REPLACED     */
/*                                                                   */
/* PUT THE BSDE GENERATED I/O RECORDS AT THE BOTTOM OF THIS FILE     */
/* HERE |                                                            */
/*      V                                                            */
/*                                                                   */
/*********************************************************************/
@DCL 1 REC1,
@      2 TEXT1                       CHAR(  1) INIT('1'),
@      2 BLANKS1                     CHAR(  1) INIT(' '),
@      2 TEXT2                       CHAR(  4) INIT('DATE'),
@      2 BLANKS2                     CHAR(  2) INIT(' '),
@      2 V1                          CHAR(  7) INIT('DATE~~~'),
@      2 BLANKS3                     CHAR( 66) INIT(' '),
@      2 TEXT3                       CHAR(  4) INIT('PAGE'),
@      2 BLANKS4                     CHAR(  2) INIT(' '),
@      2 V2                          CHAR(  3) INIT('ZZ9'),
@      2 FILL                        CHAR(43) INIT(' ');
@DCL 1 REC2,
@      2 BLANKS1                     CHAR(  2) INIT(' '),
@      2 TEXT1                       CHAR( 11) INIT('APPLICATION'),
@      2 BLANKS2                     CHAR(  5) INIT(' '),
@      2 TEXT2                       CHAR(  4) INIT('DATA'),
@      2 BLANKS3                     CHAR(  1) INIT(' '),
@      2 TEXT3                       CHAR(  3) INIT('SET'),
@      2 BLANKS4                     CHAR(  5) INIT(' '),
@      2 TEXT4                       CHAR( 14) INIT('RESPONSIBILITY'),
@      2 BLANKS5                     CHAR(  3) INIT(' '),
@      2 TEXT5                       CHAR(  6) INIT('BACKUP'),
@      2 BLANKS6                     CHAR(  1) INIT(' '),
@      2 TEXT6                       CHAR(  9) INIT('FREQUENCY'),
@      2 BLANKS7                     CHAR(  3) INIT(' '),
@      2 TEXT7                       CHAR( 11) INIT('RESPONSIBLE'),
@      2 BLANKS8                     CHAR(  1) INIT(' '),
@      2 TEXT8                       CHAR( 11) INIT('APPLICATION'),
@      2 FILL                        CHAR(43) INIT(' ');
@DCL 1 REC3,
@      2 BLANKS1                     CHAR(  2) INIT(' '),
@      2 V3                          CHAR(  4) INIT('A~~~'),
@      2 BLANKS2                     CHAR( 12) INIT(' '),
@      2 V4                          CHAR(  8) INIT('B~~~~~~~'),
@      2 BLANKS3                     CHAR(  5) INIT(' '),
@      2 V5                          CHAR( 14) INIT('C~~~~~~~~~~~~~'),
@      2 BLANKS4                     CHAR(  3) INIT(' '),
@      2 V6                          CHAR( 16) INIT('D~~~~~~~~~~~~~~~'),
@      2 BLANKS5                     CHAR(  3) INIT(' '),
@      2 V7                          CHAR( 23)
@INIT('E~~~~~~~~~~~~~~~~~~~~~~'),
@      2 FILL                        CHAR(43) INIT(' ');
@DCL 1 REC4,
@      2 BLANKS1                     CHAR(133) INIT(' ');
ON CONV
BEGIN;
    IF ONCHAR = ' '
    THEN
       ONSOURCE = '0';
END;
EXEC SQL INCLUDE SQLCA;
EXEC SQL WHENEVER SQLWARNING CONTINUE;
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL COMMIT WORK;
OPEN FILE(SQLERR) OUTPUT;
TODAY_DATE = DATE;
DATE_STRUC.YY = SUBSTR(TODAY_DATE,1,2);
DATE_STRUC.MM = SUBSTR(TODAY_DATE,3,2);
DATE_STRUC.DD = SUBSTR(TODAY_DATE,5,2);
TDATE = STRING(DATE_STRUC);
CALL VDEFINE;
CALL REPORT;
EXEC SQL COMMIT WORK;
/*********************************************************************/
/*                                                                   */
/* PROC VDEFINE ~ MAP THE PLI PROGRAM VARIABLES TO ISPF VARIABLES    */
/*                IN THE SHARED POOL                                 */
/*                                                                   */
/*********************************************************************/
VDEFINE: PROC;
CALL ISPLINK('VDEFINE','ERRCODE ',ERRCODE             ,'CHAR',L4);
END VDEFINE;
/*********************************************************************/
/*                                                                   */
/* PROC SQL_ERROR ~ PERFORM ERROR ESCAPE IF A BAD SQLCODE IS RETURNED*/
/*                                                                   */
/*********************************************************************/
SQL_ERROR: PROC;
CALL GET_TIME;
SQLMSG = TDATE || ' ' || NTIME || ' ' || SQLMSG || ' ' || ERRCODE;
PUT FILE(SQLERR) SKIP LIST(SQLMSG);
CALL ISPLINK('VPUT','ERRCODE ','SHARED ');
CALL ISPLINK('SETMSG','BSD001T ');
EXEC SQL ROLLBACK WORK;
CALL EXIT;
END SQL_ERROR;
/*********************************************************************/
/*                                                                   */
/* PROC GET_TIME ~ GET THE CURRENT TIME                              */
/*                                                                   */
/*********************************************************************/
GET_TIME: PROC;
TIME_STRING = TIME;
NOW_TIME.HOURS = SUBSTR(TIME_STRING,1,2);
NOW_TIME.MINUTES = SUBSTR(TIME_STRING,3,2);
NOW_TIME.SECONDS = SUBSTR(TIME_STRING,5,2);
NTIME = STRING(NOW_TIME);
END GET_TIME;
/*********************************************************************/
/*                                                                   */
/* PROC REPORT                                                       */
/*                                                                   */
/*********************************************************************/
REPORT: PROC;
CALL CURSOR;
DO I = 1 TO 1000000;
    CALL WRITE_HEADER;
    DETAIL_LOOP:
    DO J = 1 TO 1000000;
       CALL FETCH_DATA;
       IF SQLCODE = 100
       THEN
          RETURN;
       CALL WRITE_DETAIL;
       LINE_COUNT = LINE_COUNT + 1;
       IF LINE_COUNT = 60
       THEN
          LEAVE DETAIL_LOOP;
    END;
    PAGE_COUNT = PAGE_COUNT + 1;
END;
END REPORT;
/*********************************************************************/
/*                                                                   */
/* PROC WRITE_HEADER ~ PUT THE BSDE GENERATED HEADER RECORDS HERE.   */
/*                                                                   */
/* LINE_COUNT SHOULD BE SET TO THE NUMBER OF THE LAST RECORD IN      */
/* THE HEADER                                                        */
/*                                                                   */
/*********************************************************************/
WRITE_HEADER: PROC;
@V1 = DATE;
@V2 = 99;
@WRITE FILE(OUT) FROM(REC1);
@WRITE FILE(OUT) FROM(REC2);
LINE_COUNT = @;   /*  <= 2 IN THIS EXAMPLE   */
END WRITE_HEADER;
/*********************************************************************/
/*                                                                   */
/* PROC WRITE_DETAIL ~ PUT THE BSDE GENERATED DETAIL RECORDS HERE.   */
/*                                                                   */
/*********************************************************************/
WRITE_DETAIL: PROC;
@V3 = APPL;
@V4 = PROD_DATA_SET;
@V5 = RECOV_RESP;
@V6 = BACKUP_FREQ;
@V7 = RESPONSIBLE_APPL;
@WRITE FILE(OUT) FROM(REC3);
END WRITE_DETAIL;
/*********************************************************************/
/*                                                                   */
/* PROC CURSOR ~ PUT THE CURSOR SEGMENT OF THE BSDE GENERATED SELECT */
/*               STATEMENT HERE |                                    */
/*                              V                                    */
/*********************************************************************/
CURSOR: PROC;
@EXEC SQL DECLARE C1 CURSOR FOR SELECT
@  APPL,
@  BACKUP_DATA_SET,
@  RECOV_RESP,
@  BACKUP_FREQ,
@  RESPONSIBLE_APPL
@FROM APSYSTEM.SZ42R200
@WHERE SITE = :SITE:IND;
@
@EXEC SQL COMMIT WORK;
@EXEC SQL OPEN C1;
END CURSOR;
/*********************************************************************/
/*                                                                   */
/* PROC FETCH_DATA ~ PUT THE FETCH PART OF THE BSDE GENERATED SELECT */
/*                   STATEMENT HERE.  BE SURE TO REMOVE THE DO LOOP  */
/*                   OF THE FETCH AND CHANGE THE                     */
/*                                                                   */
/*                   LEAVE FETCH_LOOP; => RETURN;                    */
/*                                                                   */
/*********************************************************************/
FETCH_DATA: PROC;
@   EXEC SQL FETCH C1 INTO
@   :APPL:IND,
@   :PROD_DATA_SET:IND,
@   :RECOV_RESP:IND,
@   :BACKUP_FREQ:IND,
@   :RESPONSIBLE_APPL:IND;
@   IF SQLCODE = 100
@   THEN
@      RETURN;
@   IF SQLCODE ª= 0
@   THEN DO;
@      SQLMSG = ' SZ42140~1 ERROR SZ42R200 SQLCODE = ';
@      ERRCODE = SQLCODE;
@      EXEC SQL CLOSE C1;
@      CALL SQL_ERROR;
@   END;
END FETCH_DATA;
/*********************************************************************/
/*                                                                   */
/* PROC EXIT ~ SHUT DOWN THE PROGRAM AND EXIT                        */
/*                                                                   */
/*********************************************************************/
EXIT: PROC;
EXIT;
END EXIT;
END @@@@@@@;
/*********************************************************************/
/*                                                                   */
/* BELOW IS THE I/O CODE GENERATED FROM YOUR MOCKUP.                 */
/*                                                                   */
/* GENERATE SELECT STATEMENTS WITH PF3 BELOW THIS CODE AND BUST UP   */
/* THE CODE BASED ON THE INSTRUCTIONS ABOVE.                         */
/*                        |                                          */
/*                        V                                          */
/*                                                                   */
/*********************************************************************/
0DCL 1 REC1,
       2 TEXT1                       CHAR(  5) INIT('1DATE'),
       2 BLANKS1                     CHAR(  1) INIT(' '),
       2 V1                          CHAR(  8) INIT('1~~~~~~~'),
       2 BLANKS2                     CHAR( 50) INIT(' '),
       2 TEXT2                       CHAR(  4) INIT('PAGE'),
       2 BLANKS3                     CHAR(  1) INIT(' '),
       2 V2                          CHAR(  3) INIT('ZZZ'),
       2 FILL                        CHAR(8) INIT(' ');
0DCL 1 REC2,
       2 BLANKS1                     CHAR(80) INIT(' ');
0DCL 1 REC3,
       2 BLANKS1                     CHAR(80) INIT(' ');
0DCL 1 REC4,
       2 BLANKS1                     CHAR( 23) INIT(' '),
       2 TEXT1                       CHAR(  9) INIT('UNIVERSAL'),
       2 BLANKS2                     CHAR(  1) INIT(' '),
       2 TEXT2                       CHAR(  8) INIT('BUSINESS'),
       2 BLANKS3                     CHAR(  1) INIT(' '),
       2 TEXT3                       CHAR(  6) INIT('FORMS,'),
       2 BLANKS4                     CHAR(  1) INIT(' '),
       2 TEXT4                       CHAR(  4) INIT('INC.'),
       2 FILL                        CHAR(27) INIT(' ');
0DCL 1 REC5,
       2 BLANKS1                     CHAR( 25) INIT(' '),
       2 TEXT1                       CHAR(  9) INIT('PRO~FORMA'),
       2 BLANKS2                     CHAR(  1) INIT(' '),
       2 TEXT2                       CHAR(  6) INIT('INCOME'),
       2 BLANKS3                     CHAR(  1) INIT(' '),
       2 TEXT3                       CHAR(  9) INIT('STATEMENT'),
       2 FILL                        CHAR(29) INIT(' ');
0DCL 1 REC6,
       2 BLANKS1                     CHAR( 31) INIT(' '),
       2 TEXT1                       CHAR(  2) INIT('BY'),
       2 BLANKS2                     CHAR(  1) INIT(' '),
       2 TEXT2                       CHAR(  8) INIT('DISTRICT'),
       2 FILL                        CHAR(38) INIT(' ');
0DCL 1 REC7,
       2 BLANKS1                     CHAR( 29) INIT(' '),
       2 TEXT1                       CHAR( 14) INIT('FIRST_QUARTER,'),
       2 BLANKS2                     CHAR(  1) INIT(' '),
       2 V3                          CHAR(  4) INIT('1~~~'),
       2 FILL                        CHAR(32) INIT(' ');
0DCL 1 REC8,
       2 BLANKS1                     CHAR(80) INIT(' ');
0DCL 1 REC9,
       2 BLANKS1                     CHAR( 62) INIT(' '),
       2 TEXT1                       CHAR(  5) INIT('TOTAL'),
       2 FILL                        CHAR(13) INIT(' ');
0DCL 1 REC10,
       2 BLANKS1                     CHAR(  1) INIT(' '),
       2 TEXT1                       CHAR(  8) INIT('DISTRICT'),
       2 BLANKS2                     CHAR( 25) INIT(' '),
       2 TEXT2                       CHAR(  3) INIT('JAN'),
       2 BLANKS3                     CHAR(  8) INIT(' '),
       2 TEXT3                       CHAR(  3) INIT('FEB'),
       2 BLANKS4                     CHAR(  8) INIT(' '),
       2 TEXT4                       CHAR(  3) INIT('MAR'),
       2 BLANKS5                     CHAR(  3) INIT(' '),
       2 TEXT5                       CHAR(  3) INIT('1ST'),
       2 BLANKS6                     CHAR(  1) INIT(' '),
       2 TEXT6                       CHAR(  4) INIT('QTR.'),
       2 FILL                        CHAR(10) INIT(' ');
0DCL 1 REC11,
       2 BLANKS1                     CHAR(  1) INIT(' '),
       2 TEXT1                       CHAR( 69)
INIT('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~'),
       2 FILL                        CHAR(10) INIT(' ');
0DCL 1 REC12,
       2 BLANKS1                     CHAR(80) INIT(' ');
0DCL 1 REC13,
       2 BLANKS1                     CHAR(  1) INIT(' '),
       2 V4                          CHAR( 25)
INIT('1~~~~~~~~~~~~~~~~~~~~~~~~'),
       2 BLANKS2                     CHAR(  3) INIT(' '),
       2 V5                          PIC '$ZZZ,ZZ9' INIT(0),
       2 BLANKS3                     CHAR(  3) INIT(' '),
       2 V6                          PIC '$ZZZ,ZZ9' INIT(0),
       2 BLANKS4                     CHAR(  3) INIT(' '),
       2 V7                          PIC '$ZZZ,ZZ9' INIT(0),
       2 BLANKS5                     CHAR(  3) INIT(' '),
       2 V8                          PIC '$ZZZ,ZZ9' INIT(0),
       2 FILL                        CHAR(10) INIT(' ');
0DCL 1 REC14,
       2 BLANKS1                     CHAR(80) INIT(' ');
0DCL OUT                             FILE RECORD;
0DCL I                               FIXED BIN(31) INIT(0);

OPEN FILE(OUT) OUTPUT;
V1 = TODAY_DATE;
V2 = PAGE_COUNT;
WRITE FILE(OUT) FROM(REC1);
WRITE FILE(OUT) FROM(REC2);
WRITE FILE(OUT) FROM(REC3);
WRITE FILE(OUT) FROM(REC4);
WRITE FILE(OUT) FROM(REC5);
WRITE FILE(OUT) FROM(REC6);
V3 = YEAR;
WRITE FILE(OUT) FROM(REC7);
WRITE FILE(OUT) FROM(REC8);
WRITE FILE(OUT) FROM(REC9);
WRITE FILE(OUT) FROM(REC10);
WRITE FILE(OUT) FROM(REC11);
WRITE FILE(OUT) FROM(REC12);
V4 = DISTRICT_NAME;
V5 = JAN_SALES;
V6 = FEB_SALES;
V7 = MAR_SALES;
V8 = TOTAL_1ST_QUARTER;
WRITE FILE(OUT) FROM(REC13);

23. When the system is completed, use Option 6 to document the system.
    The embryo for the AM99 system comes with an online manual which
    conforms to corporate standards and covers all of the functions it
    already performs.  Use Option 6.5 of BSDE to unload specific
    sections of the online manual to a sequential file divided by
    section records.

    Sample unload of section 5.2.10 from the online manual:

DEFAULT(@ª~)
@SEC 5.2.10 ~~~~~~~~~~ LOAD SEQUENTIAL FILES INTO TABLES ~~~~~~~~~~~~~~~~ PAGE 1

This option allows you to load the unloaded files back into the system tables.
When this option is invoked, a file composed of DATALOAD statements will appear
with one DATALOAD statement for each table which was previously unloaded.  You
may modify the DATALOAD statements to reflect changes in the names of the table
columns or the locations of column data on the UNLOAD file.

You may DATALOAD the table from a file different from the file to which the
table was unloaded.  Suppose you had a table called GASOLINE which you unloaded
to GASOLINE UNLOAD with LRECL 323.

CREATE TABLE AM99DEV.GASOLINE
    (FIELD_1                         CHAR(  8) NOT NULL,
     FIELD_2                         CHAR( 10),
     FIELD_3                         VARCHAR(254),
     FIELD_4                         SMALLINT,
     FIELD_5                         INTEGER,
     FIELD_6                         DECIMAL(5,2),
     FIELD_7                         FLOAT)
     IN AO679;

CREATE UNIQUE INDEX INDEX_GASOLINE     ON AM99DEV.GASOLINE
    (FIELD_1,FIELD_2)   PCTFREE = 10;

The Generated DATALOAD statement would look like this:

DATALOAD TABLE (AM99DEV.GASOLINE)
   FIELD_1 1-8
   FIELD_2 10-19
   FIELD_3 21-274
   FIELD_4 276-281
   FIELD_5 283-293
   FIELD_6 295-301
   FIELD_7 303-322
INFILE (GASOLINE)
COMMIT WORK;

    You may alter the text in a section, drop a section, or add
    additional sections to the sequential file. To add a section
    just add a section record with the section title followed by
    the text for the section:

@SEC 5.3.4 THIS IS A NEW SECTION

Write text for the section here ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    To force a page break in your online manual add a .PA record in
    the file just like you do with DCF SCRIPT.

    Then use Option 6.6 to update the online manual and the table of
    contents for the manual.  Be sure to use the word processing line
    commands of ISPF edit, Text Split (TS) and Text Flow (TF), to format
    the text for the manual sections.  I recommend doing a TF80 on each
    paragraph in the manual.  This makes the text a full screen in width
    when viewed by a user.  Again, do this in an interactive mode with
    your system running on the upper screen under Option 4 while you use
    Option 6 on the lower screen to modify the online manual.  This will
    provide a tight feedback loop because you can immediately flip up to
    your system with PF21 and see the latest changes to the online
    manual.  Option 6.7 can be used to do a spelling check on the
    retrieved sections.

    To create a hardcopy version of the manual use Option 6.2 to unload
    the entire online manual.  Then run Option 6.3.2 to convert the
    unloaded file to a DCF SCRIPT file for the hardcopy version of your
    manual.  Use Option 6.3.6 to do a spelling check of the manual
    SCRIPT file.  Then use Option 6.3.3 to SCRIPT the file and print it
    on the 3800 laser printer on the standard 16-285 manual FLASH.

24. Finally, use Option 7 to install the completed system on either
    VM/CMS or MVS.  Have your client and DBA do a final review of your
    system before moving from the development environment to the
    production environment.

  - For VM:

    Set up a production ID called AM99 and send the AM99 CONTROL file to
    your DBA.  Your DBA should set up DBSPACES to hold the production
    SQL/DS tables.  He can then use BSDE and the AM99 CONTROL file to
    create the tables and indexes.

    Use Option 7.2.2 to PUNCH the entire system from AM99DEV to AM99.

    Use Option 7.2.3 to read in the PUNCHED system into AM99 and change
    all of the high level names of tables to that of your DBA.

    Options 7.2.4.2, 7.2.4.3, and 7.2.4.4 can be used by your DBA to
    PREP and COMPILE REXX, PL/I, and COBOL programs into production.

    Option 7.2.4.5 can be used by your DBA to run GRANTS on the
    resulting Access Modules.

  - For MVS:

    Use Option 7.3.2 to convert the AM99PNL MACLIB containing the AM99
    panels into a PDS with panel members at either CIT or TDC.

    Use Option 7.3.3 to convert the AM99 ISPF Dialog Manager messages in
    AM99MSG MACLIB into a PDS with message members at either CIT or TDC.

    Use Option 7.3.4.2 to send files which start with AM99 to either CIT
    or TDC.

    Use Option 7.3.4.3 to delete files at CIT or TDC which start with
    USERID.AM99.

    Use Option 7.3.5.2 to send other files to either CIT or TDC.

    Use Option 7.3.5.3 to delete other files at CIT or TDC.

    Use Option 7.3.6 to get files from CIT or TDC and send them to your
    VM/CMS reader.

    Use Option 7.3.7 to read MVS files in from your reader and put them
    into VM/CMS files.

    Have your DBA run your AM99 CONTROL file through Option D.1.7 of
    ISPF to create your DB2 tables and indexes.  Send the source code
    for your programs to MVS and then pre-compile, compile and bind the
    programs using Option D.1.3 of ISPF.  Modify the AM99 EXEC driver
    for the AM99 system so that it does ALLOCATES instead of FILEDEFS.

25. The above steps can be modified slightly for use in a JAD session.
    Make arrangements for a meeting room which is equipped with both a
    projector terminal and student terminals.  Try to have a local
    printer nearby for the printing of diagrams.  Then go through the
    data modeling steps above, but do it on the projector terminal for
    all to see.  Once the roughed out database has been created and
    populated with test data, have the clients in the room try it out
    with QMF from their terminals.

    When the time comes to rough out the system dialog, all members of
    the JAD team should use Option 8 of BSDE. When Option 8 is entered,
    BSDE displays a screen requesting the JAD leader's ID. In the
    example we have been working with everyone should enter AM99DEV.
    Next the JAD leader should run Option 8.2.  This will build an
    embryo on AM99DEV.  When the other JAD members run option 8.2, BSDE
    will copy over the AM99 ERDIAG and the AM99 CONTROL file from
    AM99DEV to their ID's and will plug them into the AM99 system.

    The JAD leader should then begin interactively changing the AM99
    system on the projector terminal.  He should run AM99 under Option
    8.2 on the top screen and use Option 1.1.2 (ISPF edit) on the lower
    screen as before.  The JAD team members will be plugged into the
    AM99 system via Option 8.2 and will be able to interactively try out
    any portion of the AM99 system while it is being developed.
.pa
    Caution:
    Whenever the JAD leader on AM99DEV does a "SAVE" of a AM99 system
    file, the JAD team members MUST press PF02 (not PF14) to get in
    sync with the AM99 system on AM99DEV.  Failure to press PF02 will
    cause an individual JAD team member to ABEND when he tries to use
    the changed file.

26. To maintain the AM99 system simply do the maintenance work on
    AM99DEV and send over the modified files to either the AM99
    production ID or to MVS.  Be sure to keep a mirror image of the AM99
    system on AM99DEV.  Never do maintenance directly on the production
    version of AM99.

    Use the EXAMINE utility to find where you need to make
    maintenance modifications to programs.  Suppose you need to modify
    the AM99_PRODUCT table and need to know where the AM99_PRODUCT table
    is being accessed in the AM99 system.  For example:

    EXAMINE * PLISQL (CHIDBA01.AM99_PRODUCT

    would search all of the PL/I programs and would list those accessing
    the PRODUCT table.