BMXSQL7	; IHS/OIT/HMW - BMX REMOTE PROCEDURE CALLS ;
	;;2.1;BMX;;Jul 26, 2009
	;
	;
CHKCR(BMXFNUM,BMXFLDNU,BMXRET)	;Returns cross reference to iterate on for related file
	N BMXREF,BMXHIT,BMXRNOD,BMXTMP,BMXTMPV,BMXTMPI,BMXTMPP,BMXPFFN,BMXPFF,Q
	N BMXHIT,BMXREF,BMXGL,BMXNOD,BMXRNAM,BMXTMPL,BMXTMPN,BMXTST
	;
	S BMXNOD=^DD(BMXFNUM,BMXFLDNU,0)
	S BMXGL=^DIC(BMXFNUM,0,"GL") ;Subfile global
	S BMXREF=0,BMXHIT=0,Q=$C(34),BMXRET=""
	F  S BMXREF=$O(^DD(BMXFNUM,BMXFLDNU,1,BMXREF)) Q:'+BMXREF  D  Q:BMXHIT
	. Q:'$D(^DD(BMXFNUM,BMXFLDNU,1,BMXREF,0))
	. S BMXRNOD=^DD(BMXFNUM,BMXFLDNU,1,BMXREF,0)
	. Q:$P(BMXRNOD,U,3)]""
	. S BMXRNAM=$P(BMXRNOD,U,2)
	. S BMXTMP=BMXGL_Q_BMXRNAM_Q_")"
	. S BMXTST=$P(BMXTMP,")")_",IEN0,"
	. Q:'$D(@BMXTMP)
	. S BMXTMPV=0,BMXTMPV=$O(@BMXTMP@(BMXTMPV))
	. Q:BMXTMPV=""
	. S BMXTMP=BMXGL_Q_BMXRNAM_Q_","_Q_BMXTMPV_Q_")"
	. S BMXTMPI=0,BMXTMPI=$O(@BMXTMP@(BMXTMPI))
	. S BMXTMP=$S(BMXGL[",":$P(BMXGL,",")_")",1:$P(BMXGL,"("))
	. Q:'$D(@BMXTMP@(BMXTMPI))
	. S BMXTMPL=$P(BMXNOD,U,4)
	. S BMXTMPP=$P(BMXTMPL,";",2)
	. S BMXTMPL=$P(BMXTMPL,";")
	. Q:BMXTMPL=""
	. S BMXTMP=BMXGL_BMXTMPI_")"
	. Q:'$D(@BMXTMP@(BMXTMPL))
	. S BMXTMPN=@BMXTMP@(BMXTMPL)
	. S BMXTMPP=$P(BMXTMPN,"^",BMXTMPP)
	. I BMXTMPP=BMXTMPV S BMXRET=BMXTST,BMXHIT=1
	Q BMXHIT
	;
	;
WHERE	;EP - WHERE-clause processing
	;
	;Set up the defualt iterator in BMXX(1) to scan the entire file.
	;For now, just use first file in the FROM group
	;Later, pick the smallest file if more than one file
	;
	;Set up BMXFF array for each expression element
	;  BMXFF(n)=FILENAME^FIELDNAME^OPERATOR^VALUE^FILENUMBER^FIELDNUMBER
	;           ^FILE GLOBAL^FIELD DATA LOCATION
	;  BMXFF(n,0)=Field descriptor ^DD(FILE,FIELD,0)
	;
	N BMXGL,BMXOP,BMXTYP,BMXV,BMXV1,BMXV2,BMXFILE,BMXTMP
	N BMXINTNL,BMXTMPLT
	N BMXIEN
	S BMXGL=^DIC(BMXFO(1),0,"GL")
	S BMXX=1
	S BMXX(1)="S D0=0 F  S D0=$O("_BMXGL_"D0)) Q:'+D0  Q:BMXM>BMXXMAX  "
	S BMXTMP=BMXGL
	I BMXTMP["," S BMXTMP=$TR(BMXTMP,",",")")
	E  S BMXTMP=$P(BMXTMP,"(",1)
	I $D(@BMXTMP@("B")) D
	. S BMXX(1)="S BMXTMP=0 F  S BMXTMP=$O("_BMXGL_$C(34)_"B"_$C(34)_",BMXTMP)) Q:BMXTMP=""""  S D0=0 F  S D0=$O("_BMXGL_$C(34)_"B"_$C(34)_",BMXTMP,D0)) Q:'+D0  Q:BMXM>BMXXMAX  "
	;
	;--->BMXFF array:
	;
	S T=$G(BMXTK("WHERE"))
	S BMXFF=0,C=0
	Q:'+T
	F  S T=$O(BMXTK(T)) Q:'+T  Q:T=$G(BMXTK("ORDER BY"))  Q:T=$G(BMXTK("GROUP BY"))  D  Q:$D(BMXERR)
	. ;Get the file of the field
	. I "AND^OR^(^)"[BMXTK(T) D  Q
	. . S C=C+1
	. . S BMXFF(C)=BMXTK(T)
	. . S BMXFF=C
	. S BMXTK(T)=$TR(BMXTK(T),"_"," ")
	. S BMXTK(T)=$TR(BMXTK(T),"'","")
	. S BMXINTNL=0
	. S BMXTMPLT=0
	. S BMXIEN=0
	. I BMXTK(T)["INTERNAL[" S BMXINTNL=1,BMXTK(T)=$P(BMXTK(T),"[",2),BMXTK(T)=$P(BMXTK(T),"]",1)
	. I BMXTK(T)["TEMPLATE[" S BMXTMPLT=1,BMXTK(T)=$P(BMXTK(T),"[",2),BMXTK(T)=$P(BMXTK(T),"]",1),BMXIEN=1
	. I BMXTK(T)["BMXIEN" S BMXIEN=1
	. S BMXFILE=$$FLDFILE^BMXSQL2(BMXTK(T))
	. Q:$D(BMXERR)
	. S C=C+1
	. S BMXFF=C ;This is a count of the where fields
	. I BMXFILE]"" D
	. . S $P(BMXFF(C),U,1)=$P(BMXFILE,U,1) ;FILENAME
	. . S $P(BMXFF(C),U,2)=$P(BMXFILE,U,2) ;FIELDNAME
	. . S $P(BMXFF(C),U,5)=$P(BMXFILE,U,3) ;FILENUMBER
	. . S $P(BMXFF(C),U,6)=$P(BMXFILE,U,4) ;FIELDNUMBER
	. . I $P(BMXFILE,U,3),$D(^DIC($P(BMXFILE,U,3),0,"GL")) S $P(BMXFF(C),U,7)=^DIC($P(BMXFILE,U,3),0,"GL")
	. . I BMXIEN S BMXFF(C,0)="IEN",BMXFF(C,"IEN")=1,BMXFF(C,"TYPE")="IEN"
	. . E  S BMXFF(C,0)=$S(+$P(BMXFILE,U,3):^DD($P(BMXFILE,U,3),$P(BMXFILE,U,4),0),1:"")
	. . I BMXINTNL S BMXFF(C,"INTERNAL")=1
	. ;
	. ;If BMXFF(C) is a pointer, traverse pointer chain to retrieve type
	. I $P(BMXFF(C,0),U,2)["P" D
	. . ;B  ;WHERE Pointer Type
	. . N BMXFILN,BMXFLDN,BMXDD
	. . S BMXDD=BMXFF(C,0)
	. . F  Q:$P(BMXDD,U,2)'["P"  D:$P(BMXDD,U,2)["P"
	. . . S BMXFILN=$P(BMXDD,U,2)
	. . . S BMXFILN=+$P(BMXFILN,"P",2)
	. . . S BMXDD=^DD(BMXFILN,".01",0)
	. . S BMXFF(C,"TYPE")=$S($P(BMXDD,U,2)["D":"DATE",$P(BMXDD,U,2)["S":"SET",1:"OTHER")
	. . I BMXFF(C,"TYPE")="SET" S $P(BMXFF(C,"TYPE"),U,2)=$P(BMXDD,U,3)
	. ;B  ;WHERE Set Type
	. I ($P(BMXFF(C,0),U,2)["S")!($P($G(BMXFF(C,"TYPE")),U)="SET") D  ;Set
	. . N BMXSET,BMXSETP
	. . I $P(BMXFF(C,0),U,2)["S" D
	. . . S BMXFF(C,"TYPE")="SET"
	. . . S $P(BMXFF(C,"TYPE"),U,2)=$P(BMXFF(C,0),U,3)
	. . S BMXSET=$P(BMXFF(C,"TYPE"),U,2)
	. . F J=1:1:$L(BMXSET,";") D
	. . . S BMXSETP=$P(BMXSET,";",J)
	. . . Q:BMXSETP=""
	. . . S BMXFF(C,"SET",$P(BMXSETP,":",2))=$P(BMXSETP,":")
	. ;
	. ;Set up comparisons based on operators
	. S T=T+1
	. S BMXOP=BMXTK(T)
	. I BMXTMPLT S BMXOP="="
	. I "^<^>^=^[^<>^>=^<=^LIKE"[BMXOP D  Q
	. . S $P(BMXFF(C),U,3)=BMXTK(T)
	. . ;Get the comparison value
	. . S T=T+1
	. . S BMXTMP=BMXTK(T)
	. . S BMXTMP=$TR(BMXTMP,"'","")
	. . I BMXOP="LIKE" S BMXTMP=$P(BMXTMP,"%"),$P(BMXFF(C),U,4)=BMXTMP Q
	. . I BMXTMPLT D TMPLATE Q
	. . I BMXTMP="*" S T=T+1,BMXTMP=BMXTK(T) D OTM Q
	. . I BMXTMP[".",BMXTK(T)'["'" D  ;This is a join  ;TODO: Extended pointers
	. . . ;Setting BMXFJ("JOIN"
	. . . S BMXTMP=BMXTK(T)
	. . . I $D(BMXF($P(BMXTMP,"."))),BMXF($P(BMXTMP,"."))=BMXFO(1) D  Q
	. . . . S BMXTMP=BMXTK(T-2)
	. . . . D OTM
	. . . N BMXJN
	. . . S BMXFF(C,"JOIN")="Pointer chain"
	. . . S BMXJN=+$P($P(BMXFF(C,0),U,2),"P",2)
	. . . S BMXFJ("JOIN",+$P($P(BMXFF(C,0),U,2),"P",2))=C
	. . . S:+$P($P(BMXFF(C,0),U,2),"P",2)=2 BMXFJ("JOIN",9000001)=C ;IHS Only -- auto join PATIENT to VA PATIENT
	. . I ($P(BMXFF(C,0),U,2)["D")!($G(BMXFF(C,"TYPE"))="DATE") D  ;Date
	. . . Q:$D(BMXFF(C,"INTERNAL"))
	. . . I BMXTMP]"" S X=BMXTMP,%DT="T" D ^%DT S BMXTMP=Y
	. . I $P($G(BMXFF(C,"TYPE")),U)="SET" D
	. . . Q:$D(BMXFF(C,"INTERNAL"))
	. . . Q:BMXTMP=""
	. . . I $G(BMXFF(C,"SET",BMXTMP))="" S BMXTMP="ZZZZZZ" Q
	. . . S BMXTMP=$G(BMXFF(C,"SET",BMXTMP))
	. . S $P(BMXFF(C),U,4)=BMXTMP
	. . Q
	. I BMXOP="BETWEEN" D
	. . S $P(BMXFF(C),U,3)="BETWEEN"
	. . ;Get the comparison value
	. . S T=T+1
	. . S BMXV1=BMXTK(T)
	. . S:BMXV1["'" BMXV1=$P(BMXV1,"'",2)
	. . S T=T+1
	. . I BMXTK(T)'="AND" S BMXERR="'BETWEEN' VALUES NOT SPECIFIED" D ERROR Q
	. . S T=T+1
	. . S BMXV2=BMXTK(T)
	. . S:BMXV2["'" BMXV2=$P(BMXV2,"'",2)
	. . I ($P(BMXFF(C,0),U,2)["D")!($G(BMXFF(C,"TYPE"))="DATE") D  ;Date
	. . . Q:$D(BMXFF(C,"INTERNAL"))
	. . . S X=BMXV1,%DT="T" D ^%DT S BMXV1=Y
	. . . S X=BMXV2,%DT="T" D ^%DT S BMXV2=Y
	. . I BMXV1>BMXV2 S BMXTMP=BMXV1,BMXV1=BMXV2,BMXV2=BMXTMP
	. . S $P(BMXFF(C),U,4)=BMXV1_"~"_BMXV2
	. . Q
	. I $P(BMXFF(C),U,3)="" S BMXERR="INVALID OPERATOR" D ERROR Q
	. I $D(BMXTK(T+1)),BMXTK(T+1)["[INDEX:" D
	. . S T=T+1
	. . N BMXIND
	. . S BMXIND=$P(BMXTK(T),"INDEX:",2)
	. . S:BMXIND["]" BMXIND=$P(BMXIND,"]")
	. . S:BMXIND["'" BMXIND=$P(BMXIND,"'",2)
	. . S BMXFF("INDEX")=BMXIND
	. Q
	;
	Q:$D(BMXERR)
	D JOIN^BMXSQL4
	Q
	;
TMPLATE	;
	N BMXTNUM,BMXTNOD
	I BMXTMP["[" S BMXTMP=$P(BMXTMP,"[",2),BMXTMP=$P(BMXTMP,"]")
	S BMXTMP=$TR(BMXTMP,"_"," ")
	;Test template validity
	I '$D(^DIBT("B",BMXTMP)) S BMXERR="TEMPLATE NOT FOUND" D ERROR Q
	S BMXTNUM=$O(^DIBT("B",BMXTMP,0))
	I '$D(^DIBT(BMXTNUM,0)) S BMXERR="TEMPLATE NOT FOUND" D ERROR Q
	S BMXTNOD=^DIBT(BMXTNUM,0)
	I $P(BMXTNOD,U,4)'=$P(BMXFF(C),U,5) S BMXERR="TEMPLATE DOES NOT MATCH FILE" D ERROR Q
	I '$D(^DIBT(BMXTNUM,1)) S BMXERR="TEMPLATE HAS NO ENTRIES" D ERROR Q
	S BMXFF(C,0)="IEN",BMXFF(C,"IEN")="TEMPLATE",BMXFF(C,"TYPE")="IEN"
	S $P(BMXFF(C),U,4)=BMXTMP
	;
	Q
	;
OTM	;One-To-Many
	N BMXUPFN,BMXSUBFN,BMXA,BMXB,BMXSUBFLD,BMXFNAM
	I BMXTMP["INTERNAL[" S BMXTMP=$P(BMXTMP,"INTERNAL[",2),BMXTMP=$P(BMXTMP,"]")
	S BMXUPFN=BMXFO(1)
	S BMXA=$TR($P(BMXTMP,"."),"_"," ")
	S BMXB=$TR($P(BMXTMP,".",2),"_"," ")
	S BMXFNAM=BMXB ;Required by SETMFL.  Won't work if filename BMXB [ "."
	;Get the subfile
	I '$D(BMXF(BMXA)) S BMXERR="Related File Not Found" Q
	S BMXSUBFN=BMXF(BMXA)
	I '$D(^DD(BMXSUBFN,0)) S BMXERR="Related file not found" Q
	;Get the field that points to the main file
	I '$D(^DD(BMXSUBFN,"B",BMXB)) S BMXERR="Related field not found" Q
	S BMXSUBFLD=$O(^DD(BMXSUBFN,"B",BMXB,0))
	I '+BMXSUBFLD S BMXERR="Related field not found" Q
	;
	;Find a normal index on that field
	;Set up for call to CHKCR^BMXSQL7
	N BMXEXEC
	I '$$CHKCR^BMXSQL7(BMXSUBFN,BMXSUBFLD,.BMXEXEC) S BMXERR="Related File not indexed" Q
	;
	;
	S BMXFF(C,"JOIN")="One-to-many Join"
	;
	;Call SETMFL^BMXSQL5 to set up the iteration code
	D SETMFL^BMXSQL5(BMXUPFN,BMXSUBFN,BMXEXEC,1,1)
	;
	;
	;Upfile is the mainfile, Subfile is the related file
	;BMXOFF is 1 but What is BMXGL?
	;
	Q
	;
ERROR	Q
