diff --git a/all.sas b/all.sas index 09a0b79..4d5a5eb 100644 --- a/all.sas +++ b/all.sas @@ -14405,6 +14405,176 @@ run; %inc &fref1; %mend mmx_spkexport;/** + @file + @brief Send data to/from @sasjs/server + @details This macro should be added to the start of each web service, + **immediately** followed by a call to: + + %ms_webout(FETCH) + + This will read all the input data and create same-named SAS datasets in the + WORK library. You can then insert your code, and send data back using the + following syntax: + + data some datasets; * make some data ; + retain some columns; + run; + + %ms_webout(OPEN) + %ms_webout(ARR,some) * Array format, fast, suitable for large tables ; + %ms_webout(OBJ,datasets) * Object format, easier to work with ; + %ms_webout(CLOSE) + + + @param action Either FETCH, OPEN, ARR, OBJ or CLOSE + @param ds The dataset to send back to the frontend + @param dslabel= value to use instead of the real name for sending to JSON + @param fmt=(Y) Set to N to send back unformatted values + @param fref=(_webout) The fileref to which to write the JSON + +

SAS Macros

+ @li mp_jsonout.sas + @li mf_getuser.sas + +

Related Macros

+ @li mv_webout.sas + @li mm_webout.sas + + @version 9.3 + @author Allan Bowe + +**/ + +%macro ms_webout(action,ds,dslabel=,fref=_webout,fmt=Y); +%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug + sasjs_tables; + +%local i tempds; +%let action=%upcase(&action); + +%if &action=FETCH %then %do; + %if %str(&_debug) ge 131 %then %do; + options mprint notes mprintnest; + %end; + %let _webin_file_count=%eval(&_webin_file_count+0); + /* now read in the data */ + %do i=1 %to &_webin_file_count; + %if &_webin_file_count=1 %then %do; + %let _webin_fileref1=&_webin_fileref; + %let _webin_name1=&_webin_name; + %end; + data _null_; + infile &&_webin_fileref&i termstr=crlf; + input; + call symputx('input_statement',_infile_); + putlog "&&_webin_name&i input statement: " _infile_; + stop; + data &&_webin_name&i; + infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding='utf-8'; + input &input_statement; + %if %str(&_debug) ge 131 %then %do; + if _n_<20 then putlog _infile_; + %end; + run; + %let sasjs_tables=&sasjs_tables &&_webin_name&i; + %end; +%end; + +%else %if &action=OPEN %then %do; + /* fix encoding */ + OPTIONS NOBOMFILE; + + /* setup json */ + data _null_;file &fref encoding='utf-8'; + %if %str(&_debug) ge 131 %then %do; + put '>>weboutBEGIN<<'; + %end; + put '{"SYSDATE" : "' "&SYSDATE" '"'; + put ',"SYSTIME" : "' "&SYSTIME" '"'; + run; + +%end; + +%else %if &action=ARR or &action=OBJ %then %do; + %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref + ,engine=DATASTEP,dbg=%str(&_debug) + ) +%end; +%else %if &action=CLOSE %then %do; + %if %str(&_debug) ge 131 %then %do; + /* if debug mode, send back first 10 records of each work table also */ + options obs=10; + data;run;%let tempds=%scan(&syslast,2,.); + ods output Members=&tempds; + proc datasets library=WORK memtype=data; + %local wtcnt;%let wtcnt=0; + data _null_; + set &tempds; + if not (upcase(name) =:"DATA"); /* ignore temp datasets */ + i+1; + call symputx('wt'!!left(i),name,'l'); + call symputx('wtcnt',i,'l'); + data _null_; file &fref mod encoding='utf-8'; + put ",""WORK"":{"; + %do i=1 %to &wtcnt; + %let wt=&&wt&i; + proc contents noprint data=&wt + out=_data_ (keep=name type length format:); + run;%let tempds=%scan(&syslast,2,.); + data _null_; file &fref mod encoding='utf-8'; + dsid=open("WORK.&wt",'is'); + nlobs=attrn(dsid,'NLOBS'); + nvars=attrn(dsid,'NVARS'); + rc=close(dsid); + if &i>1 then put ','@; + put " ""&wt"" : {"; + put '"nlobs":' nlobs; + put ',"nvars":' nvars; + %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP) + %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP) + data _null_; file &fref mod encoding='utf-8'; + put "}"; + %end; + data _null_; file &fref mod encoding='utf-8'; + put "}"; + run; + %end; + /* close off json */ + data _null_;file &fref mod encoding='utf-8'; + _PROGRAM=quote(trim(resolve(symget('_PROGRAM')))); + put ",""SYSUSERID"" : ""&sysuserid"" "; + put ",""MF_GETUSER"" : ""%mf_getuser()"" "; + put ",""_DEBUG"" : ""&_debug"" "; + put ',"_PROGRAM" : ' _PROGRAM ; + put ",""SYSCC"" : ""&syscc"" "; + put ",""SYSERRORTEXT"" : ""&syserrortext"" "; + SYSHOSTINFOLONG=quote(trim(symget('SYSHOSTINFOLONG'))); + put ',"SYSHOSTINFOLONG" : ' SYSHOSTINFOLONG; + put ",""SYSHOSTNAME"" : ""&syshostname"" "; + put ",""SYSPROCESSID"" : ""&SYSPROCESSID"" "; + put ",""SYSPROCESSMODE"" : ""&SYSPROCESSMODE"" "; + put ",""SYSPROCESSNAME"" : ""&SYSPROCESSNAME"" "; + put ",""SYSJOBID"" : ""&sysjobid"" "; + put ",""SYSSCPL"" : ""&sysscpl"" "; + put ",""SYSSITE"" : ""&syssite"" "; + put ",""SYSTCPIPHOSTNAME"" : ""&SYSTCPIPHOSTNAME"" "; + sysvlong=quote(trim(symget('sysvlong'))); + put ',"SYSVLONG" : ' sysvlong; + put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; + put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" '; + autoexec=quote(trim(getoption('autoexec'))); + put ',"AUTOEXEC" : ' autoexec; + memsize="%sysfunc(INPUTN(%sysfunc(getoption(memsize)), best.),sizekmg.)"; + put ',"MEMSIZE" : ' memsize; + put "}" @; + %if %str(&_debug) ge 131 %then %do; + put '>>weboutEND<<'; + %end; + run; +%end; + +%mend ms_webout; +/** @file @brief Checks whether a file exists in SAS Drive @details Returns 1 if the file exists, and 0 if it doesn't. Works by @@ -20080,6 +20250,9 @@ run; @param [out] pkg= (utils) The output package in which to create the function. Uses a 3 part format: libref.catalog.package +

SAS Macros

+ @li mf_existfunction.sas + **/ %macro mcf_stpsrv_header(wrap=NO @@ -20089,6 +20262,8 @@ run; ,pkg=UTILS )/*/STORE SOURCE*/; +%if %mf_existfunction(stpsrv_header)=1 %then %return; + %if &wrap=YES %then %do; proc fcmp outcat=&lib..&cat..&pkg; %end; diff --git a/fcmp/mcf_stpsrv_header.sas b/fcmp/mcf_stpsrv_header.sas index 3f00d17..e8d3e5d 100644 --- a/fcmp/mcf_stpsrv_header.sas +++ b/fcmp/mcf_stpsrv_header.sas @@ -54,6 +54,9 @@ @param [out] pkg= (utils) The output package in which to create the function. Uses a 3 part format: libref.catalog.package +

SAS Macros

+ @li mf_existfunction.sas + **/ %macro mcf_stpsrv_header(wrap=NO @@ -63,6 +66,8 @@ ,pkg=UTILS )/*/STORE SOURCE*/; +%if %mf_existfunction(stpsrv_header)=1 %then %return; + %if &wrap=YES %then %do; proc fcmp outcat=&lib..&cat..&pkg; %end;