*DECK DBKEYFNAT 
USETEXT CCTTEXT 
USETEXT DBTEXT
PROC KEY$F; 
*CALL DEBUGVARS 
*CALL FNAT1 
*CALL FNATVALS
*CALL AUXT1 
*CALL AUXTVALS
*CALL GETSET
*CALL TABLNAMES 
*CALL DBCORTAB
START("KEY$F")
XREF BEGIN
PROC NXTRKEY; 
PROC IERR$; 
FUNC WA$TO$DNAT;
ITEM DNTPTR I;
END 
# 
THIS PROCEDURE PROCESSES THE ACCESS KEYS FOR THE CURRENT AREA.
IT IS CALLED WHEN ALL ITEMS FOR ALL RECORDS IN THE AREA HAVE
BEEN PROCESSED. 
IT SETS UP THE FNAT POINTER AND ORDINAL FOR THE PRIMARY KEY,
AND FOR ORGANISATIONS - 
      INDEXED SEQUENTIAL
      DIRECT ACCESS 
      ACTUAL KEY
CREATES AUX TABLE ENTRIES (TYPE ALTKEYNAME) FOR EACH
ALTERNATE KEY. THESE ENTRIES CONTAIN DNAT POINTERS TO EACH
KEY, ALONG WITH THE KEY ORDINAL.
# 
ITEM LPKDNAT; #TEMP FOR DNAT OF PRIMARY KEY#
ITEM LAKDNAT; #TEMP FOR ALTERNATE KEY#
ITEM LFN$ORG; #TEMP FOR FN$ORG# 
CONTROL IFNQ CB5$CDCS,"NO"; 
IF DKPTR EQ 0 
  THENB("NO KEYS PRESENT")
  QUIT
ENDIF 
LFN$ORG=$G(FN$ORG,FNAT$,FNAT$PTR);
  IF DRKPRIMARY EQ 0
  THENB("CHECK FO") 
    IF DFITFO EQ 0
    THENB("SEQ SORT KEY")  # DDL 21 ALLOWS KEYS ON SQ FILES # 
      QUIT; 
    ELSEB("KEY IS NOT PRIMARY") 
      IERR$(L23,ABORT); 
    ENDIF 
  ENDIF 
IF DRKIMBED EQ 0
  THENB("NON-IMBEDDED PRIME KEY") 
  IF DNTPTR EQ 0
    THENB("NO DNT ENTRY") 
    $S(FN$ABORT,FNAT$,FNAT$PTR,1);
    IERR$(L34,ABORT); 
  ENDIF 
  IF LFN$ORG EQ DIRECT
    THENB("DIRECT FILE")
    $S(FN$ABORT,FNAT$,FNAT$PTR,1);
    IERR$(L33,ABORT); 
  ENDIF 
                             #AS YET, THE DDL 3 PROJECT HAS NOT DETER-
                              MINED IF NON-IMBEDDED KEYS MAY BE QUALI-
                              FIED.  (IF QUALIFICATION IS TO BE IMPLE-
                              MENTED, NOTE -DNREFSEARCH- IN -TBLPROCS-
                              AND -DNTFIND- IN -NXTREL-.)#
  LPKDNAT = DNTPTR; 
  ELSEB("IMBEDDED PRIME KEY") 
  LPKDNAT=WA$TO$DNAT(DRKWA);
ENDIF 
   IV$($SET$,"LPKDNAT",LPKDNAT) 
  $S(FN$RECPTR,FNAT$,FNAT$PTR,LPKDNAT); #STORE KEY DNAT#
  $S(FN$RKEYORD,FNAT$,FNAT$PTR,CT$IORD[CT$PTR]);
  IV$($SET$,"IORD",CT$IORD[CT$PTR]) 
  LOOP("WHILE MORE ALTKEYS")
EXITIF(DRKNXTPTR,EQ,0,"NO MORE ALTKEYS")
    NXTRKEY; #GET NXT RECORD KEY# 
  IF DRKIMBED EQ 0                                                      000521
  THENB("KEY IS NON-IMBEDED")                                           000531
  $S(FN$ABORT,FNAT$,FNAT$PTR,1);                                        000551
  IERR$(L4,ABORT);
  ENDIF                                                                 000571
    IF DRKPRIMARY NQ 0
      THENB("MORE THAN ONE PRIMARY KEY")
      IERR$(L26,ABORT); 
    ENDIF 
    IF DRKOMIT EQ 1 
    THENB("THIS ALT. KEY NOT IN SS")
      TEST; 
    ENDIF 
    SETI("AUXT$PTR",AUXT$PTR,$G(FN$ALTKPTR,FNAT$,FNAT$PTR)) 
                   #GET CURRENT AUXTPTR#
    SETI("CCTAUXTLEN",CCTAUXTLEN,CCTAUXTLEN+1)
    IF AUXT$PTR EQ 0
      THENB("NO CURRENT AUXT CHAIN")
      $S(FN$ALTKPTR,FNAT$,FNAT$PTR,CCTAUXTLEN); #FNAT -> NEW# 
      ELSEB("ALTKEY CHAIN ALREADY THERE") 
      $S(AX$TNEXTPTR,AUX$,CCTAUXTLEN,AUXT$PTR); #NEW -> 1ST IN CHN# 
      $S(FN$ALTKPTR,FNAT$,FNAT$PTR,CCTAUXTLEN); #FNAT -> NEW# 
    ENDIF 
    #BUILD NEW AUX ENTRY# 
    $S(AX$TTYPE,AUX$,CCTAUXTLEN,ALTKEYNAME);
    LAKDNAT=WA$TO$DNAT(DRKWA); #GET KEY DNAT PTR# 
    IV$($SET$,"LAKDNAT",LAKDNAT)
    $S(AX$ALTKEY,AUX$,CCTAUXTLEN,LAKDNAT);
    $S(AX$ALTKEYORD,AUX$,CCTAUXTLEN,CT$IORD[CT$PTR]); 
    OV$($SET$,"IORD",CT$IORD[CT$PTR]) 
    IV$($SET$,"CCTAUXTLEN",CCTAUXTLEN)
  ENDLOOP("ALL KEYS PROCESSED") 
CONTROL FI; 
FINIS("KEY$F")
TERM
