- DICLIX ;SEA/TOAD,SF/TKW-FileMan: Lister, Search Compound Indexes ;6/5/00 10:13 [ 04/02/2003 8:25 AM ]
- ;;22.0;VA FileMan;**1001**;APR 1, 2003
- ;;22.0;VA FileMan;**4,3**;Mar 30, 1999;
- ;Per VHA Directive 10-93-142, this routine should not be modified.
- ;
- WALK(DIFLAGS,DINDEX,DIDENT,DIFILE,DIEN,DIFIEN,DISCREEN,DILIST,DINDEX0,DIXV,DIC) ;
- ;
- ; a walker to traverse a compound index, taking actions
- ; DINDEX is an array describing the index and how to walk it
- ;
- PREP ; prepare to loop through subscript
- ;
- N DISUB S DISUB=DINDEX("AT")
- N DIVAL S DIVAL=DINDEX(DISUB)
- N DIPART,DIMORE S DIPART=$G(DINDEX(DISUB,"PART")),DIMORE=+$G(DINDEX(DISUB,"MORE?"))
- I $G(DINDEX(DISUB,"USE")),DIVAL'="" D
- . S DIVAL=$O(@DINDEX(DISUB,"ROOT")@(DIVAL),-DINDEX(DISUB,"WAY"))
- ;
- LOOP ; loop through subscripts
- ;
- N DIDONE,DISKIP S DIDONE=0 F D Q:DIDONE!$G(DIERR)
- . S DIVAL=$O(@DINDEX(DISUB,"ROOT")@(DIVAL),DINDEX(DISUB,"WAY"))
- .
- DATA . ; if we're in the data subscripts, we need to walk further
- .
- . I DISUB'>DINDEX("#") D Q
- . . I DISUB=1,$O(DIXV(0)) D LOWSUB
- . . S DISKIP=0
- . . I DIVAL'="",'$D(DINDEX(DISUB,"IXROOT")) D CHK Q:DISKIP
- . . S:DIVAL="" DIDONE=1
- . . Q:DIDONE
- . . S DINDEX(DISUB)=DIVAL,DINDEX("AT")=DISUB+1
- . . I $D(DINDEX("ROOTCNG",DISUB+1)) D BLDTMP^DICLIX1(.DINDEX,.DISCREEN,DIFLAGS,.DIDENT)
- . . D WALK(.DIFLAGS,.DINDEX,.DIDENT,.DIFILE,.DIEN,DIFIEN,.DISCREEN,.DILIST,.DINDEX0,"",.DIC)
- . . S DINDEX("AT")=DISUB
- . . I $G(DINDEX("DONE"))!$G(DIERR) S DIDONE=1
- . . Q
- .
- IEN . ; otherwise, we're in the IEN subscripts & need to process
- .
- . I DIVAL="" S DIDONE=1 Q
- . I DINDEX="B" N DISKIPMN,DIMNEM S DISKIPMN=0 D Q:DISKIPMN
- . . I $D(@DINDEX(DISUB,"ROOT")@(DIVAL))#2 Q:'^(DIVAL)
- . . E Q:'$O(@DINDEX(DISUB,"ROOT")@(DIVAL,""))
- . . I DIFLAGS["M" S DISKIPMN=1 Q
- . . S DIMNEM="" Q
- . I $G(DINDEX(DISUB,"TO")) D Q:DIDONE
- . . Q:$D(DINDEX(DISUB,"IXROOT"))
- . . D BACKPAST^DICLIX1(DIFLAGS,.DINDEX,DISUB,DIVAL,.DIDONE) Q
- . D TRY
- . Q
- CLEAN ; clean up after loop, exit
- S DINDEX(DISUB)=""
- I DISUB>1,$G(DINDEX(DISUB,"PART"))]"" S DINDEX(DISUB)=DINDEX(DISUB,"FROM")
- Q
- ;
- CHK ; See whether we have a match or are at the end of the subscripts.
- D MATCH I DIDONE,'$G(DINDEX("DONE")),DIMORE D
- . S DIDONE=0 D FINDMORE^DICLIX0(DISUB,.DIVAL,DIPART,.DINDEX,.DIMORE) I DIVAL="" S DIDONE=1 Q
- . D MATCH Q
- Q
- ;
- MATCH ; No more subscripts or partial matches, or past our TO value?
- Q:DIVAL=""
- I $P(DIVAL,$G(DIPART))'="" S DIDONE=1 Q
- Q:$G(DINDEX(DISUB,"TO"))=""
- I DIFLAGS["p" D BACKPAST^DICLIX1(DIFLAGS,.DINDEX0,DISUB,DIVAL,.DIDONE) Q
- I $G(DINDEX(DISUB+1,"TO"))="" D BACKPAST^DICLIX1(DIFLAGS,.DINDEX,DISUB,DIVAL,.DIDONE)
- Q
- ;
- LOWSUB ; Find next subscript value from multiple pointed-to files
- N I,DILOWNO,DILOWVAL S DILOWNO=+DIFILE("STACK"),DILOWVAL=DIVAL
- I DILOWVAL="" D I 'DILOWNO K DIXV Q
- . K DIXV(DILOWNO),DIFILE("STACKEND",DILOWNO)
- . S DILOWNO=$O(DIXV(0)),DILOWVAL=$G(DIXV(+DILOWNO,1,"NXTVAL"))
- . Q
- N J S J=DILOWNO
- I DILOWVAL'="" F I=0:0 S I=$O(DIFILE("STACKEND",I)) Q:'I I I'=J D
- . I DINDEX(1,"WAY")=1,DILOWVAL']]DIXV(I,1,"NXTVAL") Q
- . I DINDEX(1,"WAY")=-1,DIXV(I,1,"NXTVAL")']]DILOWVAL Q
- . S DILOWNO=I,DILOWVAL=$G(DIXV(DILOWNO,1,"NXTVAL"))
- . Q
- I DILOWNO'=DIFILE("STACK") D
- . I DIVAL'="" S DIXV(+DIFILE("STACK"),1,"NXTVAL")=DIVAL
- . S DIFILE("STACK")=DILOWNO_U_DIFILE("STACKEND",DILOWNO)
- . S DIVAL=DILOWVAL
- . S DIFILE=+$P(DIFILE("STACK"),U,3)
- . M DINDEX=DIXV(DILOWNO) Q
- Q
- ;
- TRY ; Apply screens to entry. If passed, add entry to output.
- S (DIEN,DINDEX(DISUB))=DIVAL
- I DIFLAGS["p" D
- . S DINDEX0(1,"EXT")=DINDEX(1)
- . D BACKTRAK^DICL3(.DIFLAGS,.DIFILE,DIFILE("STACK"),.DIEN,DIFIEN,.DINDEX0,.DINDEX,.DIDENT,.DISCREEN,.DILIST)
- . S:$G(DINDEX0("DONE")) (DIDONE,DINDEX("DONE"))=1 Q
- I DIFLAGS'["p" D
- . N DI0NODE S DI0NODE=$G(@DIFILE(DIFILE)@(DIEN,0))
- . Q:$$SCREEN^DICL2(.DIFILE,.DIEN,DIFLAGS,DIFIEN,.DISCREEN,.DINDEX,DI0NODE)
- . D ACCEPT^DICL2(.DIFILE,.DIEN,.DIFLAGS,DIFIEN,.DINDEX,.DIDENT,.DILIST,DI0NODE)
- . Q
- Q:$G(DIERR)!($G(DINDEX("DONE")))
- I DIDENT(-1)=DIDENT(-1,"MAX") D
- . I 'DIDENT(-1,"JUST LOOKING") S DIDONE=1,DINDEX("DONE")=1 Q
- . ; If called from online DIC help ^DICQ, display list.
- . Q:DIFLAGS'["h"
- . K DTOUT,DUOUT S DICQ(0,"MAP")=DIDENT(-3)
- . D DSP^DICQ1(.DINDEX,.DICQ,.DIC,.DIFILE)
- . I $G(DTOUT)!($G(DUOUT)) S (DINDEX("DONE"),DIDONE)=1 Q
- . S DILIST("ORDER")=$S(DINDEX("WAY")=1:0,1:DIDENT(-1,"MAX")+1)
- . S DIDENT(-1)=0,DIDENT(-1,"JUST LOOKING")=0 Q
- Q
- ;
- ;
- DICLIX ;SEA/TOAD,SF/TKW-FileMan: Lister, Search Compound Indexes ;6/5/00 10:13 [ 04/02/2003 8:25 AM ]
- +1 ;;22.0;VA FileMan;**1001**;APR 1, 2003
- +2 ;;22.0;VA FileMan;**4,3**;Mar 30, 1999;
- +3 ;Per VHA Directive 10-93-142, this routine should not be modified.
- +4 ;
- WALK(DIFLAGS,DINDEX,DIDENT,DIFILE,DIEN,DIFIEN,DISCREEN,DILIST,DINDEX0,DIXV,DIC) ;
- +1 ;
- +2 ; a walker to traverse a compound index, taking actions
- +3 ; DINDEX is an array describing the index and how to walk it
- +4 ;
- PREP ; prepare to loop through subscript
- +1 ;
- +2 NEW DISUB
- SET DISUB=DINDEX("AT")
- +3 NEW DIVAL
- SET DIVAL=DINDEX(DISUB)
- +4 NEW DIPART,DIMORE
- SET DIPART=$GET(DINDEX(DISUB,"PART"))
- SET DIMORE=+$GET(DINDEX(DISUB,"MORE?"))
- +5 IF $GET(DINDEX(DISUB,"USE"))
- IF DIVAL'=""
- Begin DoDot:1
- +6 SET DIVAL=$ORDER(@DINDEX(DISUB,"ROOT")@(DIVAL),-DINDEX(DISUB,"WAY"))
- End DoDot:1
- +7 ;
- LOOP ; loop through subscripts
- +1 ;
- +2 NEW DIDONE,DISKIP
- SET DIDONE=0
- FOR
- Begin DoDot:1
- +3 SET DIVAL=$ORDER(@DINDEX(DISUB,"ROOT")@(DIVAL),DINDEX(DISUB,"WAY"))
- +4 DATA ; if we're in the data subscripts, we need to walk further
- +1 +2 IF DISUB'>DINDEX("#")
- Begin DoDot:2
- +3 IF DISUB=1
- IF $ORDER(DIXV(0))
- DO LOWSUB
- +4 SET DISKIP=0
- +5 IF DIVAL'=""
- IF '$DATA(DINDEX(DISUB,"IXROOT"))
- DO CHK
- IF DISKIP
- QUIT
- +6 IF DIVAL=""
- SET DIDONE=1
- +7 IF DIDONE
- QUIT
- +8 SET DINDEX(DISUB)=DIVAL
- SET DINDEX("AT")=DISUB+1
- +9 IF $DATA(DINDEX("ROOTCNG",DISUB+1))
- DO BLDTMP^DICLIX1(.DINDEX,.DISCREEN,DIFLAGS,.DIDENT)
- +10 DO WALK(.DIFLAGS,.DINDEX,.DIDENT,.DIFILE,.DIEN,DIFIEN,.DISCREEN,.DILIST,.DINDEX0,"",.DIC)
- +11 SET DINDEX("AT")=DISUB
- +12 IF $GET(DINDEX("DONE"))!$GET(DIERR)
- SET DIDONE=1
- +13 QUIT
- End DoDot:2
- QUIT
- +14 IEN ; otherwise, we're in the IEN subscripts & need to process
- +1 +2 IF DIVAL=""
- SET DIDONE=1
- QUIT
- +3 IF DINDEX="B"
- NEW DISKIPMN,DIMNEM
- SET DISKIPMN=0
- Begin DoDot:2
- +4 IF $DATA(@DINDEX(DISUB,"ROOT")@(DIVAL))#2
- IF '^(DIVAL)
- QUIT
- +5 IF '$TEST
- IF '$ORDER(@DINDEX(DISUB,"ROOT")@(DIVAL,""))
- QUIT
- +6 IF DIFLAGS["M"
- SET DISKIPMN=1
- QUIT
- +7 SET DIMNEM=""
- QUIT
- End DoDot:2
- IF DISKIPMN
- QUIT
- +8 IF $GET(DINDEX(DISUB,"TO"))
- Begin DoDot:2
- +9 IF $DATA(DINDEX(DISUB,"IXROOT"))
- QUIT
- +10 DO BACKPAST^DICLIX1(DIFLAGS,.DINDEX,DISUB,DIVAL,.DIDONE)
- QUIT
- End DoDot:2
- IF DIDONE
- QUIT
- +11 DO TRY
- +12 QUIT
- End DoDot:1
- IF DIDONE!$GET(DIERR)
- QUIT
- CLEAN ; clean up after loop, exit
- +1 SET DINDEX(DISUB)=""
- +2 IF DISUB>1
- IF $GET(DINDEX(DISUB,"PART"))]""
- SET DINDEX(DISUB)=DINDEX(DISUB,"FROM")
- +3 QUIT
- +4 ;
- CHK ; See whether we have a match or are at the end of the subscripts.
- +1 DO MATCH
- IF DIDONE
- IF '$GET(DINDEX("DONE"))
- IF DIMORE
- Begin DoDot:1
- +2 SET DIDONE=0
- DO FINDMORE^DICLIX0(DISUB,.DIVAL,DIPART,.DINDEX,.DIMORE)
- IF DIVAL=""
- SET DIDONE=1
- QUIT
- +3 DO MATCH
- QUIT
- End DoDot:1
- +4 QUIT
- +5 ;
- MATCH ; No more subscripts or partial matches, or past our TO value?
- +1 IF DIVAL=""
- QUIT
- +2 IF $PIECE(DIVAL,$GET(DIPART))'=""
- SET DIDONE=1
- QUIT
- +3 IF $GET(DINDEX(DISUB,"TO"))=""
- QUIT
- +4 IF DIFLAGS["p"
- DO BACKPAST^DICLIX1(DIFLAGS,.DINDEX0,DISUB,DIVAL,.DIDONE)
- QUIT
- +5 IF $GET(DINDEX(DISUB+1,"TO"))=""
- DO BACKPAST^DICLIX1(DIFLAGS,.DINDEX,DISUB,DIVAL,.DIDONE)
- +6 QUIT
- +7 ;
- LOWSUB ; Find next subscript value from multiple pointed-to files
- +1 NEW I,DILOWNO,DILOWVAL
- SET DILOWNO=+DIFILE("STACK")
- SET DILOWVAL=DIVAL
- +2 IF DILOWVAL=""
- Begin DoDot:1
- +3 KILL DIXV(DILOWNO),DIFILE("STACKEND",DILOWNO)
- +4 SET DILOWNO=$ORDER(DIXV(0))
- SET DILOWVAL=$GET(DIXV(+DILOWNO,1,"NXTVAL"))
- +5 QUIT
- End DoDot:1
- IF 'DILOWNO
- KILL DIXV
- QUIT
- +6 NEW J
- SET J=DILOWNO
- +7 IF DILOWVAL'=""
- FOR I=0:0
- SET I=$ORDER(DIFILE("STACKEND",I))
- IF 'I
- QUIT
- IF I'=J
- Begin DoDot:1
- +8 IF DINDEX(1,"WAY")=1
- IF DILOWVAL']]DIXV(I,1,"NXTVAL")
- QUIT
- +9 IF DINDEX(1,"WAY")=-1
- IF DIXV(I,1,"NXTVAL")']]DILOWVAL
- QUIT
- +10 SET DILOWNO=I
- SET DILOWVAL=$GET(DIXV(DILOWNO,1,"NXTVAL"))
- +11 QUIT
- End DoDot:1
- +12 IF DILOWNO'=DIFILE("STACK")
- Begin DoDot:1
- +13 IF DIVAL'=""
- SET DIXV(+DIFILE("STACK"),1,"NXTVAL")=DIVAL
- +14 SET DIFILE("STACK")=DILOWNO_U_DIFILE("STACKEND",DILOWNO)
- +15 SET DIVAL=DILOWVAL
- +16 SET DIFILE=+$PIECE(DIFILE("STACK"),U,3)
- +17 MERGE DINDEX=DIXV(DILOWNO)
- QUIT
- End DoDot:1
- +18 QUIT
- +19 ;
- TRY ; Apply screens to entry. If passed, add entry to output.
- +1 SET (DIEN,DINDEX(DISUB))=DIVAL
- +2 IF DIFLAGS["p"
- Begin DoDot:1
- +3 SET DINDEX0(1,"EXT")=DINDEX(1)
- +4 DO BACKTRAK^DICL3(.DIFLAGS,.DIFILE,DIFILE("STACK"),.DIEN,DIFIEN,.DINDEX0,.DINDEX,.DIDENT,.DISCREEN,.DILIST)
- +5 IF $GET(DINDEX0("DONE"))
- SET (DIDONE,DINDEX("DONE"))=1
- QUIT
- End DoDot:1
- +6 IF DIFLAGS'["p"
- Begin DoDot:1
- +7 NEW DI0NODE
- SET DI0NODE=$GET(@DIFILE(DIFILE)@(DIEN,0))
- +8 IF $$SCREEN^DICL2(.DIFILE,.DIEN,DIFLAGS,DIFIEN,.DISCREEN,.DINDEX,DI0NODE)
- QUIT
- +9 DO ACCEPT^DICL2(.DIFILE,.DIEN,.DIFLAGS,DIFIEN,.DINDEX,.DIDENT,.DILIST,DI0NODE)
- +10 QUIT
- End DoDot:1
- +11 IF $GET(DIERR)!($GET(DINDEX("DONE")))
- QUIT
- +12 IF DIDENT(-1)=DIDENT(-1,"MAX")
- Begin DoDot:1
- +13 IF 'DIDENT(-1,"JUST LOOKING")
- SET DIDONE=1
- SET DINDEX("DONE")=1
- QUIT
- +14 ; If called from online DIC help ^DICQ, display list.
- +15 IF DIFLAGS'["h"
- QUIT
- +16 KILL DTOUT,DUOUT
- SET DICQ(0,"MAP")=DIDENT(-3)
- +17 DO DSP^DICQ1(.DINDEX,.DICQ,.DIC,.DIFILE)
- +18 IF $GET(DTOUT)!($GET(DUOUT))
- SET (DINDEX("DONE"),DIDONE)=1
- QUIT
- +19 SET DILIST("ORDER")=$SELECT(DINDEX("WAY")=1:0,1:DIDENT(-1,"MAX")+1)
- +20 SET DIDENT(-1)=0
- SET DIDENT(-1,"JUST LOOKING")=0
- QUIT
- End DoDot:1
- +21 QUIT
- +22 ;
- +23 ;