*DECK DB$JLO
USETEXT CDCSCTX 
USETEXT JLPCMTX 
  
      PROC DB$JLO;
      BEGIN 
 #
* *   DB$JLO -- OUTPUT A JOURNAL LOG RECORD      PAGE  1
* *   BOB MCALLESTER                             DATE  12/01/80 
* 
* DC  PURPOSE 
* 
*     COMPLETE THE DATA IN THE JOURNAL LOG RECORD.
*     SEND THE LOG RECORD TO THE JOURNAL LOG FILE, OR TO THE TRF IF 
*     WITHIN A BEGIN/COMMIT TRANSACTION SEQUENCE. 
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
* 
*     NONE
* 
* D   ASSUMPTIONS 
* 
*     /DB$JLCM/              JOURNAL LOG COMMON.
*       P<JLREC>             POINTS TO THE JOURNAL LOG RECORD.
*       P<PRIMKEY>           POINTS TO THE PRIMARY KEY OF A BEFORE/AFTER
*                            IMAGE. 
*       PARLEN               LENGTH (CHARACTERS) OF THE JOURNAL LOG 
*                            RECORD.  DOES NOT INCLUDE THE RECORD IMAGE.
*       TRLRLEN              LENGTH (CHARACTERS) OF THE RECORD IMAGE. 
*       WSA                  LOCATION OF THE RECORD IMAGE.
* 
*     CDCSCOMMN 
*       P<RCB>
*       P<RSB>
*       P<RSARBLK>
* 
* DC  EXIT CONDITIONS 
* 
*     THE JOURNAL LOG RECORD HAS BEEN RECORDED ON THE TRF OR ON THE 
*     JOURNAL LOG FILE. 
* 
* DC  CALLING ROUTINES
* 
*     REQUEST SYMBIONTS.
* 
* DC  CALLED ROUTINES 
# 
      XREF FUNC DB$CDEC C(10);  # INTEGER TO DISPLAY CODED DECIMAL     #
      XREF PROC DB$FLOP;     # GENERATE A FLOW POINT RECORD            #
      XREF PROC DB$JLCT;     # JOURNAL LOG CONTROLLER                  #
      XREF PROC DB$JLRS;     # JOURNAL LOG RESERVATION                 #
      XREF PROC DB$POP;      # RESTORE A WORD FROM THE RCB STACK       #
      XREF PROC DB$POP2;     # RESTORE TWO WORDS FROM THE RCB STACK    #
      XREF PROC DB$PSH2;     # SAVE TWO WORDS ON THE RCB STACK         #
      XREF PROC DB$PUSH;     # SAVE A WORD ON THE RCB PUSH DOWN STACK  #
      XREF PROC DB$TRFW;     # WRITE TO THE TRANSACTION FILE           #
# 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     THE JOURNAL LOG RECORD. 
* 
* DC  DESCRIPTION 
* 
*     THE JOURNAL LOG COMMON LENGTH PARAMETERS, PARLEN AND TRLRLEN, 
*     GIVE THE LENGTHS IN CHARACTER COUNTS. 
*     EQUIVALENT WORD LENGTHS ARE COMPUTED. 
* 
*     IF THE ACTION BEING LOGGED AFFECTS A SPECIFIC AREA, 
*     RECORD THE AREA ID AND VERSION NAME.
* 
*     'BEFORE/AFTER IMAGE' LOG RECORDS ARE PASSED TO DB$JLO WITH SPACES 
*     IN THE TRAILER SIZE FIELD.
*       THE SPACES ARE REPLACED WITH THE COMPUTED TRAILER SIZE
*       AND JLHDPAD IS FILLED WITH THE DISPLAY CODED NUMBER OF UNUSED 
*       CHARACTERS AT THE END OF THE RECORD IMAGE.
*       IF THE KEY LENGTH HAS NOT BEEN PROVIDED ON A PRIOR CALL,
*         THE KEY AND KEY LENGTH ARE INSERTED INTO THE LOG RECORD.
*         (IF DONE ON A BEFORE-IMAGE, IT WONT BE DONE ON AN AFTER-IMAGE)
* 
*     IF THE ACTION BEING LOGGED HAS OCCURRED WITHIN A TRANSACTION, 
*       DB$TRFW IS CALLED TO WRITE THE LOG RECORD ON THE TRANSACTION
*       RECOVERY FILE (TRF).
*     OTHERWISE IT IS WRITTEN TO THE JOURNAL LOG FILE BY CALLING
*       DB$JLRS AND DB$JLCT.
*       THE DB$JLRS REQUEST MAY BE TERMINATED ABNORMALLY WHEN SPACE IS
*       NOT AVAILABLE ON THE CURRENT LOG FILE AND NO OTHER LOG FILE IS
*       AVAILABLE.
*       IF THIS OCCURS ON ANYTHING OTHER THAN A RUN-UNIT TERMINATION, 
*       ERROR 642 IS ISSUED THROUGH DB$ERR AND CONTROL DOES NOT RETURN
*       FROM DB$JLRS. 
*       ON A TERMINATION LOG RECORD, THERE IS NO LONG-TERM CONNECTION.
*       IN THIS CASE DB$JLRS RETURNS WITHOUT HAVING RESERVED SPACE. 
*       THE TERMINATION LOG RECORD THEN CAN NOT BE WRITTEN. 
 #
  
