BMXSQL1 ; IHS/OIT/HMW - BMX REMOTE PROCEDURE CALLS ; ;;2.1;BMX;;Jul 26, 2009 ; ; KW(BMXTK) ;EP ;Identify and mark keywords in BMXTK ;MODIFIES BMXTK ; N J,BMXSTOP,BMXTMP ;Combine ORDER BY and GROUP BY into a single token ; S J=0 F S J=$O(BMXTK(J)) Q:'+J D . S BMXTMP=$$UCASE(BMXTK(J)) . I BMXTMP="ORDER"!(BMXTMP="GROUP") D . . I $D(BMXTK(J+1)),$$UCASE(BMXTK(J+1))="BY" D . . . S BMXTK(J)=BMXTK(J)_" "_BMXTK(J+1) . . . S BMXTK(J)=$$UCASE(BMXTK(J)) . . . S BMXTK(BMXTK(J))=J . . . K BMXTK(J+1) . . . Q . . Q . Q ; ;Find SELECT S J=0,BMXSTOP=0 F S J=$O(BMXTK(J)) Q:'+J D Q:BMXSTOP . I $$UCASE(BMXTK(J))="SELECT" D . . S BMXTK(J)=$$UCASE(BMXTK(J)) . . S BMXTK("SELECT")=J . . S BMXSTOP=1 . . Q . Q I '+J S BMXERR="SELECT KEYWORD NOT FOUND" Q ; ;DISTINCT S BMXSTOP=0 F S J=$O(BMXTK(J)) Q:'+J Q:$$UCASE(BMXTK(J))="FROM" D Q:BMXSTOP . I $$UCASE(BMXTK(J))="DISTINCT" D . . S BMXTK("DISTINCT")="TRUE" . . K BMXTK(J) . . S J=J-1 . . S BMXSTOP=1 . Q ; ;FROM S BMXSTOP=0 S J=J-1 F S J=$O(BMXTK(J)) Q:'+J Q:$$UCASE(BMXTK(J))="WHERE" D Q:BMXSTOP . I $$UCASE(BMXTK(J))="FROM" D . . S BMXTK(J)=$$UCASE(BMXTK(J)) . . S BMXTK("FROM")=J . . S BMXSTOP=1 . . Q . Q ; I '$D(BMXTK("FROM")) S BMXERR="'FROM' KEYWORD NOT FOUND" Q ; ;WHERE S BMXSTOP=0 F S J=$O(BMXTK(J)) Q:'+J Q:BMXTK(J)="ORDER BY" Q:BMXTK(J)="GROUP BY" D Q:BMXSTOP . I $$UCASE(BMXTK(J))="WHERE" D . . S BMXTK(J)=$$UCASE(BMXTK(J)) . . S BMXTK("WHERE")=J . . S BMXSTOP=1 . Q ; ;SHOWPLAN S J=BMXTK("FROM") S BMXSTOP=0 F S J=$O(BMXTK(J)) Q:'+J D Q:BMXSTOP . I $$UCASE(BMXTK(J))="SHOWPLAN" D . . S BMXTK("SHOWPLAN")="TRUE" . . K BMXTK(J) . . S J=J-1 . . S BMXSTOP=1 . Q ; ;MAXRECORDS S J=BMXTK("FROM") S BMXSTOP=0 F S J=$O(BMXTK(J)) Q:'+J D Q:BMXSTOP . I $$UCASE(BMXTK(J))["MAXRECORDS" D . . S BMXXMAX=+$P(BMXTK(J),":",2)-1 . . S:+BMXXMAX<0 BMXXMAX=0 . . K BMXTK(J) . . S J=J-1 . . S BMXSTOP=1 . Q Q ; SCREEN ;EP ;Set up BMXFG() array of executable screen code N F,BMXNOD,BMXFNUM,BMXFLDNUM,BMXHIT,BMXREF N BMXRNAM,BMXRET,BMXOP,Q,BMXPC,BMXV,BMXFLDLO,BMXFLDNO N BMXGL S BMXRET="" S Q=$C(34) S BMXFG=BMXFF S BMXFG("C")=0 I 'BMXFF Q S F=0,BMXHIT=0 F F=1:1:BMXFF S BMXNOD=BMXFF(F) D Q:$D(BMXERR) Q:BMXHIT . I $G(BMXFF(F,"INDEXED"))=1 D Q . . S BMXFG(F)="1" . . Q . I $D(BMXFF(F,"JOIN")) D Q . . S BMXFG(F)="1" . . Q . I "(^)"[BMXFF(F) D Q . . S BMXFG(F)=BMXFF(F) . . Q . I "AND^OR"[BMXFF(F) D Q . . I BMXFF(F)="AND" S BMXFG(F)="&" Q . . S BMXFG(F)="!" . . Q . S BMXFNUM=$S(+$P(BMXNOD,U):$P(BMXNOD,U),1:$O(^DIC("B",$P(BMXNOD,U),0))) . I '+BMXFNUM D ;Not a fileman field . . S BMXFLDNUM=0,BMXFLDNO="" . . S BMXFLDLO=$P(BMXFF(F),U,2) . . ; . E D ;Get fileman field data . . S BMXGL=^DIC(BMXFNUM,0,"GL") . . I $D(BMXFF(F,"IEN")) D . . . S BMXFLDNUM=".001" . . . S BMXFLDNO="IEN" . . E D . . . S BMXFLDNUM=$O(^DD(BMXFNUM,"B",$P(BMXNOD,U,2),0)) . . . S BMXFLDNO=^DD(BMXFNUM,BMXFLDNUM,0) . I BMXFLDNO="IEN" D ;BMXIEN field . . N BMXEXT,C S BMXEXT=0 . . ;S BMXPC=$P(BMXFLDNO,U,4) . . I $P(BMXFF(F),U,5)'=BMXFO(1) S BMXEXT=1 D EXP ;Extended pointer . . S BMXFLDLO="D0" . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXFLDLO,BMXFLDLO="BMXSCR(""X"","_C_")" . I $P(BMXFLDNO,U,2)["D" D ;Date field . . N BMXEXT,C S BMXEXT=0 . . S BMXPC=$P(BMXFLDNO,U,4) . . I $P(BMXFF(F),U,5)'=BMXFO(1) S BMXEXT=1 D EXP ;Extended pointer . . S BMXFLDLO="$P($G("_BMXGL_"D0,"_Q_$P(BMXPC,";")_Q_")),U,"_$P(BMXPC,";",2)_")" . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXFLDLO,BMXFLDLO="BMXSCR(""X"","_C_")" . I $P(BMXFLDNO,U,2)["S" D ;Set field . . N BMXEXT,C S BMXEXT=0 . . S BMXPC=$P(BMXFLDNO,U,4) . . I $P(BMXFF(F),U,5)'=BMXFO(1) S BMXEXT=1 D EXP ;Extended pointer . . S BMXFLDLO="$P("_BMXGL_"D0,"_$P(BMXPC,";")_"),U,"_$P(BMXPC,";",2)_")" . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXFLDLO,BMXFLDLO="BMXSCR(""X"","_C_")" . ; . I $P(BMXFLDNO,U,2)["P" D ;Pointer field . . N C,BMXEXT . . S BMXEXT=0 . . I $P(BMXFF(F),U,5)'=BMXFO(1) D . . . N R,G,BMXJN,BMXMSCR . . . S BMXMXCR=1 ;Remove after testing. Find out if the field is from a subfile. . . . I BMXMXCR D Q . . . . ;Set up a screen in BMXSCR and in BMXMFL( . . . . Q . . . ; . . . ;Find the node of BMXFF that has the join info . . . S BMXEXT=1 . . . S BMXFG("C")=BMXFG("C")+1 . . . S C=BMXFG("C") . . . S R=0 F S R=$O(BMXFJ("JOIN",R)) Q:'+R I R=$P(BMXFF(F),U,5) S G=BMXFJ("JOIN",R) Q . . . S BMXJN=BMXFF(G,"JOIN") . . . S BMXJN=$P(BMXJN,"IEN0",1)_"D0"_$P(BMXJN,"IEN0",2) . . . S BMXJN="S X="""","_BMXFF(G,"JOIN","IEN")_"=D0 N D0 "_BMXJN_"I +D0 S X=" . . . S BMXFG("C",C)=BMXJN . . S BMXFLDLO=$$SCRNP(F,BMXGL,BMXFLDNUM,BMXFLDNO) . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXFLDLO,BMXFLDLO="BMXSCR(""X"","_C_")" . I $P(BMXFLDNO,U,2)["C" D ;Computed field . . N C . . S BMXPC=$P(BMXFLDNO,U,5,99) . . S BMXFG("C")=BMXFG("C")+1 . . S C=BMXFG("C") . . ;If computed field not in primary file, connect navigation code . . I $P(BMXFF(F),U,5)'=BMXFO(1) D . . . ;Find the node of BMXFF that has the join info . . . N R,G,BMXJN . . . S R=0 F S R=$O(BMXFJ("JOIN",R)) Q:'+R I R=$P(BMXFF(F),U,5) S G=BMXFJ("JOIN",R) Q . . . S BMXJN=BMXFF(G,"JOIN") . . . S BMXJN=$P(BMXJN,"IEN0",1)_"D0"_$P(BMXJN,"IEN0",2) . . . S BMXJN="S X="""","_BMXFF(G,"JOIN","IEN")_"=D0 N D0 "_BMXJN_"I +D0 " . . . S BMXJN=BMXJN_BMXPC . . . S BMXFF(F,0)=$P(BMXFF(F,0),U,1,4) . . . S $P(BMXFF(F,0),U,5)=BMXJN . . . S BMXPC=BMXJN . . S BMXFG("C",C)=BMXPC . . S BMXFLDLO="BMXSCR(""X"","_C_")" . I $P(BMXFLDNO,U,2)["N" D ;Numeric field . . N BMXEXT,C S BMXEXT=0 . . S BMXPC=$P(BMXFLDNO,U,4) . . I $P(BMXFF(F),U,5)'=BMXFO(1) S BMXEXT=1 D EXP ;Extended pointer . . S BMXFLDLO="$P("_BMXGL_"D0,"_$P(BMXPC,";")_"),U,"_$P(BMXPC,";",2)_")" . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXFLDLO,BMXFLDLO="BMXSCR(""X"","_C_")" . ; . I $P(BMXFLDNO,U,2)["F" D ;Free Text field . . N BMXEXT,C S BMXEXT=0,C=0 . . S BMXPC=$P(BMXFLDNO,U,4) . . I $P(BMXFF(F),U,5)'=BMXFO(1) S BMXEXT=1 D . . . N R,G,BMXJN . . . S BMXFG("C")=BMXFG("C")+1 . . . S C=BMXFG("C") . . . S R=0 F S R=$O(BMXFJ("JOIN",R)) Q:'+R I R=$P(BMXFF(F),U,5) S G=BMXFJ("JOIN",R) Q . . . S BMXJN=BMXFF(G,"JOIN") . . . S BMXJN=$P(BMXJN,"IEN0",1)_"D0"_$P(BMXJN,"IEN0",2) . . . S BMXJN="S X="""","_BMXFF(G,"JOIN","IEN")_"=D0 N D0 "_BMXJN . . . S BMXJN=BMXJN_"I +D0 S X=" . . . S BMXFG("C",C)=BMXJN . . . S BMXFLDLO="BMXSCR(""X"","_C_")" . . I $P(BMXFLDNO,U,4)["E" D . . . N BMXPC2,BMXTMP . . . S BMXPC2=$P(BMXPC,"E",2) . . . S BMXTMP="$E("_BMXGL_"D0,"_$P(BMXPC,";")_"),"_$P(BMXPC2,",")_","_$P(BMXPC2,",",2)_")" . . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXTMP . . . E S BMXFLDLO=BMXTMP . . E D . . . N BMXTMP . . . S BMXTMP="$P("_BMXGL_"D0,"_$P(BMXPC,";")_"),U,"_$P(BMXPC,";",2)_")" . . . S BMXTMP="$S($D("_BMXGL_"D0,"_$P(BMXPC,";")_")):"_BMXTMP_",1:"""")" . . . I BMXEXT S BMXFG("C",C)=BMXFG("C",C)_BMXTMP . . . E S BMXFLDLO=BMXTMP . ; . S BMXOP=$P(BMXNOD,U,3) . S BMXV=$P(BMXFF(F),U,4) . I "<^>^=^["[BMXOP D . . I BMXOP=">",BMXV?.A S BMXOP="]" . . I BMXOP="<",BMXV?.A S BMXOP="']" . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . . Q . I "<>"=BMXOP D . . S BMXOP="'=" . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . I ">="=BMXOP D . . I BMXV="" S BMXRET="(I 1)" Q . . I +BMXV=BMXV D Q . . . S BMXOP="'<" . . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . . S BMXV=$$DECSTR^BMXSQL2(BMXV) . . S BMXOP="]" . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . I "<="=BMXOP D . . I BMXV="" S BMXRET="(I 0)" Q . . I +BMXV=BMXV D Q . . . S BMXOP="'>" . . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . . S BMXV=$$INCSTR^BMXSQL2(BMXV) . . S BMXOP="']" . . S BMXRET="("_BMXFLDLO_BMXOP_Q_BMXV_Q_")" . I BMXOP="BETWEEN" D . . I +$P(BMXV,"~")'=$P(BMXV,"~") D ;BMXV a string . . . N W,X,Y,Z . . . S X=$P(BMXV,"~") . . . S Y=$E(X,1,$L(X)-1) . . . S Z=$E(X,$L(X)) . . . S Z=$A(Z) . . . S Z=Z-1 . . . S Z=$C(Z) . . . S W=Y_Z . . . S $P(BMXV,"~")=W . . . S BMXRET="(("_BMXFLDLO_"]"_Q_$P(BMXV,"~")_Q_")&("_BMXFLDLO_"']"_Q_$P(BMXV,"~",2)_Q_"))" . . E D ;BMXV a number . . . S BMXRET="(("_BMXFLDLO_"'<"_$P(BMXV,"~")_")&("_BMXFLDLO_"'>"_$P(BMXV,"~",2)_"))" . . Q . I BMXOP="LIKE" D . . S BMXRET="("_BMXFLDLO_"?1"_Q_BMXV_Q_".E)" . I BMXRET]"" D . . S BMXFG(F)=BMXRET . . Q . ;TODO: Pointer fields . ;TODO: Computed fields . ;TODO: Sets of codes . ;TODO: Dates . Q Q ; SCRNP(F,BMXGL,BMXFLDNU,BMXFLDNO) ; ;Requires BMXFF() ;Sets up expression for pointer field N BMX,BMXCOR,BMXRET,BMXPC S BMXPC=$P(BMXFLDNO,U,4) S BMXCOR="$P($G("_BMXGL_"D0,"_Q_$P(BMXPC,";")_Q_")),U,"_$P(BMXPC,";",2)_")" S BMXRET=BMXCOR Q:$D(BMXFF(F,"INTERNAL")) BMXRET S BMXFNUM=$P(BMXFLDNO,U,2) S BMXFNUM=+$P(BMXFNUM,"P",2) S BMXGL=^DIC(BMXFNUM,0,"GL") S BMXFLDNUM=".01" S BMXFLDNO=^DD(BMXFNUM,BMXFLDNUM,0) F D:$P(BMXFLDNO,U,2)["P" Q:$P(BMXFLDNO,U,2)'["P" . S BMXPC=$P(BMXFLDNO,U,4) . S BMXRET="$P($G("_BMXGL_BMXRET_","_Q_$P(BMXPC,";")_Q_")),U,"_$P(BMXPC,";",2)_")" . S BMXFNUM=$P(BMXFLDNO,U,2) . S BMXFNUM=+$P(BMXFNUM,"P",2) . S BMXGL=^DIC(BMXFNUM,0,"GL") . S BMXFLDNUM=".01" . S BMXFLDNO=^DD(BMXFNUM,BMXFLDNUM,0) ;B ;SCRN2 After chain ;I 0 D ;$P(BMXFLDNO,U,2)["D" D ;Pointer to a date ;. Q:+$G(BMXFF(F,"INDEXED")) ;Dates converted when iterator built ;. N BMXD,J ;. S BMXD=$P(BMXFF(F),U,4) ;. S %DT="T" ;. F J=1:1:$L(BMXD,"~") D ;. . S X=$P(BMXD,"~",J) ;. . D ^%DT ;. . S $P(BMXD,"~",J)=Y ;. S $P(BMXFF(F),U,4)=BMXD S BMXRET="$P($G("_BMXGL_BMXRET_",0)),U,1)" S BMXRET="$S(+"_BMXCOR_":"_BMXRET_",1:"""")" Q BMXRET ; CASE(BMXTK) ;EP ;Convert keywords to uppercase N J S J=0 F S J=$O(BMXTK(J)) Q:'+J D . F K="DISTINCT","SELECT","WHERE","FROM","SHOWPLAN" D . . I $$UCASE(BMXTK(J))=K S BMXTK(J)=$$UCASE(BMXTK(J)) . Q Q ; UCASE(X) ;EP Convert X to uppercase F %=1:1:$L(X) S:$E(X,%)?1L X=$E(X,0,%-1)_$C($A(X,%)-32)_$E(X,%+1,999) Q X ; EXP ;Extended pointer N R,G,BMXJN S BMXEXT=1 S BMXFG("C")=BMXFG("C")+1 S C=BMXFG("C") S R=0 F S R=$O(BMXFJ("JOIN",R)) Q:'+R I R=$P(BMXFF(F),U,5) S G=BMXFJ("JOIN",R) Q S BMXJN=BMXFF(G,"JOIN") S BMXJN=$P(BMXJN,"IEN0",1)_"D0"_$P(BMXJN,"IEN0",2) S BMXJN="S X="""","_BMXFF(G,"JOIN","IEN")_"=D0 N D0 "_BMXJN_"I +D0 S X=" S BMXFG("C",C)=BMXJN Q