source: cprs/branches/tmg-cprs/m_files/TMGRPC1C.m~@ 796

Last change on this file since 796 was 796, checked in by Kevin Toppenberg, 14 years ago

Initial upload

File size: 15.6 KB
Line 
1TMGRPC1C ;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 ;
26SRCH(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
100SRCHDN QUIT
101 ;
102 ;
103PARSESTR(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 ;
172FNPTR(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 ;
193PARSE1(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 ;
260PS1DN IF +RESULT=-1 SET RESULT=RESULT_", found in ["_SAV_"]"
261 QUIT RESULT
262 ;
263SRCHSUB(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
Note: See TracBrowser for help on using the repository browser.