[796] | 1 | TMGRPC1C ;TMG/kst-RPC Functions for CPRS for Search functionality ;4/28/10 ; 5/18/10 12:57pm
|
---|
| 2 | ;;1.0;TMG-LIB;**1**;4/28/10
|
---|
| 3 | ;
|
---|
| 4 | ;"TMG RPC FUNCTIONS
|
---|
| 5 | ;
|
---|
| 6 | ;"Copyright Kevin Toppenberg MD 4/28/10
|
---|
| 7 | ;"Released under GNU General Public License (GPL)
|
---|
| 8 | ;"
|
---|
| 9 | ;"=======================================================================
|
---|
| 10 | ;" RPC -- Public Functions.
|
---|
| 11 | ;"=======================================================================
|
---|
| 12 | ;"SRCH(OUT,FILENUM,STR) --A search function, to support calls by RPC from CPRS
|
---|
| 13 | ;"=======================================================================
|
---|
| 14 | ;"PRIVATE API FUNCTIONS
|
---|
| 15 | ;"=======================================================================
|
---|
| 16 | ;
|
---|
| 17 | ;"=======================================================================
|
---|
| 18 | ;"=======================================================================
|
---|
| 19 | ;"Dependencies:
|
---|
| 20 | ;" DIC, TMGDEBUG
|
---|
| 21 | ;"=======================================================================
|
---|
| 22 | ;"=======================================================================
|
---|
| 23 | ;
|
---|
| 24 | ;
|
---|
| 25 | ;
|
---|
| 26 | SRCH(OUT,FILENUM,STR) ;
|
---|
| 27 | ;"Purpose: A search function, to support calls by RPC from CPRS
|
---|
| 28 | ;"Input: OUT-- Pass by reference. AN OUT PARAMETER.
|
---|
| 29 | ;" FILENUM -- The target file number that resulting IENs will be in
|
---|
| 30 | ;" STR -- This is a logic string for searching. See details below.
|
---|
| 31 | ;"Results: OUT is filled in. Format:
|
---|
| 32 | ;" OUT(0)=1 for success, or -1^Error Message
|
---|
| 33 | ;" OUT(IEN)=""
|
---|
| 34 | ;" OUT(IEN)=""
|
---|
| 35 | ;"Search string examples:
|
---|
| 36 | ;" 8925:.02(.01="SMITH,JOHN")
|
---|
| 37 | ;" 1234:.01(.03in"32..55") <-- this is a range test
|
---|
| 38 | ;" 1234:.99((.01="SMITH,JOHN") OR (.01="SMITH,BILL")) AND 4567:.01(.02'="4/2/10") NOT (1["HAPPY")
|
---|
| 39 | ;" -- File specifier. To specify searching in a file OTHER THAN target filenumber, an optional
|
---|
| 40 | ;" FILENUM:FLD[:FLD[:FLD...]] may be specified. However, ultimately, this must point back
|
---|
| 41 | ;" to the target filenumber. E.g. Search in file 8925, but for each entry found, use the IEN
|
---|
| 42 | ;" specified by FLD (or FLDA:FLDB or FLDA:FLDB:FLDC:...)
|
---|
| 43 | ;" FILENUM:(...)
|
---|
| 44 | ;" The logic is read from left to right, honoring parentheses. If a filenumber
|
---|
| 45 | ;" is not specified, then the last specified filenumber is used.
|
---|
| 46 | ;" E.g. 1234:.01( LogicA ) OR 234:.99( LogicB ) AND ( LogicC )
|
---|
| 47 | ;" LogicA fields refer to file 1234:.01.
|
---|
| 48 | ;" LogicB fields refer to file 234:.99
|
---|
| 49 | ;" LogicA fields refer to file 234:.99 (last specified file number)
|
---|
| 50 | ;" E.g. 5678:.01( (LogicA1) OR 5432:.88(LogicA2) NOT (LogicA3) ) or (LogicB)
|
---|
| 51 | ;" LogicA1 fields refer to file 5678:.01
|
---|
| 52 | ;" LogicA2 fields refer to file 5432:.88
|
---|
| 53 | ;" LogicA3 fields refer to file 5432:.88 (last specified file number inside parentheses)
|
---|
| 54 | ;" LogicB fields refer to file 5678 (last specified file number at same parentheses level)
|
---|
| 55 | ;" -- Each individual search term must be enclosed in parentheses, and may contain sub-terms
|
---|
| 56 | ;" enclosed in nested parentheses
|
---|
| 57 | ;" -- Each individual search term is comprised of:
|
---|
| 58 | ;" FIELD then COMPARATOR then VALUE
|
---|
| 59 | ;" 1. FIELDS -- can be name or number. This is for currently active file (see below)
|
---|
| 60 | ;" may also be FIELDA:FIELDB:... when FIELDA is a pointer, then FIELDB
|
---|
| 61 | ;" is taken from the pointed-to field.
|
---|
| 62 | ;" 2. COMPARATOR -- can be:
|
---|
| 63 | ;" "=" -- means exact match
|
---|
| 64 | ;" "'=", "!=", "<>", -- any of these means 'Does not equal'
|
---|
| 65 | ;" ">=", "'<" -- means greater-than-or-equal-to (same as not-less-than)
|
---|
| 66 | ;" "<=", "'>" -- means less-than-or-equal-to (same sa not-greater-than)
|
---|
| 67 | ;" "in","IN","In" -- means field is in specified rage (see Value below)
|
---|
| 68 | ;" "[" -- means 'contains'. Interpreted as follows:
|
---|
| 69 | ;" -- For Word processor (WP) fields, this means that any line in the entire field
|
---|
| 70 | ;" can contain search term, to be matched positive.
|
---|
| 71 | ;" -- For free text field, then just text of field is searched.
|
---|
| 72 | ;" -- For Date fields .... (FINISH THIS...)
|
---|
| 73 | ;" -- For Sets ... (FINISH THIS...)
|
---|
| 74 | ;" 3. VALUE -- The search term to search for. Should be in quotes.
|
---|
| 75 | ;" Note: if comparator is "IN", then syntax is "Value1..Value2"
|
---|
| 76 | ;" There should be a ".." between the two values.
|
---|
| 77 | ;" -- Logical combiners of separate search terms allowed are:
|
---|
| 78 | ;" "OR" or "|" or "||"
|
---|
| 79 | ;" "AND" or "&" or "&&"
|
---|
| 80 | ;" "NOT" or "!" or "'" or "ANDNOT"
|
---|
| 81 | ;" -- Logic short-circuiting is applied. The algorhythm will try to identify the elements
|
---|
| 82 | ;" of the search that will be the fastest, and then work from that set, to make the overall
|
---|
| 83 | ;" search better.
|
---|
| 84 | ;" -- Searching of subfiles is not currently supported. IMPLEMENT LATER....
|
---|
| 85 | ;"Results: None
|
---|
| 86 | ;"
|
---|
| 87 | NEW ARRAY,RESULT
|
---|
| 88 | SET FILENUM=$GET(FILENUM)
|
---|
| 89 | SET ARRAY("FILE")=FILENUM
|
---|
| 90 | SET OUT(0)=1 ;"Default to success
|
---|
| 91 | SET RESULT=$$PARSESTR(FILENUM,STR,.ARRAY)
|
---|
| 92 | ZWR ARRAY
|
---|
| 93 | DO PressToCont^TMGUSRIF
|
---|
| 94 | quit
|
---|
| 95 | IF +RESULT=-1 SET OUT(0)=RESULT GOTO SRCHDN
|
---|
| 96 | SET RESULT=$$OPTIMIZ(.ARRAY)
|
---|
| 97 | IF +RESULT=-1 SET OUT(0)=RESULT GOTO SRCHDN
|
---|
| 98 | SET RESULT=$$DOSRCH(.ARRAY,.OUT)
|
---|
| 99 | IF +RESULT=-1 SET OUT(0)=RESULT GOTO SRCHDN
|
---|
| 100 | SRCHDN QUIT
|
---|
| 101 | ;
|
---|
| 102 | ;
|
---|
| 103 | PARSESTR(FILENUM,STR,ARRAY,FNUMPTR) ;
|
---|
| 104 | ;"Purpose: To take user input, validate it, and parse into an formatted array
|
---|
| 105 | ;"Input: STR: This is the user input string. Format as documented in SRCH() above.
|
---|
| 106 | ;" ARRAY -- PASS BY REFERENCE. An OUT PARAMETER. Format as follows.
|
---|
| 107 | ;" ARRAY(1,"FNUMPTR")= FNUM:FLDA[:FLDB[:FLDC...]] FNUM is filenumber that
|
---|
| 108 | ;" contain search field, and then fields used to point
|
---|
| 109 | ;" back to *TARGET* FILENUM for entire search
|
---|
| 110 | ;" ARRAY(1,"FLD")=Fieldnumber to search
|
---|
| 111 | ;" ARRAY(1,"COMP")=Comparator, will be "=", "'=", "'<", or "'>", "["
|
---|
| 112 | ;" ARRAY(1,"SRCH")=The value of to be used in search.
|
---|
| 113 | ;" ARRAY(2,...) The second search term.
|
---|
| 114 | ;" ARRAY(3,...) The third search term (which is comprised of sub terms)
|
---|
| 115 | ;" ARRAY(3,1,... The first subterm (same format as higher level)
|
---|
| 116 | ;" ARRAY(3,2,... The second subterm (same format as higher level)
|
---|
| 117 | ;" ARRAY(n,...) The N'th search term.
|
---|
| 118 | ;" ARRAY("SETCOMP",i)= NumA^Combiner^NumB
|
---|
| 119 | ;" NumA and NumB refer to seach term number (e.g. 1, 2, ... n above)
|
---|
| 120 | ;" If NumA="#", then it means 'the resulting set of results so far'
|
---|
| 121 | ;" Combiner will be "AND", "OR", or "NOT"
|
---|
| 122 | ;" i is the index variable, and logic should be evaluated in numerical order
|
---|
| 123 | ;" FNUMPTR: Will be used when calling self reiteratively. Leave blank in first call.
|
---|
| 124 | ;" DON'T pass by reference. This is 'FileNum:FLD[:FLD[:FLD...]] specifier
|
---|
| 125 | ;"Results: 1 if OK, or -1^Message if error during processing.
|
---|
| 126 | ;
|
---|
| 127 | NEW SUBSTRA,SUBSTRB,POS
|
---|
| 128 | NEW RESULT SET RESULT=1 ;"default to success
|
---|
| 129 | NEW TERMNUM SET TERMNUM=0
|
---|
| 130 | SET FNUMPTR=$GET(FNUMPTR,FILENUM)
|
---|
| 131 | NEW LOGICNUM SET LOGICNUM=0
|
---|
| 132 | NEW DONE SET DONE=0
|
---|
| 133 | FOR DO QUIT:(DONE=1)!(+RESULT=-1)
|
---|
| 134 | . NEW TEMPARRAY
|
---|
| 135 | . SET TERMNUM=TERMNUM+1
|
---|
| 136 | . ;"--- Get file number, if any
|
---|
| 137 | . SET STR=$$TRIM^XLFSTR(STR)
|
---|
| 138 | . IF +$PIECE(STR,"(",1)>0 DO QUIT:(+RESULT=-1)
|
---|
| 139 | . . SET FNUMPTR=$PIECE(STR,"(",1) ;"Convert 1234:.01:.02:(...) --> 1234:.01:.02:
|
---|
| 140 | . . IF $EXTRACT(FNUMPTR,$LENGTH(FNUMPTR))=":" SET FNUMPTR=$EXTRACT(FNUMPTR,1,$LENGTH(FNUMPTR)-1)
|
---|
| 141 | . . IF $$FNPTR(FNUMPTR)'=FILENUM DO QUIT
|
---|
| 142 | . . . SET RESULT="-1^'"_FNUMPTR_"' points to file #"_$$FNPTR(FNUMPTR)_", not file #"_FILENUM_" as expected"
|
---|
| 143 | . ;"Split STR --> SUBSTRA + SUBSTRB
|
---|
| 144 | . SET SUBSTRA=$$MATCHXTR^TMGSTUTL(STR,"(")
|
---|
| 145 | . IF SUBSTRA="" SET DONE=1 QUIT
|
---|
| 146 | . SET POS=$FIND(STR,SUBSTRA) ;"Return pos of following character
|
---|
| 147 | . SET SUBSTRB=$EXTRACT(STR,POS+1,9999) ;"Should be " [LOGICTERM] [SearchTerm]..."
|
---|
| 148 | . ;"Process SUBSTRA, either directly if single term, or recursively if compound term.
|
---|
| 149 | . IF $$HNQTSUB^TMGSTUTL(SUBSTRA,"(") DO
|
---|
| 150 | . . SET RESULT=$$PARSESTR(FILENUM,SUBSTRA,.TEMPARRAY,FNUMPTR)
|
---|
| 151 | . ELSE DO
|
---|
| 152 | . . SET RESULT=$$PARSE1(FILENUM,SUBSTRA,FNUMPTR,.TEMPARRAY)
|
---|
| 153 | . IF +RESULT=-1 QUIT
|
---|
| 154 | . MERGE ARRAY(TERMNUM)=TEMPARRAY
|
---|
| 155 | . ;"Now get Logic term connecting this to next term (if any)
|
---|
| 156 | . SET SUBSTRB=$$TRIM^XLFSTR(SUBSTRB) ;"Remove opening (and closing) spaces
|
---|
| 157 | . NEW LOGICTERM SET LOGICTERM=$$UP^XLFSTR($PIECE(SUBSTRB," ",1))
|
---|
| 158 | . IF LOGICTERM="" SET DONE=1 QUIT
|
---|
| 159 | . IF (LOGICTERM="|")!(LOGICTERM="||") SET LOGICTERM="OR"
|
---|
| 160 | . ELSE IF (LOGICTERM="&")!(LOGICTERM="&&") SET LOGICTERM="AND"
|
---|
| 161 | . ELSE IF (LOGICTERM="!")!(LOGICTERM="'")!(LOGICTERM="ANDNOT") SET LOGICTERM="NOT"
|
---|
| 162 | . IF (LOGICTERM="AND")!(LOGICTERM="OR")!(LOGICTERM="NOT") DO
|
---|
| 163 | . . NEW CURSET SET CURSET=$SELECT(TERMNUM=1:"1",1:"#")
|
---|
| 164 | . . SET LOGICNUM=LOGICNUM+1
|
---|
| 165 | . . SET ARRAY("SETCOMP",LOGICNUM)=CURSET_"^"_LOGICTERM_"^"_(TERMNUM+1) ;"will check later that TERMNUM+1 is supplied
|
---|
| 166 | . ELSE DO QUIT
|
---|
| 167 | . . SET RESULT="-1^Bad logic term. Expect 'AND', 'OR', or 'NOT'. Found: ["_LOGICTERM_"]"
|
---|
| 168 | . SET STR=$PIECE(SUBSTRB," ",2,999)
|
---|
| 169 | QUIT RESULT
|
---|
| 170 | ;
|
---|
| 171 | ;
|
---|
| 172 | FNPTR(FNUMPTR) ;
|
---|
| 173 | ;"Puprose: To resolve a FNUMPTR, finding ultimate target file
|
---|
| 174 | ;"Input: FNUMPTR: Format: FNUM:FLDA[:FLDB[:FLDC...]] FNUM is filenumber that
|
---|
| 175 | ;" contain search field, and then fields used to point to *TARGET* FILENUM
|
---|
| 176 | ;"Results: -1^Error message if error, otherwise returns pointed to file
|
---|
| 177 | NEW RESULT,FILE,FLD,I,DONE
|
---|
| 178 | SET FILE=+$GET(FNUMPTR)
|
---|
| 179 | SET RESULT=0
|
---|
| 180 | SET DONE=0
|
---|
| 181 | FOR I=2:1:999 DO QUIT:(+RESULT=-1)!(DONE=1)
|
---|
| 182 | . SET FLD=$PIECE(FNUMPTR,":",I)
|
---|
| 183 | . IF FLD="" SET DONE=1 QUIT
|
---|
| 184 | . IF $DATA(^DD(FILE,FLD,0))=0 DO QUIT
|
---|
| 185 | . . SET RESULT="-1^Field ["_FLD_"] was not found in file ["_FILE_"]"
|
---|
| 186 | . NEW FLDTYPE SET FLDTYPE=$PIECE(^DD(+FILE,+FLD,0),"^",2)
|
---|
| 187 | . IF FLDTYPE'["P" DO QUIT
|
---|
| 188 | . . SET RESULT="-1^Field ["_FLD_"] does not point to another file."
|
---|
| 189 | . SET FILE=+$PIECE(FLDTYPE,"P",2)
|
---|
| 190 | SET RESULT=FILE
|
---|
| 191 | QUIT RESULT
|
---|
| 192 | ;
|
---|
| 193 | PARSE1(FILENUM,STR,FNUMPTR,ARRAY) ;
|
---|
| 194 | ;"Purpose: Parse a simple search term (e.g. .01="SMITH,JOHN"). Also validate that field exists in file.
|
---|
| 195 | ;"Input: FILENUM -- The TARGET filenumber that the entire search is referencing.
|
---|
| 196 | ;" STR: This is part of the user input string to parse
|
---|
| 197 | ;" FNUMPTR: FNUM:FLDA[:FLDB[:FLDC...]] FNUM is filenumber that contain search field, and then
|
---|
| 198 | ;" fields used to point back to *TARGET* FILENUM for entire search
|
---|
| 199 | ;" ARRAY -- PASS BY REFERENCE. An OUT PARAMETER. Format as follows.
|
---|
| 200 | ;" ARRAY("FNUMPTR")=Filenumber that contains field)
|
---|
| 201 | ;" ARRAY("FLD")=Fieldnumber to search
|
---|
| 202 | ;" ARRAY("COMP")=Comparator, will be "=", "'=", "'<", or "'>", "[","IN"
|
---|
| 203 | ;" ARRAY("SRCH")=The value of to be used in search.
|
---|
| 204 | ;"NOTE: If field specifies a DATE, then the search value will be converted to FileMan format
|
---|
| 205 | ;"Results: 1 if OK, or -1^Message if error during processing.
|
---|
| 206 | ;"
|
---|
| 207 | NEW RESULT SET RESULT=1 ;"default to success
|
---|
| 208 | NEW SAV SET SAV=STR
|
---|
| 209 | SET STR=$$TRIM^XLFSTR($GET(STR))
|
---|
| 210 | SET ARRAY("FNUMPTR")=FNUMPTR
|
---|
| 211 | NEW FLD SET FLD=+STR
|
---|
| 212 | IF $DATA(^DD(+FNUMPTR,FLD,0))=0 DO GOTO PS1DN
|
---|
| 213 | . SET RESULT="-1^Field ["_FLD_"] was not found in file ["_+FNUMPTR_"]"
|
---|
| 214 | FOR DO QUIT:(+STR=0)
|
---|
| 215 | . SET STR=$EXTRACT(STR,$LENGTH(+STR)+1,9999) ;"Strip off field number
|
---|
| 216 | . IF $EXTRACT(STR,1)=":" DO ;"Handle '.02:.99:.01' format, as Fileman does.
|
---|
| 217 | . . SET STR=$$TrimL^TMGSTUTL(STR,":")
|
---|
| 218 | . . IF +STR>0 SET FLD=FLD_":"_+STR
|
---|
| 219 | SET ARRAY("FLD")=FLD
|
---|
| 220 | NEW FLDTYPE SET FLDTYPE=$PIECE(^DD(+FNUMPTR,+FLD,0),"^",2)
|
---|
| 221 | IF (FLD[":"),(FLDTYPE'["P") DO GOTO PS1DN
|
---|
| 222 | . SET RESULT="-1^Found fields ["_FLD_"], however field "_+FLD_" is not a pointer in file "_FILENUM
|
---|
| 223 | IF FLDTYPE["M" DO GOTO PS1DN
|
---|
| 224 | . SET RESULT="-1^Searches in fields that are MULTIPLES not supported"
|
---|
| 225 | NEW COMP SET COMP=$PIECE(STR,"""",1)
|
---|
| 226 | SET COMP=$$UP^XLFSTR($$TRIM^XLFSTR(COMP))
|
---|
| 227 | IF (COMP="!=")!(COMP="<>") SET COMP="'="
|
---|
| 228 | ELSE IF (COMP=">=") SET COMP="'<"
|
---|
| 229 | ELSE IF (COMP="<=") SET COMP="'>"
|
---|
| 230 | NEW NOT SET NOT=$EXTRACT(COMP,1) IF NOT'="'" SET NOT=""
|
---|
| 231 | IF (COMP="=")!(COMP="[")!(COMP="IN")!(COMP="<")!(COMP=">") DO
|
---|
| 232 | . SET ARRAY("COMP")=NOT_COMP
|
---|
| 233 | ELSE DO GOTO PS1DN
|
---|
| 234 | . SET RESULT="-1^Comparator ["_COMP_"] is not valid"
|
---|
| 235 | NEW SRCH SET SRCH=$PIECE(STR,"""",2,999) ;"Will strip off opening quotes
|
---|
| 236 | IF $EXTRACT(SRCH,$LENGTH(SRCH))="""" SET SRCH=$EXTRACT(SRCH,1,$LENGTH(SRCH)-1) ;"Strip closing quote
|
---|
| 237 | IF FLDTYPE["D" DO ;"Convert search value into a FM date (internal format)
|
---|
| 238 | . NEW ADATE SET ADATE=SRCH
|
---|
| 239 | . NEW TEMPRSLT SET TEMPRSLT=""
|
---|
| 240 | . FOR QUIT:(ADATE="")!(+RESULT=-1) DO
|
---|
| 241 | . . NEW X,Y,%DT
|
---|
| 242 | . . SET %DT="T"
|
---|
| 243 | . . SET X=$PIECE(ADATE,"..",1)
|
---|
| 244 | . . SET ADATE=$PIECE(ADATE,"..",2)
|
---|
| 245 | . . DO ^%DT
|
---|
| 246 | . . IF Y=-1 DO QUIT
|
---|
| 247 | . . . SET RESULT="-1^Invalid date: ["_X_"]"
|
---|
| 248 | . . . SET SRCH="",ADATE=""
|
---|
| 249 | . . IF TEMPRSLT'="" SET TEMPRSLT=TEMPRSLT_".."
|
---|
| 250 | . . SET TEMPRSLT=TEMPRSLT_Y
|
---|
| 251 | . SET SRCH=TEMPRSLT
|
---|
| 252 | ELSE IF FLDTYPE["S" DO ;"Convert FM SET type into internal format
|
---|
| 253 | . NEW OUT,TMGMSG
|
---|
| 254 | . DO VAL^DIE(+FNUMPTR,"+1,",FLD,"E",SRCH,.OUT,,"TMGMSG")
|
---|
| 255 | . SET SRCH=$GET(OUT)
|
---|
| 256 | IF SRCH'="" SET ARRAY("SRCH")=SRCH
|
---|
| 257 | ELSE DO GOTO PS1DN
|
---|
| 258 | . SET RESULT="-1^Search value is invalid"
|
---|
| 259 | ;
|
---|
| 260 | PS1DN IF +RESULT=-1 SET RESULT=RESULT_", found in ["_SAV_"]"
|
---|
| 261 | QUIT RESULT
|
---|
| 262 | ;
|
---|
| 263 | SRCHSUB(RESULT,TERMS) ;
|
---|
| 264 | ;"Purpose: A search function, to support calls by RPC from CPRS
|
---|
| 265 | ;"Input: RESULT-- Pass by reference. AN OUT PARAMETER.
|
---|
| 266 | ;" TERMS -- Pass by reference. Contains search terms. Format
|
---|
| 267 | ;" TERMS("FILE")=FileNumber
|
---|
| 268 | ;" TERMS(Field)=Comparator^SearchValue
|
---|
| 269 | ;" TERMS(Field)=Comparator^SearchValue
|
---|
| 270 | ;" -- Allowed Comparators: "=","[","<",
|
---|
| 271 | ;"Results: RESULT is filled in. Format:
|
---|
| 272 | ;" RESULT(0)=1 for success, or -1^Error Message
|
---|
| 273 | ;" RESULT(IEN)=""
|
---|
| 274 | ;" RESULT(IEN)=""
|
---|
| 275 | ;"NOTE: When multiple fields are specfied, then search results will combine terms
|
---|
| 276 | ;" in an AND fashion. I.e. results only returned that match ALL specified terms.
|
---|
| 277 | ;
|
---|
| 278 | QUIT
|
---|