57%macro ms_createwebservice(path=0
61 ,desc=Not currently used
66%
if &mdebug=1 %then %
do;
67 %put &sysmacroname entry vars:;
72%mp_abort(iftrue=(&syscc ge 4 )
73 ,mac=ms_createwebservice
74 ,msg=%str(syscc=&syscc on macro entry)
76%mp_abort(iftrue=(
"&path"=
"0")
77 ,mac=ms_createwebservice
78 ,msg=%str(Path not provided)
82%
if "%substr(&path,%length(&path),1)" =
"/" %then
83 %let path=%substr(&path,1,%length(&path)-1);
91%let sasjsref=%mf_getuniquefileref();
93 file &sasjsref termstr=crlf lrecl=512;
94 put
"/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
96 put
'%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y ';
97 put
' ,engine=DATASTEP ';
98 put
' ,missing=NULL ';
101 put
')/*/STORE SOURCE*/; ';
102 put
'%local tempds colinfo fmtds i numcols numobs stmt_obs lastobs optval ';
103 put
' tmpds1 tmpds2 tmpds3 tmpds4; ';
104 put
'%let numcols=0; ';
105 put
'%if &maxobs ne MAX %then %let stmt_obs=%str(if _n_>&maxobs then stop;); ';
107 put
'%if &action=OPEN %then %do; ';
108 put
' options nobomfile; ';
109 put
' data _null_;file &jref encoding=''utf-8'' lrecl=200; ';
110 put
' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
113 put
'%else %if (&action=ARR or &action=OBJ) %then %do; ';
114 put
' /* force variable names to always be uppercase in the JSON */ ';
115 put
' options validvarname=upcase; ';
116 put
' /* To avoid issues with _webout on EBI - such as encoding diffs and truncation ';
117 put
' (https://support.sas.com/kb/49/325.html) we use temporary files */ ';
118 put
' filename _sjs1 temp lrecl=200 ; ';
119 put
' data _null_; file _sjs1 encoding=''utf-8''; ';
120 put
' put ", ""%lowcase(%sysfunc(coalescec(&dslabel,&ds)))"":"; ';
122 put
' /* now write to _webout 1 char at a time */ ';
123 put
' data _null_; ';
124 put
' infile _sjs1 lrecl=1 recfm=n; ';
125 put
' file &jref mod lrecl=1 recfm=n; ';
126 put
' input sourcechar $char1. @@; ';
127 put
' format sourcechar hex2.; ';
128 put
' put sourcechar char1. @@; ';
130 put
' filename _sjs1 clear; ';
132 put
' /* grab col defs */ ';
133 put
' proc contents noprint data=&ds ';
134 put
' out=_data_(keep=name type length format formatl formatd varnum label); ';
136 put
' %let colinfo=%scan(&syslast,2,.); ';
137 put
' proc sort data=&colinfo; ';
140 put
' /* move meta to mac vars */ ';
141 put
' data &colinfo; ';
142 put
' if _n_=1 then call symputx(''numcols'',nobs,''l''); ';
143 put
' set &colinfo end=last nobs=nobs; ';
144 put
' name=upcase(name); ';
145 put
' /* fix formats */ ';
146 put
' if type=2 or type=6 then do; ';
147 put
' typelong=''char''; ';
148 put
' length fmt $49.; ';
149 put
' if format='''' then fmt=cats(
''$
'',length,
''.
'');
';
150 put ' else if formatl=0 then fmt=cats(format,
''.
'');
';
151 put ' else fmt=cats(format,formatl,
''.
'');
';
154 put ' typelong=
''num
'';
';
155 put ' if format=
'''' then fmt=''best.''; ';
156 put
' else if formatl=0 then fmt=cats(format,''.''); ';
157 put
' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
158 put
' else fmt=cats(format,formatl,''.'',formatd); ';
160 put
' /* 32 char unique name */ ';
161 put
' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
163 put
' call symputx(cats(''name'',_n_),name,''l''); ';
164 put
' call symputx(cats(''newname'',_n_),newname,''l''); ';
165 put
' call symputx(cats(''length'',_n_),length,''l''); ';
166 put
' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
167 put
' call symputx(cats(''type'',_n_),type,''l''); ';
168 put
' call symputx(cats(''typelong'',_n_),typelong,''l''); ';
169 put
' call symputx(cats(''label'',_n_),coalescec(label,name),''l''); ';
170 put
' /* overwritten when fmt=Y and a custom format exists in catalog */ ';
171 put
' if typelong=''num'' then call symputx(cats(''fmtlen'',_n_),200,''l''); ';
172 put
' else call symputx(cats(''fmtlen'',_n_),min(32767,ceil((length+10)*1.5)),''l''); ';
175 put
' %let tempds=%substr(_%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
176 put
' proc sql noprint; ';
177 put
' select count(*) into: lastobs from &ds; ';
178 put
' %if &maxobs ne MAX %then %let lastobs=%sysfunc(min(&lastobs,&maxobs)); ';
180 put
' %if &engine=PROCJSON %then %do; ';
181 put
' %if &missing=STRING %then %do; ';
182 put
' %put &sysmacroname: Special Missings not supported in proc json.; ';
183 put
' %put &sysmacroname: Switching to DATASTEP engine; ';
184 put
' %goto datastep; ';
186 put
' data &tempds; ';
189 put
' %if &fmt=N %then format _numeric_ best32.;; ';
190 put
' /* PRETTY is necessary to avoid line truncation in large files */ ';
191 put
' filename _sjs2 temp lrecl=131068 encoding=''utf-8''; ';
192 put
' proc json out=_sjs2 pretty ';
193 put
' %if &action=ARR %then nokeys ; ';
194 put
' ;export &tempds / nosastags fmtnumeric; ';
196 put
' /* send back to webout */ ';
197 put
' data _null_; ';
198 put
' infile _sjs2 lrecl=1 recfm=n; ';
199 put
' file &jref mod lrecl=1 recfm=n; ';
200 put
' input sourcechar $char1. @@; ';
201 put
' format sourcechar hex2.; ';
202 put
' put sourcechar char1. @@; ';
204 put
' filename _sjs2 clear; ';
206 put
' %else %if &engine=DATASTEP %then %do; ';
208 put
' %if %sysfunc(exist(&ds)) ne 1 & %sysfunc(exist(&ds,VIEW)) ne 1 ';
210 put
' %put &sysmacroname: &ds NOT FOUND!!!; ';
214 put
' %if &fmt=Y %then %do; ';
216 put
' * Extract format definitions ';
217 put
' * First, by getting library locations from dictionary.formats ';
218 put
' * Then, by exporting the width using proc format ';
219 put
' * Cannot use maxw from sashelp.vformat as not always populated ';
220 put
' * Cannot use fmtinfo() as not supported in all flavours ';
222 put
' %let tmpds1=%substr(fmtsum%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
223 put
' %let tmpds2=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
224 put
' %let tmpds3=%substr(cntl%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
225 put
' %let tmpds4=%substr(col%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32); ';
226 put
' proc sql noprint; ';
227 put
' create table &tmpds1 as ';
228 put
' select cats(libname,''.'',memname) as FMTCAT, ';
230 put
' from dictionary.formats ';
231 put
' where fmttype=''F'' and libname is not null ';
232 put
' and fmtname in (select format from &colinfo where format is not null) ';
234 put
' create table &tmpds2( ';
235 put
' FMTNAME char(32), ';
238 put
' %local catlist cat fmtlist i; ';
239 put
' select distinct fmtcat into: catlist separated by '' '' from &tmpds1; ';
240 put
' %do i=1 %to %sysfunc(countw(&catlist,%str( ))); ';
241 put
' %let cat=%scan(&catlist,&i,%str( )); ';
243 put
' select distinct fmtname into: fmtlist separated by '' '' ';
244 put
' from &tmpds1 where fmtcat="&cat"; ';
245 put
' proc format lib=&cat cntlout=&tmpds3(keep=fmtname length); ';
246 put
' select &fmtlist; ';
249 put
' insert into &tmpds2 select distinct fmtname,length from &tmpds3; ';
253 put
' create table &tmpds4 as ';
254 put
' select a.*, b.length as MAXW ';
255 put
' from &colinfo a ';
256 put
' left join &tmpds2 b ';
257 put
' on cats(a.format)=cats(upcase(b.fmtname)) ';
258 put
' order by a.varnum; ';
259 put
' data _null_; ';
260 put
' set &tmpds4; ';
261 put
' if not missing(maxw); ';
262 put
' call symputx( ';
263 put
' cats(''fmtlen'',_n_), ';
264 put
' /* vars need extra padding due to JSON escaping of special chars */ ';
265 put
' min(32767,ceil((max(length,maxw)+10)*1.5)) ';
270 put
' /* configure varlenchk - as we are explicitly shortening the variables */ ';
271 put
' %let optval=%sysfunc(getoption(varlenchk)); ';
272 put
' options varlenchk=NOWARN; ';
273 put
' data _data_(compress=char); ';
274 put
' /* shorten the new vars */ ';
276 put
' %do i=1 %to &numcols; ';
277 put
' &&name&i $&&fmtlen&i ';
280 put
' /* rename on entry */ ';
281 put
' set &ds(rename=( ';
282 put
' %do i=1 %to &numcols; ';
283 put
' &&name&i=&&newname&i ';
289 put
' %do i=1 %to &numcols; ';
293 put
' %do i=1 %to &numcols; ';
294 put
' %if &&typelong&i=num %then %do; ';
295 put
' &&name&i=cats(put(&&newname&i,&&fmt&i)); ';
298 put
' &&name&i=put(&&newname&i,&&fmt&i); ';
301 put
' if _error_ then do; ';
302 put
' call symputx(''syscc'',1012); ';
306 put
' %let fmtds=&syslast; ';
307 put
' options varlenchk=&optval; ';
310 put
' proc format; /* credit yabwon for special null removal */ ';
311 put
' value bart (default=40) ';
312 put
' %if &missing=NULL %then %do; ';
313 put
' ._ - .z = null ';
316 put
' ._ = [quote()] ';
318 put
' .a - .z = [quote()] ';
320 put
' other = [best.]; ';
322 put
' data &tempds; ';
323 put
' attrib _all_ label='''';
';
324 put ' %
do i=1 %to &numcols;
';
325 put ' %
if &&typelong&i=
char or &fmt=Y %then %
do;
';
326 put ' length &&name&i $&&fmtlen&i...;
';
327 put ' format &&name&i $&&fmtlen&i...;
';
330 put ' %
if &fmt=Y %then %
do;
';
337 put ' format _numeric_ bart.;
';
338 put ' %
do i=1 %to &numcols;
';
339 put ' %
if &&typelong&i=
char or &fmt=Y %then %
do;
';
340 put ' if findc(&&name&i,
''"\''!!''0A0D09000E0F010210111A''x) then do; ';
341 put ' &&name&i=''"''!!trim(
';
342 put ' prxchange(
''s/
"/\\"/
'',-1,
';
343 put ' prxchange(
''s/\x0A/\n/
'',-1,
';
344 put ' prxchange(
''s/\x0D/\r/
'',-1,
';
345 put ' prxchange(
''s/\x09/\\t/
'',-1,
';
346 put ' prxchange(
''s/\x00/\\u0000/
'',-1,
';
347 put ' prxchange(
''s/\x0E/\\u000E/
'',-1,
';
348 put ' prxchange(
''s/\x0F/\\u000F/
'',-1,
';
349 put ' prxchange(
''s/\x01/\\u0001/
'',-1,
';
350 put ' prxchange(
''s/\x02/\\u0002/
'',-1,
';
351 put ' prxchange(
''s/\x10/\\u0010/
'',-1,
';
352 put ' prxchange(
''s/\x11/\\u0011/
'',-1,
';
353 put ' prxchange(
''s/\x1A/\\u001A/
'',-1,
';
354 put ' prxchange(
''s/\\/\\\\/
'',-1,&&name&i)
';
355 put ' )))))))))))))!!
''"''; ';
357 put ' /* trim (not cats) so leading blanks are retained */ ';
358 put ' else &&name&i=''"''!!trim(&&name&i)!!
''"''; ';
363 put ' filename _sjs3 temp lrecl=131068 ; ';
364 put ' data _null_; ';
365 put ' file _sjs3 encoding=''utf-8''; ';
366 put ' if _n_=1 then put "[
"; ';
367 put ' set &tempds; ';
368 put ' if _n_>1 then put ",
" @; put ';
369 put ' %if &action=ARR %then "[
" ; %else "{
" ; ';
370 put ' %do i=1 %to &numcols; ';
371 put ' %if &i>1 %then ",
" ; ';
372 put ' %if &action=OBJ %then """&&name&i
"":
" ; ';
373 put ' "&&name&i
"n /* name literal for reserved variable names */ ';
375 put ' %if &action=ARR %then "]
" ; %else "}
" ; ; ';
377 put ' /* close out the table */ ';
378 put ' data _null_; ';
379 put ' file _sjs3 mod encoding=''utf-8''; ';
382 put ' data _null_; ';
383 put ' infile _sjs3 lrecl=1 recfm=n; ';
384 put ' file &jref mod lrecl=1 recfm=n; ';
385 put ' input sourcechar $char1. @@; ';
386 put ' format sourcechar hex2.; ';
387 put ' put sourcechar char1. @@; ';
389 put ' filename _sjs3 clear; ';
393 put ' drop table &colinfo, &tempds; ';
395 put ' %if %substr(&showmeta,1,1)=Y %then %do; ';
396 put ' filename _sjs4 temp lrecl=131068 encoding=''utf-8''; ';
397 put ' data _null_; ';
399 put ' length label $350; ';
400 put ' put ",
""$%lowcase(%sysfunc(coalescec(&dslabel,&ds)))
"":{
""vars
"":{
"; ';
401 put ' do i=1 to &numcols; ';
402 put ' name=quote(trim(symget(cats(''name'',i)))); ';
403 put ' format=quote(trim(symget(cats(''fmt'',i)))); ';
404 put ' label=quote(prxchange(''s/\\/\\\\/'',-1,trim(symget(cats(''label'',i))))); ';
405 put ' length=quote(trim(symget(cats(''length'',i)))); ';
406 put ' type=quote(trim(symget(cats(''typelong'',i)))); ';
407 put ' if i>1 then put ",
" @@; ';
408 put ' put name '':{"format
":'' format '',"label
":'' label ';
409 put ' '',"length
":'' length '',"type
":'' type ''}''; ';
413 put ' /* send back to webout */ ';
414 put ' data _null_; ';
415 put ' infile _sjs4 lrecl=1 recfm=n; ';
416 put ' file &jref mod lrecl=1 recfm=n; ';
417 put ' input sourcechar $char1. @@; ';
418 put ' format sourcechar hex2.; ';
419 put ' put sourcechar char1. @@; ';
421 put ' filename _sjs4 clear; ';
425 put '%else %if &action=CLOSE %then %do; ';
426 put ' data _null_; file &jref encoding=''utf-8'' mod ; ';
430 put '%mend mp_jsonout; ';
432 put '%macro mf_getuser( ';
433 put ')/*/STORE SOURCE*/; ';
434 put ' %local user; ';
436 put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
437 put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
438 put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
440 put ' %else %if %symexist(_metaperson) %then %do; ';
441 put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
442 put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
443 put ' /* but be sure to quote in case of usernames with commas */ ';
444 put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
446 put ' %else %let user=&sysuserid; ';
448 put ' %quote(&user) ';
450 put '%mend mf_getuser; ';
452 put '%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=N,missing=NULL ';
453 put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
455 put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
456 put ' sasjs_tables; ';
458 put '%local i tempds; ';
459 put '%let action=%upcase(&action); ';
461 put '%if &action=FETCH %then %do; ';
462 put ' %if %str(&_debug) ge 131 %then %do; ';
463 put ' options mprint notes mprintnest; ';
465 put ' %let _webin_file_count=%eval(&_webin_file_count+0); ';
466 put ' /* now read in the data */ ';
467 put ' %do i=1 %to &_webin_file_count; ';
468 put ' %if &_webin_file_count=1 %then %do; ';
469 put ' %let _webin_fileref1=&_webin_fileref; ';
470 put ' %let _webin_name1=&_webin_name; ';
472 put ' data _null_; ';
473 put ' infile &&_webin_fileref&i termstr=crlf lrecl=32767; ';
475 put ' /* a plain $ informat strips leading blanks - use $char instead */ ';
476 put ' call symputx(''input_statement'' ';
477 put ' ,prxchange(''s/:\$(?=[0-9 ])/:\$char/i'',-1,_infile_) ';
479 put ' putlog "&&_webin_name&i input statement:
" _infile_; ';
481 put ' data &&_webin_name&i; ';
482 put ' infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding=''utf-8'' ';
483 put ' lrecl=32767; ';
484 put ' input &input_statement; ';
485 put ' %if %str(&_debug) ge 131 %then %do; ';
486 put ' if _n_<20 then putlog _infile_; ';
489 put ' %let sasjs_tables=&sasjs_tables &&_webin_name&i; ';
493 put '%else %if &action=OPEN %then %do; ';
494 put ' /* fix encoding and ensure enough lrecl */ ';
495 put ' OPTIONS NOBOMFILE lrecl=32767; ';
497 put ' /* set the header */ ';
498 put ' %mfs_httpheader(Content-type,application/json) ';
500 put ' /* setup json. */ ';
501 put ' data _null_;file &fref encoding=''utf-8'' termstr=lf ; ';
502 put ' put ''{"SYSDATE
" : "'' "&SYSDATE" ''"''; ';
503 put ' put '',"SYSTIME
" : "'' "&SYSTIME" ''"''; ';
508 put '%else %if &action=ARR or &action=OBJ %then %do; ';
509 put ' %if "%substr(&sysver,1,1)
"="4
" or "%substr(&sysver,1,1)
"="5
" %then %do; ';
510 put ' /* functions in formats unsupported */ ';
511 put ' %put &sysmacroname: forcing missing back to NULL as feature not supported; ';
512 put ' %let missing=NULL; ';
514 put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
515 put ' ,engine=DATASTEP,missing=&missing,showmeta=&showmeta,maxobs=&maxobs ';
518 put '%else %if &action=CLOSE %then %do; ';
519 put ' %if %str(&workobs) > 0 %then %do; ';
520 put ' /* if debug mode, send back first XX records of each work table also */ ';
521 put ' data;run;%let tempds=%scan(&syslast,2,.); ';
522 put ' ods output Members=&tempds; ';
523 put ' proc datasets library=WORK memtype=data; ';
524 put ' %local wtcnt;%let wtcnt=0; ';
525 put ' data _null_; ';
526 put ' set &tempds; ';
527 put ' if not (upcase(name) =:"DATA
"); /* ignore temp datasets */ ';
528 put ' if not (upcase(name)=:"_DATA_
"); ';
530 put ' call symputx(cats(''wt'',i),name,''l''); ';
531 put ' call symputx(''wtcnt'',i,''l''); ';
532 put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
533 put ' put ",
""WORK
"":{
"; ';
534 put ' %do i=1 %to &wtcnt; ';
535 put ' %let wt=&&wt&i; ';
536 put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
537 put ' dsid=open("WORK.&wt
",''is''); ';
538 put ' nlobs=attrn(dsid,''NLOBS''); ';
539 put ' nvars=attrn(dsid,''NVARS''); ';
540 put ' rc=close(dsid); ';
541 put ' if &i>1 then put '',''@; ';
542 put ' put " ""&wt
"" : {
"; ';
543 put ' put ''"nlobs
":'' nlobs; ';
544 put ' put '',"nvars
":'' nvars; ';
545 put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,showmeta=Y ';
546 put ' ,maxobs=&workobs ';
548 put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
551 put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
555 put ' /* close off json */ ';
556 put ' data _null_;file &fref mod encoding=''utf-8'' termstr=lf lrecl=32767; ';
557 put ' length SYSPROCESSNAME syserrortext syswarningtext autoexec $512; ';
558 put ' put ",
""_DEBUG
"" :
""&_debug
"" "; ';
559 put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
560 put ' put '',"_PROGRAM
" : '' _PROGRAM ; ';
561 put ' autoexec=quote(urlencode(trim(getoption(''autoexec'')))); ';
562 put ' put '',"AUTOEXEC
" : '' autoexec; ';
563 put ' put ",
""MF_GETUSER
"" :
""%mf_getuser()
"" "; ';
564 put ' put ",
""SYSCC
"" :
""&syscc
"" "; ';
565 put ' put ",
""SYSENCODING
"" :
""&sysencoding
"" "; ';
566 put ' syserrortext=cats(symget(''syserrortext'')); ';
567 put ' if findc(syserrortext,''"\
''!!
''0A0D09000E0F010210111A
''x) then
do;
';
568 put ' syserrortext=
''"''!!trim( ';
569 put ' prxchange(''s/"/\\
"/'',-1, /* double quote */ ';
570 put ' prxchange(''s/\x0A/\n/'',-1, /* new line */ ';
571 put ' prxchange(''s/\x0D/\r/'',-1, /* carriage return */ ';
572 put ' prxchange(''s/\x09/\\t/'',-1, /* tab */ ';
573 put ' prxchange(''s/\x00/\\u0000/'',-1, /* NUL */ ';
574 put ' prxchange(''s/\x0E/\\u000E/'',-1, /* SS */ ';
575 put ' prxchange(''s/\x0F/\\u000F/'',-1, /* SF */ ';
576 put ' prxchange(''s/\x01/\\u0001/'',-1, /* SOH */ ';
577 put ' prxchange(''s/\x02/\\u0002/'',-1, /* STX */ ';
578 put ' prxchange(''s/\x10/\\u0010/'',-1, /* DLE */ ';
579 put ' prxchange(''s/\x11/\\u0011/'',-1, /* DC1 */ ';
580 put ' prxchange(''s/\x1A/\\u001A/'',-1, /* SUB */ ';
581 put ' prxchange(''s/\\/\\\\/'',-1,syserrortext) ';
582 put ' )))))))))))))!!''"'';
';
584 put ' else syserrortext=cats(
''"'',syserrortext,''"'');
';
585 put ' put
'',
"SYSERRORTEXT" :
'' syserrortext;
';
586 put ' SYSHOSTINFOLONG=quote(trim(symget(
''SYSHOSTINFOLONG
'')));
';
587 put ' put
'',
"SYSHOSTINFOLONG" :
'' SYSHOSTINFOLONG;
';
588 put ' put
",""SYSHOSTNAME"" : ""&syshostname"" ";
';
589 put ' put
",""SYSPROCESSID"" : ""&SYSPROCESSID"" ";
';
590 put ' put
",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" ";
';
591 put ' SYSPROCESSNAME=quote(urlencode(cats(SYSPROCESSNAME)));
';
592 put ' put
",""SYSPROCESSNAME"" : " SYSPROCESSNAME;
';
593 put ' put
",""SYSJOBID"" : ""&sysjobid"" ";
';
594 put ' put
",""SYSSCPL"" : ""&sysscpl"" ";
';
595 put ' put
",""SYSSITE"" : ""&syssite"" ";
';
596 put ' put
",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" ";
';
597 put ' put
",""SYSUSERID"" : ""&sysuserid"" ";
';
598 put ' sysvlong=quote(trim(symget(
''sysvlong
'')));
';
599 put ' put
'',
"SYSVLONG" :
'' sysvlong;
';
600 put ' syswarningtext=cats(symget(
''syswarningtext
''));
';
601 put ' if findc(syswarningtext,
''"\''!!''0A0D09000E0F010210111A''x) then do; ';
602 put ' syswarningtext=''"''!!trim(
';
603 put ' prxchange(
''s/
"/\\"/
'',-1,
';
604 put ' prxchange(
''s/\x0A/\n/
'',-1,
';
605 put ' prxchange(
''s/\x0D/\r/
'',-1,
';
606 put ' prxchange(
''s/\x09/\\t/
'',-1,
';
607 put ' prxchange(
''s/\x00/\\u0000/
'',-1,
';
608 put ' prxchange(
''s/\x0E/\\u000E/
'',-1,
';
609 put ' prxchange(
''s/\x0F/\\u000F/
'',-1,
';
610 put ' prxchange(
''s/\x01/\\u0001/
'',-1,
';
611 put ' prxchange(
''s/\x02/\\u0002/
'',-1,
';
612 put ' prxchange(
''s/\x10/\\u0010/
'',-1,
';
613 put ' prxchange(
''s/\x11/\\u0011/
'',-1,
';
614 put ' prxchange(
''s/\x1A/\\u001A/
'',-1,
';
615 put ' prxchange(
''s/\\/\\\\/
'',-1,syswarningtext)
';
616 put ' )))))))))))))!!
''"''; ';
618 put ' else syswarningtext=cats(''"'',syswarningtext,
''"''); ';
619 put ' put '',"SYSWARNINGTEXT
" : '' syswarningtext; ';
620 put ' put '',"END_DTTM
" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''" ''; ';
621 put ' length memsize $32; ';
622 put ' memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)
"; ';
623 put ' memsize=quote(cats(memsize)); ';
624 put ' put '',"MEMSIZE
" : '' memsize; ';
629 put '%mend ms_webout; ';
631 put '%macro mfs_httpheader(header_name ';
632 put ' ,header_value ';
633 put ')/*/STORE SOURCE*/; ';
634 put '%global _sasjs_webout_headers; ';
635 put '%local fref fid i; ';
637 put '%if %sysfunc(filename(fref,&_sasjs_webout_headers)) ne 0 %then %do; ';
638 put ' %put &=fref &=_sasjs_webout_headers; ';
639 put ' %put %str(ERR)OR: %sysfunc(sysmsg()); ';
643 put '%let fid=%sysfunc(fopen(&fref,A)); ';
645 put '%if &fid=0 %then %do; ';
646 put ' %put %str(ERR)OR: %sysfunc(sysmsg()); ';
650 put '%let rc=%sysfunc(fput(&fid,%str(&header_name): %str(&header_value))); ';
651 put '%let rc=%sysfunc(fwrite(&fid)); ';
653 put '%let rc=%sysfunc(fclose(&fid)); ';
654 put '%let rc=%sysfunc(filename(&fref)); ';
656 put '%mend mfs_httpheader; ';
658 put '%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO';
661 put ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing';
662 put ' ,showmeta=&showmeta,maxobs=&maxobs';
667/* add precode and code */
668%local x fref freflist;
669%let freflist=&precode &code ;
670%do x=1 %to %sysfunc(countw(&freflist));
671 %let fref=%scan(&freflist,&x);
672 %put &sysmacroname: adding &fref;
674 file &sasjsref lrecl=3000 termstr=crlf mod;
675 infile &fref lrecl=3000;
681/* create the web service */
682%ms_createfile(&path/&name..sas, inref=&sasjsref, mdebug=&mdebug)
684%put ;%put ;%put ;%put ;%put ;%put ;
685%put &sysmacroname: STP &name successfully created in &path;
687%put Check it out here:;
689%put &_sasjs_apiserverurl.&_sasjs_apipath?_PROGRAM=&path/&name;
690%put ;%put ;%put ;%put ;%put ;%put ;
692%mend ms_createwebservice;