#     LOCAL VARIABLES                                                  #
  
      ITEM PARLENW I;        # LENGTH (WORDS) OF JOURNAL LOG RECORD,   #
                             # EXCLUSIVE OF RECORD IMAGE               #
      ITEM TRLRLENW I;       # LENGTH (WORDS) OF RECORD IMAGE          #
      ITEM SCRATCH I; 
      CONTROL EJECT;
  
#     S T A R T   O F   D B $ J L O   E X E C U T A B L E   C O D E .  #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("JLO"); 
      CONTROL ENDIF;
  
      DB$PUSH(DB$JLO);
  
#     COMPUTE WORD LENGTHS                                             #
  
      PARLENW = (PARLEN+9)/10;
      TRLRLENW = (TRLRLEN+9)/10;
  
#     IF THE LOGGING RECORD TYPE CODE INDICATES AN ACTION ON AN AREA,  #
#     RECORD THE AREA ID AND VERSION NAME.                             #
  
      IF JLHDTYPE[0] GQ DFJLRQTR
        AND JLHDTYPE[0] LQ DFJLRQIN 
      THEN
        BEGIN 
        JLHDARID[0] = DB$CDEC(RSARID[0],4); 
        JLHDVENM[0] = RSFVENAME[0]; 
        END 
  
#     IF THE JOURNAL RECORD IS A BEFORE/AFTER IMAGE, COMPLETE SOME     #
#     ADDITIONAL HEADER FIELDS.                                        #
  
      IF JLHDTRLS[0] EQ " " 
      THEN                   # COMPLETE THE LOG RECORD                 #
        BEGIN 
                             # SET NUMBER OF CHARACTERS IN THE TRAILER #
        JLHDTRLS[0] = DB$CDEC(PARLENW*10 + TRLRLENW*10 - DFHDRSZ, 6); 
  
                             # NUMBER OF UNUSED CHARACTERS AT THE END  #
                             # OF THE RECORD IMAGE                     #
        SCRATCH = TRLRLENW * 10 - TRLRLEN + O"33";
        JLHDPAD[0] = C<9,1>SCRATCH; 
  
        IF JLHDKEYL[0] EQ "000" 
        THEN                 # THE KEY LENGTH IS NOT FILLED IN YET     #
          BEGIN 
          SCRATCH = PARLEN - DFHDRSZ;  # KEY LENGTH                    #
          JLHDKEYL[0] = DB$CDEC(SCRATCH,3); 
                             # INSERT THE KEY VALUE                    #
          C<0,(SCRATCH+9)/10*10>JLBARKEY[0] = C<0,SCRATCH>PRKEY[0]; 
          END 
        END 
  
#     IF THIS USER JOB IS WITHIN A BEGIN/COMMIT SEQUENCE,              #
#       CALL DB$TRFW TO WRITE TO THE TRANSACTION FILE.                 #
#       RETURN.                                                        #
  
      IF TQARTX[0] NQ 0 
        AND (JLHDTYPE[0] EQ DFJLRQAI
        OR JLHDTYPE[0] EQ DFJLRQBI
        OR JLHDTYPE[0] EQ DFJLRQTR) 
      THEN
        BEGIN 
        DB$TRFW(P<JLREC>,PARLENW,WSA,TRLRLENW); 
        DB$POP(DB$JLO); 
        RETURN; 
  
        END 
  
#     IF NOT WITHIN A BEGIN/COMMIT SEQUENCE,                           #
#       CALL DB$JLRS TO RESERVE SPACE ON THE JOURNAL LOG FILE.         #
#       CALL DB$JLCT TO WRITE TO THE JOURNAL LOG FILE.                 #
  
      DB$PSH2(PARLENW,P<JLREC>);
      DB$PSH2(TRLRLENW,WSA);
      DB$JLRS(PARLENW + TRLRLENW);
      DB$POP2(WSA,TRLRLENW);
      DB$POP2(P<JLREC>,PARLENW);
  
#     AN INTERNAL TASK OR A TERMINATING USER TASK RETURNS THROUGH HERE #
#     IF IT IS UNSUCCESSFUL IN RESERVING JOURNAL LOG SPACE.            #
#     THIS SITUATION IS FLAGGED BY A CONTINATION TYPE OF DFWAITTERM.   #
#     NO ATTEMPT SHOULD BE MADE TO WRITE TO THE JLF.                   #
  
      IF RCCT[0] NQ DFWAITTERM
      THEN
        BEGIN 
        DB$JLCT(P<JLREC>,PARLENW,WSA,TRLRLENW,
             JLHDTYPE EQ DFJLRQBI  # FORCE BEFORE IMAGES TO DISK       #
          OR JLHDTYPE EQ DFJLRQAI  # FORCE AFTER IMAGES                #
          OR JLHDTYPE EQ DFJLRQRP  # FORCE RECOVERY POINT LOG RECORDS  #
          );
        END 
      DB$POP(DB$JLO); 
      RETURN; 
      END 
      TERM
