Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: BMXSQL

BMXSQL.m

Go to the documentation of this file.
  1. BMXSQL ; IHS/OIT/HMW - BMX REMOTE PROCEDURE CALLS ;
  1. ;;4.0;BMX;;JUN 28, 2010
  1. ;
  1. ;
  1. Q
  1. ;
  1. FLDNDX(BMXGBL,BMXFL,BMXFLD) ;
  1. ;Returns index name and set code for all indexes on field
  1. ;on field BMXFLD in file BMXFL
  1. S BMX31=$C(31)_$C(31)
  1. K ^BMXTMP($J),^BMXTEMP($J)
  1. S BMXGBL="^BMXTEMP("_$J_")"
  1. I +BMXFL'=BMXFL D
  1. . S BMXFL=$TR(BMXFL,"_"," ")
  1. . I '$D(^DIC("B",BMXFL)) S BMXFL="" Q
  1. . S BMXFL=$O(^DIC("B",BMXFL,0))
  1. I '$G(BMXFL) D ERROUT("File number not provided.",1) Q
  1. ;
  1. ;Check for field name
  1. I +BMXFLD'=BMXFLD D
  1. . S BMXFLD=$TR(BMXFLD,"_"," ")
  1. . I '$D(^DD(BMXFL,"B",BMXFLD)) S BMXFLD="" Q
  1. . S BMXFLD=$O(^DD(BMXFL,"B",BMXFLD,0))
  1. I '$G(BMXFLD) D ERROUT("Field not provided",1) Q
  1. ;
  1. ;Set up Column names
  1. S ^BMXTEMP($J,0)="T"_$$NUMCHAR(30)_"INDEX^T"_$$NUMCHAR(200)_"CODE"_$C(30)
  1. ;
  1. ;Write field data to BMXTEMP
  1. S BMXI=0,I=0
  1. N BMXNAM,BMXCOD,BMXNOD,BMXTYP
  1. F S BMXI=$O(^DD(BMXFL,BMXFLD,1,BMXI)) Q:'+BMXI Q:$D(BMXERR) D
  1. . S I=I+1
  1. . S BMXNOD=$G(^DD(BMXFL,BMXFLD,1,BMXI,0))
  1. . S BMXNAM=$P(BMXNOD,U,2)
  1. . S BMXTYP=$P(BMXNOD,U,3)
  1. . S:BMXTYP="" BMXTYP="REGULAR"
  1. . S BMXCOD=$G(^DD(BMXFL,BMXFLD,1,BMXI,1))
  1. . S BMXCOD=$TR(BMXCOD,"^","~")
  1. . S ^BMXTEMP($J,I)=BMXNAM_U_BMXTYP_U_BMXCOD_$C(30)
  1. Q
  1. ;
  1. TLIST(BMXGBL,BMXFROM,BMXTO) ;
  1. ;Returns list of Fileman files to which user has READ access
  1. ;TODO: Pass in type of access (RD,DL,WR) in BMXPAR
  1. ;
  1. N A,F,BMXF,BMXFLD,D0,BMXU,I,BMXCNT,BMXMFL,BMXRD,BMXMAX
  1. S U="^"
  1. S:$G(BMXFROM)="RD" BMXFROM=""
  1. K ^BMXTMP($J),^BMXTEMP($J)
  1. S BMXGBL="^BMXTEMP("_$J_")"
  1. S BMXF=1
  1. S BMXF("FILE")=1
  1. S BMXFLD("FILE")="1^.01"
  1. S BMXFLD("NUMBER")="1^.001" ;ADDED
  1. S BMXFLDN=$P(BMXFLD("FILE"),"^",2)
  1. S BMXFLDN(1,BMXFLDN)="FILE"
  1. S BMXFLDN=$P(BMXFLD("NUMBER"),"^",2) ;ADDED
  1. S BMXFLDN(1,BMXFLDN)="NUMBER" ;ADDED
  1. S BMXFLDO=2 ;CHANGED FROM 1 TO 2
  1. S BMXFLDO(0)="1^.01"
  1. S BMXFLDOX(1,.01,"E")=0
  1. S BMXFLDO(1)="1^.001" ;ADDED
  1. S BMXFLDOX(1,.001,"E")=1 ;ADDED
  1. S BMXFNX(1)="FILE"
  1. S BMXFO(1)="1"
  1. S BMXU=$G(DUZ(0))
  1. S BMXRD=$C(30)
  1. S ^BMXTEMP($J,0)="T00030FILE^N00010NUMBER"_BMXRD
  1. S BMXSET="S I=I+1,^BMXTEMP($J,I)=$P($G(^DIC(D0,0)),U)_U_D0_BMXRD,BMXCNT=BMXCNT+1"
  1. S D0=0,I=0,BMXCNT=0,BMXMAX=2000
  1. S BMXFROM=$G(BMXFROM),BMXTO=$G(BMXTO)
  1. I +BMXFROM=BMXFROM D ;BMXFROM is a filenumber
  1. . S F=(+BMXFROM-1),T=+BMXTO
  1. . S:BMXTO<BMXFROM BMXTO=BMXFROM+1
  1. . S D0=F F S D0=$O(^DIC(D0)) Q:'+D0 Q:D0>T Q:BMXCNT>BMXMAX I $D(^DD(D0)) D TLIST1
  1. I +BMXFROM'=BMXFROM D ;F is a filename or is null
  1. . S F="",T="zzzzzzz"
  1. . S:$G(BMXFROM)]"" F=$O(^DIC("B",BMXFROM),-1)
  1. . S:$G(BMXTO)]"" T=BMXTO
  1. . F S F=$O(^DIC("B",F)) Q:F="" Q:F]T Q:BMXCNT>BMXMAX D
  1. . . S D0=0 F S D0=$O(^DIC("B",F,D0)) Q:'+D0 D TLIST1
  1. ;
  1. S I=I+1,^BMXTEMP($J,I)=$C(31)
  1. Q
  1. ;
  1. TLIST1 ;
  1. I BMXU="@" X BMXSET Q
  1. Q:$D(^DIC(D0,0))'=11
  1. S A=$G(^DIC(D0,0,"RD"))
  1. I $D(^VA(200,DUZ,"FOF",D0,0)) D Q
  1. . ;I $P(^(0),U,5)="1" X BMXSET Q
  1. . I $P(^VA(200,DUZ,"FOF",D0,0),U,5)="1" X BMXSET Q
  1. F J=1:1:$L(A) I DUZ(0)[$E(A,J) X BMXSET
  1. Q
  1. ;
  1. SQLCOL(BMXGBL,BMXSQL) ;EP
  1. D INTSQL(.BMXGBL,.BMXSQL,1)
  1. Q
  1. ;
  1. SQLD(BMXGBL,BMXSQL) ;EP Serenji Debug Entrypoint
  1. ;D DEBUG^%Serenji("SQLD^BMXSQL(.BMXGBL,.BMXSQL)")
  1. Q
  1. ;
  1. SQL(BMXGBL,BMXSQL) ;EP
  1. D INTSQL(.BMXGBL,.BMXSQL,0)
  1. Q
  1. ;
  1. INTSQL(BMXGBL,BMXSQL,BMXCOL) ;EP
  1. ;
  1. ;SQL Top Wait for debug break
  1. ;D
  1. ;. F J=1:1:10 S K=$H H 1
  1. ;. Q
  1. ;
  1. S X="ERRTRAP^BMXSQL",@^%ZOSF("TRAP")
  1. I $G(BMXSQL)="" S BMXSQL="" D
  1. . N C S C=0 F S C=$O(BMXSQL(C)) Q:'+C D
  1. . . S BMXSQL=BMXSQL_BMXSQL(C)
  1. ;
  1. I BMXSQL["call SHAPE" S BMXSQL="SELECT JUNKNAME, MULTCOLOR FROM JUNKMULT"
  1. ; Global-scope variables
  1. K BMXTK
  1. N BMXF,BMXTK,T,BMXFLD,BMXTMP,BMXM,BMXXMAX,BMXFLDN,BMXV
  1. N BMXX,BMXFG,BMXFF,BMXSCR,BMXPFP
  1. N BMXERR,BMXFLDO,BMXFLDOX,BMXFJ,BMXFO,BMXFNX
  1. N BMXMFL,BMXFLDA
  1. D ^XBKVAR
  1. S U="^"
  1. I $D(^%ZOSF("MAXSIZ")) S X=640 X ^%ZOSF("MAXSIZ")
  1. K ^BMXTMP($J),^BMXTEMP($J),^BMXTMPD($J)
  1. S BMXGBL="^BMXTEMP("_$J_")"
  1. ;Remove CR and LF from BMXSQL
  1. S BMXSQL=$TR(BMXSQL,$C(13)," ")
  1. S BMXSQL=$TR(BMXSQL,$C(10)," ")
  1. S BMXSQL=$TR(BMXSQL,$C(9)," ")
  1. S BMXSQL=$TR(BMXSQL,$C(34),"")
  1. D PARSE^BMXPRS(BMXSQL)
  1. S BMXXMAX=1000000 ;Default Maximum records to return.
  1. D KW^BMXSQL1(.BMXTK)
  1. Q:$D(BMXERR)
  1. ;
  1. ;Get file names into BMXF("NAME")="NUMBER"
  1. ;Get file numbers into BMXFNX(NUMBER)="NAME"
  1. ; Files are ordered in BMXFO(order)="NUMBER"
  1. ;
  1. FROM S T=$G(BMXTK("FROM"))
  1. I '+T S BMXERR="'FROM' CLAUSE NOT FOUND" D ERROR Q
  1. S BMXF=0
  1. F S T=$O(BMXTK(T)) Q:'+T Q:T=$G(BMXTK("WHERE")) Q:T=$G(BMXTK("ORDER BY")) Q:T=$G(BMXTK("GROUP BY")) D Q:$D(BMXERR)
  1. . Q:BMXTK(T)=","
  1. . N BMXFNT
  1. . I BMXTK(T)["'" S BMXTK(T)=$P(BMXTK(T),"'",2)
  1. . S BMXTK(T)=$TR(BMXTK(T),"_"," ")
  1. . I '(BMXTK(T)?.N),'$D(^DIC("B",BMXTK(T))) S BMXERR="FILE NOT FOUND" D ERROR Q
  1. . S BMXF=BMXF+1
  1. . I BMXTK(T)?.N S BMXFNT=BMXTK(T)
  1. . E S BMXFNT=$O(^DIC("B",BMXTK(T),0))
  1. . S BMXMFL(BMXFNT,"GLOC")=^DIC(BMXFNT,0,"GL")
  1. . D F1(BMXF,BMXTK(T),BMXFNT)
  1. . I '+BMXF(BMXTK(T)) S BMXERR="FILE NUMBER NOT FOUND" D ERROR Q
  1. . D ;Test alias
  1. . . Q:'+$O(BMXTK(T))
  1. . . N V
  1. . . S V=T+1
  1. . . Q:$G(BMXTK(V))=","
  1. . . Q:V=$G(BMXTK("WHERE"))
  1. . . Q:V=$G(BMXTK("ORDER BY"))
  1. . . Q:V=$G(BMXTK("GROUP BY"))
  1. . . S BMXTK(T,"ALIAS")=BMXTK(V)
  1. . . K BMXTK(V)
  1. . . Q
  1. . Q
  1. ;
  1. D SELECT^BMXSQL5
  1. I $D(BMXERR) G END
  1. D POST2^BMXPRS ;Remove commas from BMXTK
  1. D KW^BMXSQL1(.BMXTK)
  1. ;
  1. D WHERE^BMXSQL7
  1. ;
  1. ;Find the first WHERE field that has an index
  1. I $D(BMXERR) G END
  1. ;
  1. D INDEX(.BMXFF,.BMXX,.BMXTMP)
  1. ;
  1. S:BMXTMP BMXX=BMXTMP
  1. ;
  1. ;Set up screen logic for where fields
  1. D SCREEN^BMXSQL1
  1. D SETX^BMXSQL2(.BMXX,.BMXFG,.BMXSCR)
  1. ;
  1. ;
  1. EXEC ;Execute enumerator and screen code to call Output routine
  1. ;
  1. N BMXOUT,J,BMXC
  1. S BMXOUT=0
  1. ;Debug lines (retain):
  1. ;K ^HW("BMXX") S J=0 F S J=$O(BMXX(J)) Q:'+J S ^HW("BMXX",J)=BMXX(J)
  1. ;K ^HW("BMXSCR") S ^HW("BMXSCR")=$G(BMXSCR) S J=0 F S J=$O(BMXSCR(J)) Q:'+J S ^HW("BMXSCR",J)=BMXSCR(J)
  1. ;Test for SHOWPLAN
  1. I $G(BMXTK("SHOWPLAN"))="TRUE" D WPLAN Q
  1. S BMXM=0
  1. I 'BMXCOL S J=0 F S J=$O(BMXX(J)) Q:'+J D Q:BMXM>BMXXMAX
  1. . X BMXX(J)
  1. ;
  1. D WRITE^BMXSQL6
  1. ;
  1. END Q
  1. ;
  1. ;
  1. F1(BMXC,BMXNAM,BMXNUM) ;EP
  1. S BMXF(BMXNAM)=BMXNUM
  1. S BMXFNX(BMXNUM)=BMXNAM
  1. S BMXFO(BMXC)=BMXF(BMXNAM)
  1. Q
  1. ;
  1. OUT ;Set result in ^BMXTMP
  1. S BMXOUT=BMXOUT+1
  1. S ^BMXTMP($J,"O",D0)=""
  1. S ^BMXTMP($J,BMXOUT)=D0
  1. S BMXM=BMXM+1
  1. Q
  1. ;
  1. WPLAN ;Write execution plan
  1. ;Set up Column Names
  1. N BMXLEN,BMXTYP,BMXT,J,BMXSCRT,BMXXT
  1. S I=1
  1. F BMXT="VARIABLE^","VALUE"_$C(30) D
  1. . S ^BMXTEMP($J,I)=BMXT,BMXLEN(I)=15,BMXTYP(I)="T"
  1. . S I=I+1
  1. S J=0
  1. I $D(BMXX) F S J=$O(BMXX(J)) Q:'+J D
  1. . S ^BMXTEMP($J,I)="INDEX("_J_")^"
  1. . S I=I+1
  1. . S BMXXT(J)=BMXX(J)
  1. . S BMXXT(J)=$P(BMXXT(J)," X BMXSCR")
  1. . S ^BMXTEMP($J,I)=$TR(BMXXT(J),"^","~")_$C(30)
  1. . S:$L(^BMXTEMP($J,I))>BMXLEN(2) BMXLEN(2)=$L(^BMXTEMP($J,I))
  1. . S I=I+1
  1. S ^BMXTEMP($J,I)="SCREEN^"
  1. S I=I+1
  1. S BMXSCRT=$G(BMXSCR)
  1. S BMXSCRT=$P(BMXSCRT,"D:'$D(^BMXTMP")
  1. S ^BMXTEMP($J,I)=$TR(BMXSCRT,"^","~")_$C(30)
  1. S:$L(^BMXTEMP($J,I))>BMXLEN(2) BMXLEN(2)=$L(^BMXTEMP($J,I))
  1. S I=I+1
  1. S J=0
  1. I $D(BMXSCR("C")) F S J=$O(BMXSCR("C",J)) Q:'+J D
  1. . S ^BMXTEMP($J,I)="SCREEN("_J_")^"
  1. . S I=I+1
  1. . S ^BMXTEMP($J,I)=$TR(BMXSCR("C",J),"^","~")_$C(30)
  1. . S:$L(^BMXTEMP($J,I))>BMXLEN(2) BMXLEN(2)=$L(^BMXTEMP($J,I))
  1. . S I=I+1
  1. D COLTYPE
  1. S I=I+1
  1. D ERRTACK(I)
  1. Q
  1. ;
  1. ;
  1. COLTYPE ;EP - Append column types and widths to output global
  1. ;REQUIRES - BMXLEN(),BMXTYP(),^BMXTEMP
  1. ;IHS/SET/HMW 4-22-2004 Modified to use new schema string
  1. ;
  1. ;"@@@meta@@@BMXIEN|FILE #|DA STRING"
  1. ;
  1. N C
  1. S C=0
  1. F S C=$O(BMXLEN(C)) Q:'C D
  1. . I BMXLEN(C)>99999 S BMXLEN(C)=99999
  1. . I BMXLEN(C)=0 S BMXLEN(C)=50 ;Default column length
  1. . S ^BMXTEMP($J,C)=BMXTYP(C)_$$NUMCHAR(BMXLEN(C))_^BMXTEMP($J,C)
  1. Q
  1. ;
  1. ;S ^BXTEMP($J,0)="@@@meta@@@BMXIEN|"_BMXF_"|" ;Last |-piece will be DA string
  1. ;N C
  1. ;S C=0
  1. ;F S C=$O(BMXLEN(C)) Q:'C D
  1. ;. I BMXLEN(C)>99999 S BMXLEN(C)=99999
  1. ;. I BMXLEN(C)=0 S BMXLEN(C)=50 ;Default column length
  1. ;. S ^BMXTEMP($J,C)=BMXTYP(C)_$$NUMCHAR(BMXLEN(C))_^BMXTEMP($J,C)
  1. ;Q
  1. ;
  1. ERRTACK(I) ;EP
  1. ;
  1. S ^BMXTEMP($J,I)=$C(31)
  1. S:$D(BMXERR) ^BMXTEMP($J,I)=^BMXTEMP($J,I)_BMXERR
  1. Q
  1. ;
  1. NUMCHAR(BMXN) ;EP
  1. ;---> Returns Field Length left-padded with 0
  1. ;
  1. N BMXC
  1. S BMXC="00000"_BMXN
  1. Q $E(BMXC,$L(BMXC)-4,$L(BMXC))
  1. ;
  1. ;
  1. INDEX(BMXFF,BMXRET,BMXXCNT) ;
  1. ;Returns executable enumerator on first where field with an index
  1. ;or "" if no indexed where field
  1. ;IN: BMXFF()
  1. ;OUT: BMXRET()
  1. ; BMXXCNT - size of BMXRET array
  1. ;
  1. N F,BMXNOD,BMXFNUM,BMXFLDNM,BMXHIT,BMXREF,BMXRNAM,BMXOP,Q,BMXGL
  1. N BMXTMP,BMXTMPV,BMXTMPI,BMXTMPL,BMXTMPN,BMXV,BMXRNOD,BMXTMPP
  1. S BMXXCNT=0
  1. S Q=$C(34)
  1. I 'BMXFF Q
  1. S F=0,BMXHIT=0
  1. ;
  1. ;--->Search BMXFF for special case WHERE clause 1 = "0"
  1. ; reset BMXX(1) to return no records
  1. F F=1:1:BMXFF S BMXNOD=BMXFF(F) D Q:$D(BMXERR) Q:BMXHIT
  1. . I ($P(BMXFF(F),"^",2,4)="1^=^0")!($P(BMXFF(F),"^",2,4)="0^=^1") S BMXRET(1)="Q ",BMXHIT=1,BMXXCNT=1
  1. . Q
  1. Q:BMXHIT
  1. ;
  1. ;Organize the first level into AND- and OR-parts
  1. N BMXR1,BMXR2,BMXE,BMXR3,BMXRNAM
  1. N BMXSTOP,BMXOR
  1. D PLEVEL^BMXSQL3(.BMXFF,.BMXR1,.BMXR2)
  1. ;
  1. N BMXPFF S BMXPFF=0
  1. S BMXR3=0
  1. ;Look for an AND-part with only one element.
  1. ; If found, build an iterator on it and quit
  1. F J=1:1:$L(BMXR2,"&") D Q:BMXHIT
  1. . S BMXE=$P(BMXR2,"&",J)
  1. . I +BMXE=BMXE,BMXR1(BMXE,"ELEMENTS")=1 D
  1. . . ;Test index for element
  1. . . F K=BMXR1(BMXE,"BEGIN"):1:BMXR1(BMXE,"END") I "(^)"'[BMXFF(K) D Q ;I'm not sure why this quit was here
  1. . . . Q:$D(BMXFF(K,"JOIN"))
  1. . . . S BMXPFP=K,BMXPFF=0
  1. . . . D XRTST^BMXSQL3(.BMXFF,K,.BMXR3,.BMXRNAM,.BMXPFP)
  1. . . . I BMXR3 S BMXHIT=1,BMXFF(K,"INDEXED")=1
  1. . Q:'BMXHIT
  1. . ;Build iterator and quit
  1. . D BLDIT^BMXSQL3(.BMXFF,K,.BMXRNAM,.BMXOR,.BMXPFP)
  1. . S BMXXCNT=1
  1. . S BMXRET(BMXXCNT)=BMXOR
  1. . Q
  1. Q:BMXHIT
  1. ;
  1. ;None of the single-element AND parts has a good index or
  1. ; there are no single-element AND parts
  1. ;If there are no OR-parts, then there are no good indexes so quit
  1. I $L(BMXR2,"!")=1 Q
  1. ;
  1. ;Test each OR-part for a good index.
  1. ;If an OR-part is multi-element or
  1. ;if one OR-part doesn't have an index
  1. ;then set up to do a table scan and quit
  1. S BMXSTOP=0
  1. F J=1:1:$L(BMXR2,"!") D Q:BMXSTOP
  1. . S BMXE=$P(BMXR2,"!",J)
  1. . I +BMXE=BMXE D
  1. . . I BMXR1(BMXE,"ELEMENTS")'=1 S BMXSTOP=1 Q ;Multiple elements
  1. . . ;Test index elements
  1. . . F K=BMXR1(BMXE,"BEGIN"):1:BMXR1(BMXE,"END") I "(^)"'[BMXFF(K) D Q
  1. . . . S BMXPFP=K,BMXPFF=0
  1. . . . D XRTST^BMXSQL3(.BMXFF,K,.BMXR3,.BMXRNAM,.BMXPFP)
  1. . . . I 'BMXR3 S BMXSTOP=1 Q
  1. . . . S BMXFF(K,"INDEXED")=1
  1. . . . S BMXR1(BMXE,"XREF")=BMXRNAM
  1. ;
  1. ;Build iterator and quit
  1. I BMXSTOP D Q ;One of the elements had no index
  1. . S J=0 F S J=$O(BMXFF(J)) Q:'+J K BMXFF(J,"INDEXED")
  1. S BMXXCNT=0
  1. F J=1:1:$L(BMXR2,"!") D
  1. . S BMXE=$P(BMXR2,"!",J)
  1. . I +BMXE=BMXE,BMXR1(BMXE,"ELEMENTS")=1 D
  1. . . F K=BMXR1(BMXE,"BEGIN"):1:BMXR1(BMXE,"END") I "(^)"'[BMXFF(K) D Q
  1. . . . D BLDIT^BMXSQL3(.BMXFF,K,BMXR1(BMXE,"XREF"),.BMXOR,.BMXPFP)
  1. . . . S BMXXCNT=BMXXCNT+1
  1. . . . S BMXRET(BMXXCNT)=BMXOR
  1. . Q
  1. Q
  1. ;
  1. ;
  1. ;
  1. ERROR ;EP - Error processing
  1. ;W !,BMXERR
  1. ;N A
  1. ;S A=0
  1. ;I $D(I) S A=I
  1. ;D ERROUT(BMXERR,A)
  1. ;B ;ERROR in BMXSQL
  1. Q
  1. ;
  1. ERROUT(BMXERR,I) ;EP
  1. ;---> Save next line for Error Code File if ever used.
  1. ;---> If necessary, use I>1 to avoid overwriting valid data.
  1. D ERRTACK(I)
  1. Q
  1. ;
  1. ERRTRAP ;
  1. ;
  1. K ^BMXTEMP($J)
  1. S ^BMXTEMP($J,0)="T00030M_ERROR"_$C(30)
  1. S BMXZE=$$EC^%ZOSV
  1. S BMXZE=$TR(BMXZE,"^","~")
  1. S ^BMXTEMP($J,1)=BMXZE_$C(30)
  1. S ^BMXTEMP($J,2)=$C(31)
  1. Q