*DECK DB$CCHK 
USETEXT UTMPTTX 
USETEXT UTCITTX 
USETEXT MDBCMTX 
      PROC DB$CCHK; 
      BEGIN 
 #
  *   DB$CCHK - COMPARE CHECKSUMS                PAGE  1
  *   L. G. WHITE                                DATE  08/30/78 
  
  DC  PURPOSE 
  
      COMPARE CHECKSUMS OF AREAS AND RELATIONS CONTAINED IN MD SCHEMA 
      AGAINST THE CHECKSUMS IN THE ATTACHED SCHEMA AND SUBSCHEMA TO SEE 
      IF THE SCHEMA AND SUBSCHEMA INFORMATION IS ALL CONSISTENT.
  
  DC  ENTRY CONDITIONS
  
      SCHEMA, SUBSCHEMA FILES OPEN, BLOCK POINTERS CHKSMBP AND MDCHKSMBP
      SET.
  
  DC  EXIT CONDITIONS 
  
      SCHEMA IN MD, ATTACHED SCHEMA, ATTACHED SUBSCHEMA ARE VERIFIED
      AS CONSISTENT.  MD SCHEMA CKSM BLOCK POINTER SET TO POINT 
      TO CMM BLOCK CONTAINING CKSM LIST.  BLOCK HAS BEEN ALLOCATED FOR
      LOCAL CHECKSUM LIST BLOCK - BLOCK POINTER SET.  ABNORMAL EXIT 
      THROUGH DB$CERR WITH ERROR NUMBERS 7151CCHK-7160CCHK. 
  
  DC  CALLING ROUTINES
  
      DB$CBLD - CST BUILDER CONTROLLING ROUTINE 
  
  DC  CALLED ROUTINES 
  
      DB$CERR - CST BUILDER ERROR HANDLER 
      DB$CGSB - WA GET FROM SUBSCHEMA FILE
      DB$CGSC - WA GET FROM SCHEMA FILE 
      DB$UAWS - ADJUST WORK SPACE 
      DB$USHR - SHRINK WORK SPACE 
  
  DC  NON-LOCAL VARIABLES 
  
      NONE
  
  DC  DESCRIPTION 
  
  
      ENSURE THAT THE ATTACHED SCHEMA IS LOGICALLY THE SAME AS SCHEMA 
      IN THE MD BY COMPARING AREA AND RELATION CHECKSUMS FOR EACH AREA
      AND RELATION IN THE SCHEMA.  ENSURE THAT THE SUBSCHEMA IS CONSIS- 
      TENT WITH THE MD SCHEMA BY COMPARING AREA AND RELATION CHECKSUMS
      FOR EACH AREA AND RELATION IN THE SUBSCHEMA.  EXIT IS THROUGH 
      DB$CERR IF AN AREA OR RELATION IS NOT FOUND IN THE MD SCHEMA OR IF
      THERE IS A CHECKSUM MISMATCH. 
      NOTE:  "MD SCHEMA" REFERS TO THE SCHEMA INFORMATION CURRENTLY 
      BEING PROCESSED BY THE MDU.  "ATTACHED SCHEMA" REFERS TO THE
      ACTUAL DDL SCHEMA FILE ATTACHED TO THE CP.  THESE TWO INFORM- 
      ATION STRUCTURES MAY BE IDENTICAL, AS IN THE CASE THAT THE RUN
      IS A CREATION RUN FOR THAT SCHEMA.
 #
# 
      UNLISTED: UTCDFDCLS, UTCITDCLS, MDBCMDCLS, UTMPTDCLS, UTCASDCLS 
# 
      CONTROL NOLIST; 
*CALL UTCDFDCLS 
*CALL UTCASDCLS 
      CONTROL LIST; 
      CONTROL EJECT;
  
  
      XREF
        BEGIN 
        PROC DB$CERR;        # CST ERROR HANDLER #
        PROC DB$CGSB;        # W A GET FROM SUBSCH FILE # 
        PROC DB$CGSC;        # WA GET FROM SCH FILE # 
        PROC DB$UAWS;        # ADJUST WORK SPACE #
        PROC DB$USHR;        # SHRINK WORK SPACE #
        END 
  
      BASED ARRAY CHKSMENTRY S(DFCKSMSZ);   # B.ARRAY FOR LOCAL CHKSMS# 
        BEGIN 
        ITEM HDRNUMREL  U(0,36,12);   # HDR WRD - NUMBER RELTNS        #
        ITEM HDRNUMAR   U(0,48,12);   # HDR WORD - NUMBER AREAS       # 
        ITEM ELEMNAM    C(0,00,30);   # AREA OR RELATION NAME          #
        ITEM CKSUM      U(3,00,60);   # CHECKSUM FOR AREA OR RELATION  #
        END 
  
      ITEM CONTROLIST U;           # FWA OF LIST BEING VALIDATED     #
      ITEM SEARCHLIST U;             # FWA OF MD SCHEMA CKSUM LIST #
      ITEM CNUMENTRIES U;            # NUM ELEMS TO CHECK IN CNTRL LIST#
      ITEM SNUMENTRIES U;            # NUM ELEMS TO SRCH IN SRCH LIST  #
      ITEM SIZE U;                   # SIZE OF BLOCK BEING ALLOCATED  # 
      ITEM ERR1 C(8);                # VARIABLE PARAMETER TO CERR # 
      ITEM ERR2 C(8);                # VARIABLE PARAMETER TO CERR # 
      ITEM FLAG U;                   # ERROR FLAG RETURNED BY COMPARE # 
      ITEM I I;                      # SCRATCH VARIABLE # 
      ITEM J I;                      # SCRATCH VARIABLE # 
      ITEM MDCHKPOINT U;             # ADDR. OF GLOBAL CHKSM BLOCK #
      ITEM CHKPOINT U;               # ADDR. OF LOCAL CHKSM BLOCK # 
      LABEL ERREXIT;                 # SET UP TO CALL DB$CERR # 
  
      CONTROL EJECT;
  
      PROC COMPARE; 
      BEGIN 
# 
 *    COMPARE CHECKSUMS IN THE TWO LISTS WHOSE FWA"S ARE GIVEN
 *    BY SEARCHLIST AND CONTROLIST.  THE PROC CHECKS CNUMENTRIES
 *    OF CONTROLIST BY PULLING A DATABASE ELEMENT NAME FROM THAT
 *    LIST AND LOOKING FOR THAT NAME IN THE FIRST SNUMENTRIES OF
 *    SEARCHLIST.  IF AN ERROR OCCURS, FLAG IS RETURNED WITH A
 *    VALUE OF ONE IF DB ELEMENT WAS NOT KNOWN TO THE MD, AND WITH
 *    VALUE OF TWO IF THE CHECKSUMS DID NOT AGREE.
# 
      FOR I = 1 STEP 1 UNTIL CNUMENTRIES DO 
        BEGIN 
        P<MDSCCKSUM> = SEARCHLIST;
        P<CHKSMENTRY> = CONTROLIST + (I-1)*DFCKSMSZ;
        J = 1;
        FOR J = J WHILE ELEMNAM[0] NQ MDELEMNM[0] DO
          BEGIN 
          IF J GQ SNUMENTRIES THEN  #ERROR - ELEM NOT IN SCH #
            BEGIN 
            FLAG = 1; 
            RETURN; 
            END 
          ELSE
            BEGIN 
            J = J + 1;
            P<MDSCCKSUM> = P<MDSCCKSUM> + DFCKSMSZ; 
            END 
          END 
  
   # **  HAVE FOUND NAME - VALIDATE CHECKSUM  ** #
  
        IF MDCKSUM[0] NQ CKSUM[0] THEN   #CHECKSUM MISMATCH#
          BEGIN 
          FLAG = 2; 
          RETURN; 
          END 
        END           #  CHECKSUM MATCH  #
  
      END 
  
      CONTROL EJECT;
  
# 
  ************ BEGIN EXECUTABLE CODE DB$CCK ************
# 
      MDCHKPOINT = 0; 
      CHKPOINT = 0; 
      FLAG = 0; 
# 
 COMPUTE SIZE OF ATTACHED SCHEMA"S CHECKSUM LIST ACCORDING TO THE SIZE
 OF THE LIST IN THE MD SCHEMA.  GROW THE LOCAL CHECKSUM BLOCK TO THAT 
 SIZE.  EXTRACT THE BLOCK"S ADDRESS, AND READ THE LIST IN FROM ATTACHED 
 SCHEMA.
# 
      P<MDSCCKSUM> = B<42,18> MDCHKSMBP + 1;
      SIZE = (MDHDRNUMREL[0] + MDHDRNUMAR[0])*DFCKSMSZ + 1; 
      DB$UAWS (LOC(CHKSMBP),SIZE);    #ADJUST SPACE FOR LIST# 
      DB$CGSC (CHKSMBP+1,SIZE,SCCWCKSUMWA);  # PLUS ONE FOR CMM HEADER #
      MDCHKPOINT = B<42,18> MDCHKSMBP + 1;
      CHKPOINT = B<42,18> CHKSMBP + 1;
# 
 COMPARE NUMBER OF AREAS AND RELATIONS IN ATTACHED SCHEMA AND MD SCHEMA 
 BASED ON HEADER INFO.  ISSUE DIAGNOSTIC MESSAGE IF DIFFERENT.
# 
      P<MDSCCKSUM> = MDCHKPOINT;
      P<CHKSMENTRY> = CHKPOINT; 
      IF (HDRNUMREL[0] NQ MDHDRNUMREL[0]) THEN
        DB$CERR ("7151CCHK", HDRNUMREL[0]); 
      IF (HDRNUMAR[0] NQ MDHDRNUMAR[0]) THEN
        DB$CERR ("7152CCHK", HDRNUMAR[0]);
# 
 COMPARE ATTACHED SCHEMA AGAINST SCHEMA IN MD, VERIFYING THE AREA 
 CHECKSUMS FIRST. 
# 
      SEARCHLIST = MDCHKPOINT + 1;  #POINT B.ARRAY TO 1ST AREA ENT# 
      CONTROLIST = CHKPOINT + 1;
      CNUMENTRIES = SCCWNUMAREAS[0];
      SNUMENTRIES = SCCWNUMAREAS[0];
      ERR1 = "7153CCHK";
      ERR2 = "7154CCHK";
      COMPARE;
      IF FLAG NQ 0 THEN 
        GOTO ERREXIT; 
  
# 
 IF THERE ARE ANY RELATIONS, POINT B.ARRAYS PAST AREA ENTRIES AND VERIFY
 RELATION CHECKSUMS FOR ATTACHED SCHEMA 
# 
      IF SCCWNUMRELTN[0] NQ 0 THEN
        BEGIN 
        SEARCHLIST = MDCHKPOINT + (SCCWNUMAREAS[0]*DFCKSMSZ) + 1; 
        CONTROLIST = CHKPOINT + 1 + (SCCWNUMAREAS[0]*DFCKSMSZ); 
        SNUMENTRIES = SCCWNUMRELTN[0];
        CNUMENTRIES = SCCWNUMRELTN[0];
        ERR1 = "7155CCHK";
        ERR2 = "7156CCHK";
        COMPARE;
        IF FLAG NQ 0 THEN 
          GOTO ERREXIT; 
  
        END 
# 
 REPEAT SCHEMA PROCESSING FOR SUBSCHEMA.  COMPUTE CHECKSUM LIST SIZE. 
 READ IN THE LIST FROM THE SUBSCHEMA.  POINT TO FIRST AREA ENTRY AND
 VERIFY CHECKSUMS FOR AREAS IN SUBSCHEMA. 
# 
      DB$USHR (LOC(CHKSMBP));     # SHRINK BLOCK BEFORE ADJUST #
      SIZE = (SBCWNUMAREAS[0] + SBCWNUMRELS[0])*DFCKSMSZ + 1; 
      DB$UAWS (LOC(CHKSMBP),SIZE);
      DB$CGSB(CHKSMBP+1,SIZE,SBCWCKSUMWA[0]+SBCWSBADDR[0]); 
      MDCHKPOINT = B<42,18> MDCHKSMBP + 1;
      CHKPOINT = B<42,18> CHKSMBP + 1;
      CONTROLIST = CHKPOINT + 1;
      SEARCHLIST = MDCHKPOINT + 1;
      SNUMENTRIES = SCCWNUMAREAS[0];
      CNUMENTRIES = SBCWNUMAREAS[0];
      ERR1 = "7157CCHK";
      ERR2 = "7158CCHK";
      COMPARE;
      IF FLAG NQ 0 THEN 
        GOTO ERREXIT; 
  
#****  AREAS ALL RIGHT - LOOK AT RELATIONS  ****# 
  
      IF SBCWNUMRELS[0] NQ 0 THEN 
        BEGIN 
        SEARCHLIST = SCCWNUMAREAS[0] * DFCKSMSZ + 1 + MDCHKPOINT; 
        CONTROLIST = SBCWNUMAREAS[0] * DFCKSMSZ + 1 + CHKPOINT; 
        SNUMENTRIES = SCCWNUMRELTN; 
        CNUMENTRIES = SBCWNUMRELS;
        ERR1 = "7159CCHK";
        ERR2 = "7160CCHK";
        COMPARE;
        IF FLAG NQ 0 THEN 
          GOTO ERREXIT; 
  
        END 
      RETURN; 
  
ERREXIT:  
      CURSCRAT = ELEMNAM[0];
      IF FLAG EQ 1 THEN 
        DB$CERR (ERR1,DFNAMECH);
      IF FLAG EQ 2 THEN 
        DB$CERR (ERR2,DFNAMECH);
  
  END 
TERM
