mirror of
https://github.com/sasjs/core.git
synced 2026-04-18 22:23:12 +00:00
chore: all.sas update
This commit is contained in:
645
all.sas
645
all.sas
@@ -960,15 +960,17 @@ or %index(&pgm,/tests/testteardown)
|
|||||||
be 8 characters, so a 7 letter prefix would mean `maxtries` should be 10.
|
be 8 characters, so a 7 letter prefix would mean `maxtries` should be 10.
|
||||||
if using zero (0) as the prefix, a native assignment is used.
|
if using zero (0) as the prefix, a native assignment is used.
|
||||||
@param [in] maxtries= (1000) the last part of the libref. Must be an integer.
|
@param [in] maxtries= (1000) the last part of the libref. Must be an integer.
|
||||||
|
@param [in] lrecl= (32767) Provide a default lrecl with which to initialise
|
||||||
|
the generated fileref.
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mf_getuniquefileref(prefix=_,maxtries=1000);
|
%macro mf_getuniquefileref(prefix=_,maxtries=1000,lrecl=32767);
|
||||||
%local rc fname;
|
%local rc fname;
|
||||||
%if &prefix=0 %then %do;
|
%if &prefix=0 %then %do;
|
||||||
%let rc=%sysfunc(filename(fname,,temp));
|
%let rc=%sysfunc(filename(fname,,temp,lrecl=&lrecl));
|
||||||
%if &rc %then %put %sysfunc(sysmsg());
|
%if &rc %then %put %sysfunc(sysmsg());
|
||||||
&fname
|
&fname
|
||||||
%end;
|
%end;
|
||||||
@@ -979,7 +981,7 @@ or %index(&pgm,/tests/testteardown)
|
|||||||
%do x=0 %to &maxtries;
|
%do x=0 %to &maxtries;
|
||||||
%let fname=&prefix%substr(%sysfunc(ranuni(0)),3,&len);
|
%let fname=&prefix%substr(%sysfunc(ranuni(0)),3,&len);
|
||||||
%if %sysfunc(fileref(&fname)) > 0 %then %do;
|
%if %sysfunc(fileref(&fname)) > 0 %then %do;
|
||||||
%let rc=%sysfunc(filename(fname,,temp));
|
%let rc=%sysfunc(filename(fname,,temp,lrecl=&lrecl));
|
||||||
%if &rc %then %put %sysfunc(sysmsg());
|
%if &rc %then %put %sysfunc(sysmsg());
|
||||||
&fname
|
&fname
|
||||||
%return;
|
%return;
|
||||||
@@ -1604,8 +1606,11 @@ Usage:
|
|||||||
|
|
||||||
%macro mf_isint(arg
|
%macro mf_isint(arg
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
/* remove minus sign if exists */
|
|
||||||
|
|
||||||
|
/* blank val is not an integer */
|
||||||
|
%if "&arg"="" %then %do;0%return;%end;
|
||||||
|
|
||||||
|
/* remove minus sign if exists */
|
||||||
%local val;
|
%local val;
|
||||||
%if "%substr(%str(&arg),1,1)"="-" %then %let val=%substr(%str(&arg),2);
|
%if "%substr(%str(&arg),1,1)"="-" %then %let val=%substr(%str(&arg),2);
|
||||||
%else %let val=&arg;
|
%else %let val=&arg;
|
||||||
@@ -3441,6 +3446,200 @@ run;
|
|||||||
filename &outref clear;
|
filename &outref clear;
|
||||||
%end;
|
%end;
|
||||||
%mend mp_binarycopy;/**
|
%mend mp_binarycopy;/**
|
||||||
|
@file
|
||||||
|
@brief Splits a file of ANY SIZE by reference to a search string.
|
||||||
|
@details Provide a fileref and a search string to chop off part of a file.
|
||||||
|
|
||||||
|
Works by reading in the file byte by byte, then marking the beginning and end
|
||||||
|
of each matched string, before finally doing the chop.
|
||||||
|
|
||||||
|
Choose whether to keep the FIRST or the LAST section of the file. Optionally,
|
||||||
|
use an OFFSET to fix the precise chop point.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%let src="%sysfunc(pathname(work))/file.txt";
|
||||||
|
%let str=Chop here!;
|
||||||
|
%let out1="%sysfunc(pathname(work))/file1.txt";
|
||||||
|
%let out2="%sysfunc(pathname(work))/file2.txt";
|
||||||
|
%let out3="%sysfunc(pathname(work))/file3.txt";
|
||||||
|
%let out4="%sysfunc(pathname(work))/file4.txt";
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &src;
|
||||||
|
put "startsection&str.endsection";
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_chop(&src, matchvar=str, keep=FIRST, outfile=&out1)
|
||||||
|
%mp_chop(&src, matchvar=str, keep=LAST, outfile=&out2)
|
||||||
|
%mp_chop(&src, matchvar=str, keep=FIRST, matchpoint=END, outfile=&out3)
|
||||||
|
%mp_chop(&src, matchvar=str, keep=LAST, matchpoint=END, outfile=&out4)
|
||||||
|
|
||||||
|
filename results (&out1 &out2 &out3 &out4);
|
||||||
|
data _null_;
|
||||||
|
infile results;
|
||||||
|
input;
|
||||||
|
list;
|
||||||
|
run;
|
||||||
|
|
||||||
|
Results:
|
||||||
|
@li `startsection`
|
||||||
|
@li `Chop here!endsection`
|
||||||
|
@li `startsectionChop here!`
|
||||||
|
@li `endsection`
|
||||||
|
|
||||||
|
For more examples, see mp_chop.test.sas
|
||||||
|
|
||||||
|
@param [in] infile The QUOTED path to the file on which to perform the chop
|
||||||
|
@param [in] matchvar= Macro variable NAME containing the string to split by
|
||||||
|
@param [in] matchpoint= (START) Valid values:
|
||||||
|
@li START - chop at the beginning of the string in `matchvar`.
|
||||||
|
@li END - chop at the end of the string in `matchvar`.
|
||||||
|
@param [in] offset= (0) An adjustment to the precise chop location, by
|
||||||
|
by reference to the `matchpoint`. Should be a positive or negative integer.
|
||||||
|
@param [in] keep= (FIRST) Valid values:
|
||||||
|
@li FIRST - keep the section of the file before the chop
|
||||||
|
@li LAST - keep the section of the file after the chop
|
||||||
|
@param [in] mdebug= (0) Set to 1 to provide macro debugging
|
||||||
|
@param outfile= (0) Optional QUOTED path to the adjusted output file (avoids
|
||||||
|
overwriting the first file).
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mp_abort.sas
|
||||||
|
@li mp_gsubfile.sas
|
||||||
|
@li mp_replace.sas
|
||||||
|
@li mp_chop.test.sas
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_chop(infile,
|
||||||
|
matchvar=,
|
||||||
|
matchpoint=START,
|
||||||
|
keep=FIRST,
|
||||||
|
offset=0,
|
||||||
|
mdebug=0,
|
||||||
|
outfile=0
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%local fref0 dttm ds1 outref;
|
||||||
|
%let fref0=%mf_getuniquefileref();
|
||||||
|
%let ds1=%mf_getuniquename(prefix=allchars);
|
||||||
|
%let ds2=%mf_getuniquename(prefix=startmark);
|
||||||
|
|
||||||
|
%if &outfile=0 %then %let outfile=&infile;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (%length(%superq(&matchvar))=0)
|
||||||
|
,mac=mp_chop.sas
|
||||||
|
,msg=%str(&matchvar is an empty variable)
|
||||||
|
)
|
||||||
|
|
||||||
|
/* START */
|
||||||
|
%let dttm=%sysfunc(datetime());
|
||||||
|
|
||||||
|
filename &fref0 &infile lrecl=1 recfm=n;
|
||||||
|
|
||||||
|
/* create dataset with one char per row */
|
||||||
|
data &ds1;
|
||||||
|
infile &fref0;
|
||||||
|
input sourcechar $char1. @@;
|
||||||
|
format sourcechar hex2.;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* get start & stop position of first matchvar string (one row, two vars) */
|
||||||
|
data &ds2;
|
||||||
|
/* set find string to length in bytes to cover trailing spaces */
|
||||||
|
length string $ %length(%superq(&matchvar));
|
||||||
|
string =symget("&matchvar");
|
||||||
|
drop string;
|
||||||
|
|
||||||
|
firstchar=char(string,1);
|
||||||
|
findlen=lengthm(string); /* <- for trailing bytes */
|
||||||
|
|
||||||
|
do _N_=1 to nobs;
|
||||||
|
set &ds1 nobs=nobs point=_N_;
|
||||||
|
if sourcechar=firstchar then do;
|
||||||
|
pos=1;
|
||||||
|
s=0;
|
||||||
|
do point=_N_ to min(_N_ + findlen -1,nobs);
|
||||||
|
set &ds1 point=point;
|
||||||
|
if sourcechar=char(string, pos) then s + 1;
|
||||||
|
else goto _leave_;
|
||||||
|
pos+1;
|
||||||
|
end;
|
||||||
|
_leave_:
|
||||||
|
if s=findlen then do;
|
||||||
|
START =_N_;
|
||||||
|
_N_ =_N_+ s - 1;
|
||||||
|
STOP =_N_;
|
||||||
|
output;
|
||||||
|
/* matched! */
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
stop;
|
||||||
|
keep START STOP;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%local split;
|
||||||
|
%let split=0;
|
||||||
|
data _null_;
|
||||||
|
set &ds2;
|
||||||
|
if "&matchpoint"='START' then do;
|
||||||
|
if "&keep"='FIRST' then mp=start;
|
||||||
|
else if "&keep"='LAST' then mp=start-1;
|
||||||
|
end;
|
||||||
|
else if "&matchpoint"='END' then do;
|
||||||
|
if "&keep"='FIRST' then mp=stop+1;
|
||||||
|
else if "&keep"='LAST' then mp=stop;
|
||||||
|
end;
|
||||||
|
split=mp+&offset;
|
||||||
|
call symputx('split',split,'l');
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
put (_all_)(=);
|
||||||
|
%put &=offset;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
%if &split=0 %then %do;
|
||||||
|
%put &sysmacroname: No match found in &infile for string %superq(&matchvar);
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &outfile recfm=n;
|
||||||
|
set &ds1;
|
||||||
|
%if &keep=FIRST %then %do;
|
||||||
|
if _n_ ge &split then stop;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
if _n_ gt &split;
|
||||||
|
%end;
|
||||||
|
put sourcechar char1.;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%if &mdebug=0 %then %do;
|
||||||
|
filename &fref0 clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
data _null_;
|
||||||
|
infile &outfile lrecl=32767;
|
||||||
|
input;
|
||||||
|
list;
|
||||||
|
if _n_>50 then stop;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
/* END */
|
||||||
|
%put &sysmacroname took %sysevalf(%sysfunc(datetime())-&dttm) seconds to run;
|
||||||
|
|
||||||
|
%mend mp_chop;
|
||||||
|
/**
|
||||||
@file mp_cleancsv.sas
|
@file mp_cleancsv.sas
|
||||||
@brief Fixes embedded cr / lf / crlf in CSV
|
@brief Fixes embedded cr / lf / crlf in CSV
|
||||||
@details CSVs will sometimes contain lf or crlf within quotes (eg when
|
@details CSVs will sometimes contain lf or crlf within quotes (eg when
|
||||||
@@ -7646,7 +7845,7 @@ create table &outds as
|
|||||||
outfile=0
|
outfile=0
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%if "%substr(&sysver,1,4)"="V.04" %then %do;
|
%if "%substr(&sysver.XX,1,4)"="V.04" %then %do;
|
||||||
%put %str(ERR)OR: Viya 4 does not support the IO library in lua;
|
%put %str(ERR)OR: Viya 4 does not support the IO library in lua;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
@@ -8323,7 +8522,7 @@ options
|
|||||||
|
|
||||||
%if &action=OPEN %then %do;
|
%if &action=OPEN %then %do;
|
||||||
options nobomfile;
|
options nobomfile;
|
||||||
data _null_;file &jref encoding='utf-8' ;
|
data _null_;file &jref encoding='utf-8' lrecl=200;
|
||||||
put '{"PROCESSED_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '"';
|
put '{"PROCESSED_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '"';
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
@@ -9753,7 +9952,7 @@ insert into &outds select distinct * from &append_ds;
|
|||||||
@param infile The QUOTED path to the file on which to perform the substitution
|
@param infile The QUOTED path to the file on which to perform the substitution
|
||||||
@param findvar= Macro variable NAME containing the string to search for
|
@param findvar= Macro variable NAME containing the string to search for
|
||||||
@param replacevar= Macro variable NAME containing the replacement string
|
@param replacevar= Macro variable NAME containing the replacement string
|
||||||
@param outfile= (0) Optional QUOTED path to an the adjusted output file (to
|
@param outfile= (0) Optional QUOTED path to the adjusted output file (to
|
||||||
avoid overwriting the first file).
|
avoid overwriting the first file).
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@@ -9761,7 +9960,9 @@ insert into &outds select distinct * from &append_ds;
|
|||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Macros </h4>
|
||||||
@li mp_gsubfile.test.sas
|
@li mp_chop.sas
|
||||||
|
@li mp_gsubfile.sas
|
||||||
|
@li mp_replace.test.sas
|
||||||
|
|
||||||
@version 9.4
|
@version 9.4
|
||||||
@author Bartosz Jabłoński
|
@author Bartosz Jabłoński
|
||||||
@@ -11855,7 +12056,9 @@ libname &lib clear;
|
|||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mp_binarycopy.sas
|
@li mp_binarycopy.sas
|
||||||
|
@li mp_chop.sas
|
||||||
@li mp_ds2csv.sas
|
@li mp_ds2csv.sas
|
||||||
|
@li ms_testservice.sas
|
||||||
@li mv_getjobresult.sas
|
@li mv_getjobresult.sas
|
||||||
@li mv_jobflow.sas
|
@li mv_jobflow.sas
|
||||||
|
|
||||||
@@ -11878,7 +12081,7 @@ libname &lib clear;
|
|||||||
viyaresult=WEBOUT_JSON,
|
viyaresult=WEBOUT_JSON,
|
||||||
viyacontext=SAS Job Execution compute context
|
viyacontext=SAS Job Execution compute context
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%local dbg pcnt fref1 webref i webcount var platform;
|
%local dbg pcnt fref1 fref2 webref webrefpath i webcount var platform;
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
%put &sysmacroname entry vars:;
|
%put &sysmacroname entry vars:;
|
||||||
%put _local_;
|
%put _local_;
|
||||||
@@ -11919,10 +12122,14 @@ libname &lib clear;
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
|
||||||
%let fref1=%mf_getuniquefileref();
|
|
||||||
%let webref=%mf_getuniquefileref();
|
|
||||||
%let platform=%mf_getplatform();
|
%let platform=%mf_getplatform();
|
||||||
|
%let fref1=%mf_getuniquefileref();
|
||||||
|
%let fref2=%mf_getuniquefileref();
|
||||||
|
%let webref=%mf_getuniquefileref();
|
||||||
|
%let webrefpath=%sysfunc(pathname(work))/%mf_getuniquename();
|
||||||
|
/* mp_chop requires a physical path as input */
|
||||||
|
filename &webref "&webrefpath";
|
||||||
|
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA %then %do;
|
||||||
|
|
||||||
/* parse the input files */
|
/* parse the input files */
|
||||||
@@ -12077,6 +12284,19 @@ libname &lib clear;
|
|||||||
mdebug=&mdebug
|
mdebug=&mdebug
|
||||||
)
|
)
|
||||||
|
|
||||||
|
%end;
|
||||||
|
%else %if &platform=SASJS %then %do;
|
||||||
|
|
||||||
|
%ms_testservice(&program
|
||||||
|
,inputfiles=&inputfiles
|
||||||
|
,inputdatasets=&inputdatasets
|
||||||
|
,inputparams=&inputparams
|
||||||
|
,debug=&debug
|
||||||
|
,mdebug=&mdebug
|
||||||
|
,outlib=&outlib
|
||||||
|
,outref=&outref
|
||||||
|
)
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put %str(ERR)OR: Unrecognised platform: &platform;
|
%put %str(ERR)OR: Unrecognised platform: &platform;
|
||||||
@@ -12084,6 +12304,8 @@ libname &lib clear;
|
|||||||
|
|
||||||
%if &mdebug=0 %then %do;
|
%if &mdebug=0 %then %do;
|
||||||
filename &webref clear;
|
filename &webref clear;
|
||||||
|
filename &fref1 clear;
|
||||||
|
filename &fref2 clear;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put &sysmacroname exit vars:;
|
%put &sysmacroname exit vars:;
|
||||||
@@ -14852,7 +15074,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
put ' options nobomfile; ';
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
put ' data _null_;file &jref encoding=''utf-8'' lrecl=200; ';
|
||||||
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
@@ -18949,6 +19171,7 @@ run;
|
|||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
@li ms_deletefile.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -18957,6 +19180,9 @@ run;
|
|||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* first, delete in case it exists */
|
||||||
|
%ms_deletefile(&driveloc,mdebug=&mdebug)
|
||||||
|
|
||||||
%local fname0 fname1 fname2 boundary fname statcd msg optval;
|
%local fname0 fname1 fname2 boundary fname statcd msg optval;
|
||||||
%let fname0=%mf_getuniquefileref();
|
%let fname0=%mf_getuniquefileref();
|
||||||
%let fname1=%mf_getuniquefileref();
|
%let fname1=%mf_getuniquefileref();
|
||||||
@@ -18968,8 +19194,8 @@ run;
|
|||||||
options nobomfile;
|
options nobomfile;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
file &fname0 termstr=crlf;
|
file &fname0 termstr=crlf lrecl=32767;
|
||||||
infile &inref end=eof;
|
infile &inref end=eof lrecl=32767;
|
||||||
if _n_ = 1 then do;
|
if _n_ = 1 then do;
|
||||||
put "--&boundary.";
|
put "--&boundary.";
|
||||||
put 'Content-Disposition: form-data; name="filePath"';
|
put 'Content-Disposition: form-data; name="filePath"';
|
||||||
@@ -18998,11 +19224,11 @@ run;
|
|||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname0;
|
infile &fname0 lrecl=32767;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname1;
|
infile &fname1 lrecl=32767;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
@@ -19211,7 +19437,7 @@ options &optval;
|
|||||||
For more examples of using these web services with the SASjs Adapter, see:
|
For more examples of using these web services with the SASjs Adapter, see:
|
||||||
https://github.com/sasjs/adapter#readme
|
https://github.com/sasjs/adapter#readme
|
||||||
|
|
||||||
@param [in] path= The full SASjs Drive path in which to create the service
|
@param [in] path= (0) The full SASjs Drive path in which to create the service
|
||||||
@param [in] name= Stored Program name
|
@param [in] name= Stored Program name
|
||||||
@param [in] desc= The description of the service (not implemented yet)
|
@param [in] desc= The description of the service (not implemented yet)
|
||||||
@param [in] precode= Space separated list of filerefs, pointing to the code
|
@param [in] precode= Space separated list of filerefs, pointing to the code
|
||||||
@@ -19224,6 +19450,8 @@ options &optval;
|
|||||||
@li ms_createfile.sas
|
@li ms_createfile.sas
|
||||||
@li mf_getuser.sas
|
@li mf_getuser.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
|
||||||
<h4> Related Files </h4>
|
<h4> Related Files </h4>
|
||||||
@li ms_createwebservice.test.sas
|
@li ms_createwebservice.test.sas
|
||||||
@@ -19233,7 +19461,7 @@ options &optval;
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_createwebservice(path=
|
%macro ms_createwebservice(path=0
|
||||||
,name=initService
|
,name=initService
|
||||||
,precode=
|
,precode=
|
||||||
,code=ft15f001
|
,code=ft15f001
|
||||||
@@ -19241,18 +19469,23 @@ options &optval;
|
|||||||
,mDebug=0
|
,mDebug=0
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%if &syscc ge 4 %then %do;
|
%local dbg;
|
||||||
%put &=syscc - &sysmacroname will not execute in this state;
|
%if &mdebug=1 %then %do;
|
||||||
%return;
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
%end;
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local mD;
|
%mp_abort(iftrue=(&syscc ge 4 )
|
||||||
%if &mDebug=1 %then %let mD=;
|
,mac=ms_createwebservice
|
||||||
%else %let mD=%str(*);
|
,msg=%str(syscc=&syscc on macro entry)
|
||||||
%&mD.put Executing ms_createwebservice.sas;
|
)
|
||||||
%&mD.put _local_;
|
%mp_abort(iftrue=("&path"="0")
|
||||||
|
,mac=ms_createwebservice
|
||||||
|
,msg=%str(Path not provided)
|
||||||
|
)
|
||||||
|
|
||||||
* remove any trailing slash ;
|
/* remove any trailing slash */
|
||||||
%if "%substr(&path,%length(&path),1)" = "/" %then
|
%if "%substr(&path,%length(&path),1)" = "/" %then
|
||||||
%let path=%substr(&path,1,%length(&path)-1);
|
%let path=%substr(&path,1,%length(&path)-1);
|
||||||
|
|
||||||
@@ -19261,9 +19494,10 @@ options &optval;
|
|||||||
* These put statements are auto generated - to change the macro, change the
|
* These put statements are auto generated - to change the macro, change the
|
||||||
* source (ms_webout) and run `build.py`
|
* source (ms_webout) and run `build.py`
|
||||||
*/
|
*/
|
||||||
filename sasjs temp;
|
%local sasjsref;
|
||||||
|
%let sasjsref=%mf_getuniquefileref();
|
||||||
data _null_;
|
data _null_;
|
||||||
file sasjs lrecl=3000 ;
|
file &sasjsref termstr=crlf lrecl=512;
|
||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -19277,7 +19511,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
put ' options nobomfile; ';
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
put ' data _null_;file &jref encoding=''utf-8'' lrecl=200; ';
|
||||||
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
@@ -19529,13 +19763,14 @@ data _null_;
|
|||||||
put ' %let _webin_name1=&_webin_name; ';
|
put ' %let _webin_name1=&_webin_name; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' data _null_; ';
|
put ' data _null_; ';
|
||||||
put ' infile &&_webin_fileref&i termstr=crlf; ';
|
put ' infile &&_webin_fileref&i termstr=crlf lrecl=32767; ';
|
||||||
put ' input; ';
|
put ' input; ';
|
||||||
put ' call symputx(''input_statement'',_infile_); ';
|
put ' call symputx(''input_statement'',_infile_); ';
|
||||||
put ' putlog "&&_webin_name&i input statement: " _infile_; ';
|
put ' putlog "&&_webin_name&i input statement: " _infile_; ';
|
||||||
put ' stop; ';
|
put ' stop; ';
|
||||||
put ' data &&_webin_name&i; ';
|
put ' data &&_webin_name&i; ';
|
||||||
put ' infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding=''utf-8''; ';
|
put ' infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding=''utf-8'' ';
|
||||||
|
put ' lrecl=32767; ';
|
||||||
put ' input &input_statement; ';
|
put ' input &input_statement; ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||||
put ' if _n_<20 then putlog _infile_; ';
|
put ' if _n_<20 then putlog _infile_; ';
|
||||||
@@ -19546,14 +19781,14 @@ data _null_;
|
|||||||
put '%end; ';
|
put '%end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%else %if &action=OPEN %then %do; ';
|
put '%else %if &action=OPEN %then %do; ';
|
||||||
put ' /* fix encoding */ ';
|
put ' /* fix encoding and ensure enough lrecl */ ';
|
||||||
put ' OPTIONS NOBOMFILE; ';
|
put ' OPTIONS NOBOMFILE lrecl=32767; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' /* set the header */ ';
|
put ' /* set the header */ ';
|
||||||
put ' %mfs_httpheader(Content-type,application/json) ';
|
put ' %mfs_httpheader(Content-type,application/json) ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put ' /* setup json */ ';
|
put ' /* setup json. */ ';
|
||||||
put ' data _null_;file &fref encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_;file &fref encoding=''utf-8'' termstr=lf ; ';
|
||||||
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||||
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -19597,12 +19832,12 @@ data _null_;
|
|||||||
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf termstr=lf; ';
|
put ' data _null_; file &fref mod encoding=''utf-8'' termstr=lf; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' /* close off json */ ';
|
put ' /* close off json */ ';
|
||||||
put ' data _null_;file &fref mod encoding=''utf-8'' termstr=lf; ';
|
put ' data _null_;file &fref mod encoding=''utf-8'' termstr=lf lrecl=32767; ';
|
||||||
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
put ' _PROGRAM=quote(trim(resolve(symget(''_PROGRAM'')))); ';
|
||||||
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
put ' put ",""SYSUSERID"" : ""&sysuserid"" "; ';
|
||||||
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
put ' put ",""MF_GETUSER"" : ""%mf_getuser()"" "; ';
|
||||||
@@ -19675,24 +19910,21 @@ data _null_;
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
/* add precode and code */
|
/* add precode and code */
|
||||||
%local tmpref x fref freflist mod;
|
%local x fref freflist;
|
||||||
%let tmpref=%mf_getuniquefileref();
|
|
||||||
%let freflist=&precode &code ;
|
%let freflist=&precode &code ;
|
||||||
%do x=1 %to %sysfunc(countw(&freflist));
|
%do x=1 %to %sysfunc(countw(&freflist));
|
||||||
%if &x>1 %then %let mod=mod;
|
|
||||||
|
|
||||||
%let fref=%scan(&freflist,&x);
|
%let fref=%scan(&freflist,&x);
|
||||||
%put &sysmacroname: adding &fref;
|
%put &sysmacroname: adding &fref;
|
||||||
data _null_;
|
data _null_;
|
||||||
file &tmpref lrecl=3000 &mod;
|
file &sasjsref lrecl=3000 termstr=crlf mod;
|
||||||
infile &fref;
|
infile &fref lrecl=3000;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
/* create the web service */
|
/* create the web service */
|
||||||
%ms_createfile(&path/&name..sas, inref=&tmpref,mdebug=&mdebug)
|
%ms_createfile(&path/&name..sas, inref=&sasjsref, mdebug=&mdebug)
|
||||||
|
|
||||||
%put ;%put ;%put ;%put ;%put ;%put ;
|
%put ;%put ;%put ;%put ;%put ;%put ;
|
||||||
%put &sysmacroname: STP &name successfully created in &path;
|
%put &sysmacroname: STP &name successfully created in &path;
|
||||||
@@ -19924,48 +20156,154 @@ options &optval;
|
|||||||
parameter)
|
parameter)
|
||||||
@param [in] debug= (131) The value to supply to the _debug URL parameter
|
@param [in] debug= (131) The value to supply to the _debug URL parameter
|
||||||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
@param [in] inputparams=(_null_) A dataset containing name/value pairs in the
|
||||||
|
following format:
|
||||||
|
|name:$32|value:$10000|
|
||||||
|
|---|---|
|
||||||
|
|stpmacname|some value|
|
||||||
|
|mustbevalidname|can be anything, oops, %abort!!|
|
||||||
|
@param [in] inputfiles= (_null_) A dataset containing fileref/name/filename in
|
||||||
|
the following format:
|
||||||
|
|fileref:$8|name:$32|filename:$256|
|
||||||
|
|---|---|--|
|
||||||
|
|someref|some_name|some_filename.xls|
|
||||||
|
|fref2|another_file|zyx_v2.csv|
|
||||||
|
|
||||||
@param [out] outref= (outweb) The output fileref to contain the response JSON
|
@param [out] outref= (outweb) The output fileref to contain the response JSON
|
||||||
(will be created using temp engine)
|
(will be created using temp engine)
|
||||||
|
@param [out] outlogds= (_null_) Set to the name of a dataset to contain the
|
||||||
|
log. Table format:
|
||||||
|
|line:$2000|
|
||||||
|
|---|
|
||||||
|
|log line 1|
|
||||||
|
|log line 2|
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquelibref.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro ms_runstp(pgm
|
%macro ms_runstp(pgm
|
||||||
,debug=131
|
,debug=131
|
||||||
|
,inputparams=_null_
|
||||||
|
,inputfiles=_null_
|
||||||
,outref=outweb
|
,outref=outweb
|
||||||
|
,outlogds=_null_
|
||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
%local dbg fname1;
|
%local dbg mainref authref boundary;
|
||||||
|
%let mainref=%mf_getuniquefileref();
|
||||||
|
%let authref=%mf_getuniquefileref();
|
||||||
|
%let boundary=%mf_getuniquename();
|
||||||
|
%if &inputparams=0 %then %let inputparams=_null_;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
%put &sysmacroname entry vars:;
|
%put &sysmacroname entry vars:;
|
||||||
%put _local_;
|
%put _local_;
|
||||||
%end;
|
%end;
|
||||||
%else %let dbg=*;
|
%else %let dbg=*;
|
||||||
%let fname1=%mf_getuniquefileref();
|
|
||||||
|
|
||||||
%mp_abort(iftrue=("&pgm"="")
|
%mp_abort(iftrue=("&pgm"="")
|
||||||
,mac=&sysmacroname
|
,mac=&sysmacroname
|
||||||
,msg=%str(Program not provided)
|
,msg=%str(Program not provided)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* avoid sending bom marker to API */
|
||||||
|
%local optval;
|
||||||
|
%let optval=%sysfunc(getoption(bomfile));
|
||||||
|
options nobomfile;
|
||||||
|
|
||||||
|
/* add params */
|
||||||
data _null_;
|
data _null_;
|
||||||
file &fname1 lrecl=1000;
|
file &mainref termstr=crlf lrecl=32767 mod;
|
||||||
|
length line $1000 name $32 value $32767;
|
||||||
|
if _n_=1 then call missing(of _all_);
|
||||||
|
set &inputparams;
|
||||||
|
put "--&boundary";
|
||||||
|
line=cats('Content-Disposition: form-data; name="',name,'"');
|
||||||
|
put line;
|
||||||
|
put ;
|
||||||
|
put value;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* parse input file list */
|
||||||
|
%local webcount;
|
||||||
|
%let webcount=0;
|
||||||
|
data _null_;
|
||||||
|
set &inputfiles end=last;
|
||||||
|
length fileref $8 name $32 filename $256;
|
||||||
|
call symputx(cats('webref',_n_),fileref,'l');
|
||||||
|
call symputx(cats('webname',_n_),name,'l');
|
||||||
|
call symputx(cats('webfilename',_n_),filename,'l');
|
||||||
|
if last then do;
|
||||||
|
call symputx('webcount',_n_);
|
||||||
|
call missing(of _all_);
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* write out the input files */
|
||||||
|
%local i;
|
||||||
|
%do i=1 %to &webcount;
|
||||||
|
data _null_;
|
||||||
|
file &mainref termstr=crlf lrecl=32767 mod;
|
||||||
|
infile &&webref&i lrecl=32767;
|
||||||
|
if _n_ = 1 then do;
|
||||||
|
length line $32767;
|
||||||
|
line=cats(
|
||||||
|
'Content-Disposition: form-data; name="'
|
||||||
|
,"&&webname&i"
|
||||||
|
,'"; filename="'
|
||||||
|
,"&&webfilename&i"
|
||||||
|
,'"'
|
||||||
|
);
|
||||||
|
put "--&boundary";
|
||||||
|
put line;
|
||||||
|
put "Content-Type: text/plain";
|
||||||
|
put ;
|
||||||
|
end;
|
||||||
|
input;
|
||||||
|
put _infile_; /* add the actual file to be sent */
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &mainref termstr=crlf mod;
|
||||||
|
put "--&boundary--";
|
||||||
|
run;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &authref lrecl=1000;
|
||||||
infile "&_sasjs_tokenfile" lrecl=1000;
|
infile "&_sasjs_tokenfile" lrecl=1000;
|
||||||
input;
|
input;
|
||||||
put 'Authorization: Bearer ' _infile_;
|
put 'Authorization: Bearer ' _infile_;
|
||||||
|
put "Content-Type: multipart/form-data; boundary=&boundary";
|
||||||
run;
|
run;
|
||||||
|
|
||||||
filename &outref temp;
|
%if &mdebug=1 %then %do;
|
||||||
|
data _null_;
|
||||||
|
infile &authref;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
data _null_;
|
||||||
|
infile &mainref;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
filename &outref temp lrecl=32767;
|
||||||
/* prepare request*/
|
/* prepare request*/
|
||||||
proc http method='POST' headerin=&fname1 out=&outref
|
proc http method='POST' headerin=&authref in=&mainref out=&outref
|
||||||
url="&_sasjs_apiserverurl.&_sasjs_apipath?_program=&pgm%str(&)_debug=131";
|
url="&_sasjs_apiserverurl.&_sasjs_apipath?_program=&pgm%str(&)_debug=131";
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
debug level=2;
|
||||||
|
%end;
|
||||||
run;
|
run;
|
||||||
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
|
%if (&SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201)
|
||||||
or &mdebug=1 %then %do;
|
%then %do;
|
||||||
data _null_;infile &outref;input;putlog _infile_;run;
|
data _null_;infile &outref;input;putlog _infile_;run;
|
||||||
%end;
|
%end;
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
@@ -19974,6 +20312,20 @@ run;
|
|||||||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* reset options */
|
||||||
|
options &optval;
|
||||||
|
|
||||||
|
%if &outlogds ne _null_ or &mdebug=1 %then %do;
|
||||||
|
%local dumplib;
|
||||||
|
%let dumplib=%mf_getuniquelibref();
|
||||||
|
libname &dumplib json (&outref);
|
||||||
|
data &outlogds;
|
||||||
|
set &dumplib..log;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
putlog line=;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
%put &sysmacroname exit vars:;
|
%put &sysmacroname exit vars:;
|
||||||
@@ -19981,9 +20333,161 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
/* clear refs */
|
/* clear refs */
|
||||||
filename &fname1 clear;
|
filename &authref;
|
||||||
|
filename &mainref;
|
||||||
%end;
|
%end;
|
||||||
%mend ms_runstp;/**
|
%mend ms_runstp;/**
|
||||||
|
@file
|
||||||
|
@brief Will execute a SASjs web service on SASjs Server
|
||||||
|
@details Prepares the input files and retrieves the resulting datasets from
|
||||||
|
the response JSON.
|
||||||
|
|
||||||
|
@param [in] program The Stored Program endpoint to test
|
||||||
|
@param [in] inputfiles=(0) A list of space seperated fileref:filename pairs as
|
||||||
|
follows:
|
||||||
|
inputfiles=inref:filename inref2:filename2
|
||||||
|
@param [in] inputdatasets= (0) All datasets in this space seperated list are
|
||||||
|
converted into SASJS-formatted CSVs (see mp_ds2csv.sas) files and added to
|
||||||
|
the list of `inputfiles` for ingestion. The dataset will be sent with the
|
||||||
|
same name (no need for a colon modifier).
|
||||||
|
@param [in] inputparams=(0) A dataset containing name/value pairs in the
|
||||||
|
following format:
|
||||||
|
|name:$32|value:$1000|
|
||||||
|
|---|---|
|
||||||
|
|stpmacname|some value|
|
||||||
|
|mustbevalidname|can be anything, oops, %abort!!|
|
||||||
|
|
||||||
|
@param [in] debug= (131) Provide the _debug value to pass to the STP
|
||||||
|
@param [in] mdebug= (0) Set to 1 to provide macro debugging (this macro)
|
||||||
|
@param [out] outlib= (0) Output libref to contain the final tables. Set to
|
||||||
|
0 if the service output is not in JSON format.
|
||||||
|
@param [out] outref= (0) Output fileref to create, to contain the full _webout
|
||||||
|
response.
|
||||||
|
@param [out] outlogds= (_null_) Set to the name of a dataset to contain the
|
||||||
|
log. Table format:
|
||||||
|
|line:$2000|
|
||||||
|
|---|
|
||||||
|
|log line 1|
|
||||||
|
|log line 2|
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
@li mp_binarycopy.sas
|
||||||
|
@li mp_chop.sas
|
||||||
|
@li mp_ds2csv.sas
|
||||||
|
@li ms_runstp.sas
|
||||||
|
|
||||||
|
<h4> Related Programs </h4>
|
||||||
|
@li mp_testservice.test.sas
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_testservice(program,
|
||||||
|
inputfiles=0,
|
||||||
|
inputdatasets=0,
|
||||||
|
inputparams=0,
|
||||||
|
debug=0,
|
||||||
|
mdebug=0,
|
||||||
|
outlib=0,
|
||||||
|
outref=0,
|
||||||
|
outlogds=_null_
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
%local dbg fref1 chopout1 chopout2;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
|
/* convert inputdatasets to filerefs */
|
||||||
|
%if "&inputdatasets" ne "0" %then %do;
|
||||||
|
%if %quote(&inputfiles)=0 %then %let inputfiles=;
|
||||||
|
%do i=1 %to %sysfunc(countw(&inputdatasets,%str( )));
|
||||||
|
%let var=%scan(&inputdatasets,&i,%str( ));
|
||||||
|
%local dsref&i;
|
||||||
|
%let dsref&i=%mf_getuniquefileref();
|
||||||
|
%mp_ds2csv(&var,outref=&&dsref&i,headerformat=SASJS)
|
||||||
|
%let inputfiles=&inputfiles &&dsref&i:%scan(&var,-1,.);
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* parse the filerefs - convert to a dataset */
|
||||||
|
%let ds1=%mf_getuniquename();
|
||||||
|
data &ds1;
|
||||||
|
length fileref $8 name $32 filename $256 var $300;
|
||||||
|
webcount=countw("&inputfiles");
|
||||||
|
do i=1 to webcount;
|
||||||
|
var=scan("&inputfiles",i,' ');
|
||||||
|
fileref=scan(var,1,':');
|
||||||
|
name=scan(var,2,':');
|
||||||
|
filename=cats(name,'.csv');
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
|
||||||
|
/* execute the STP */
|
||||||
|
%let fref1=%mf_getuniquefileref();
|
||||||
|
|
||||||
|
%ms_runstp(&program
|
||||||
|
,debug=&debug
|
||||||
|
,inputparams=&inputparams
|
||||||
|
,inputfiles=&ds1
|
||||||
|
,outref=&fref1
|
||||||
|
,mdebug=&mdebug
|
||||||
|
,outlogds=&outlogds
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/* SASjs services have the _webout embedded in wrapper JSON */
|
||||||
|
/* Files can also be very large - so use a dedicated macro to chop it out */
|
||||||
|
%local matchstr1 matchstr2 ;
|
||||||
|
%let matchstr1={"status":"success","_webout":{;
|
||||||
|
%let matchstr2=},"log":[{;
|
||||||
|
%let chopout1=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop1);
|
||||||
|
%let chopout2=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop2);
|
||||||
|
|
||||||
|
%mp_chop("%sysfunc(pathname(&fref1,F))"
|
||||||
|
,matchvar=matchstr1
|
||||||
|
,keep=LAST
|
||||||
|
,matchpoint=END
|
||||||
|
,offset=-1
|
||||||
|
,outfile="&chopout1"
|
||||||
|
,mdebug=&mdebug
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_chop("&chopout1"
|
||||||
|
,matchvar=matchstr2
|
||||||
|
,keep=FIRST
|
||||||
|
,matchpoint=START
|
||||||
|
,offset=1
|
||||||
|
,outfile="&chopout2"
|
||||||
|
,mdebug=&mdebug
|
||||||
|
)
|
||||||
|
|
||||||
|
%if &outlib ne 0 %then %do;
|
||||||
|
libname &outlib json "&chopout2";
|
||||||
|
%end;
|
||||||
|
%if &outref ne 0 %then %do;
|
||||||
|
filename &outref "&chopout2";
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &mdebug=0 %then %do;
|
||||||
|
filename &webref clear;
|
||||||
|
filename &fref1 clear;
|
||||||
|
filename &fref2 clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend ms_testservice;/**
|
||||||
@file
|
@file
|
||||||
@brief Send data to/from sasjs/server
|
@brief Send data to/from sasjs/server
|
||||||
@details This macro should be added to the start of each web service,
|
@details This macro should be added to the start of each web service,
|
||||||
@@ -20052,13 +20556,14 @@ run;
|
|||||||
%let _webin_name1=&_webin_name;
|
%let _webin_name1=&_webin_name;
|
||||||
%end;
|
%end;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &&_webin_fileref&i termstr=crlf;
|
infile &&_webin_fileref&i termstr=crlf lrecl=32767;
|
||||||
input;
|
input;
|
||||||
call symputx('input_statement',_infile_);
|
call symputx('input_statement',_infile_);
|
||||||
putlog "&&_webin_name&i input statement: " _infile_;
|
putlog "&&_webin_name&i input statement: " _infile_;
|
||||||
stop;
|
stop;
|
||||||
data &&_webin_name&i;
|
data &&_webin_name&i;
|
||||||
infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding='utf-8';
|
infile &&_webin_fileref&i firstobs=2 dsd termstr=crlf encoding='utf-8'
|
||||||
|
lrecl=32767;
|
||||||
input &input_statement;
|
input &input_statement;
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&_debug) ge 131 %then %do;
|
||||||
if _n_<20 then putlog _infile_;
|
if _n_<20 then putlog _infile_;
|
||||||
@@ -20069,14 +20574,14 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%else %if &action=OPEN %then %do;
|
%else %if &action=OPEN %then %do;
|
||||||
/* fix encoding */
|
/* fix encoding and ensure enough lrecl */
|
||||||
OPTIONS NOBOMFILE;
|
OPTIONS NOBOMFILE lrecl=32767;
|
||||||
|
|
||||||
/* set the header */
|
/* set the header */
|
||||||
%mfs_httpheader(Content-type,application/json)
|
%mfs_httpheader(Content-type,application/json)
|
||||||
|
|
||||||
/* setup json */
|
/* setup json. */
|
||||||
data _null_;file &fref encoding='utf-8' termstr=lf;
|
data _null_;file &fref encoding='utf-8' termstr=lf ;
|
||||||
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||||
run;
|
run;
|
||||||
@@ -20120,12 +20625,12 @@ run;
|
|||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
%end;
|
%end;
|
||||||
data _null_; file &fref mod encoding='utf-8' termstr=lf termstr=lf;
|
data _null_; file &fref mod encoding='utf-8' termstr=lf;
|
||||||
put "}";
|
put "}";
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
/* close off json */
|
/* close off json */
|
||||||
data _null_;file &fref mod encoding='utf-8' termstr=lf;
|
data _null_;file &fref mod encoding='utf-8' termstr=lf lrecl=32767;
|
||||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||||
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
put ",""MF_GETUSER"" : ""%mf_getuser()"" ";
|
||||||
@@ -21147,7 +21652,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
put ' options nobomfile; ';
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8'' ; ';
|
put ' data _null_;file &jref encoding=''utf-8'' lrecl=200; ';
|
||||||
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
put ' put ''{"PROCESSED_DTTM" : "'' "%sysfunc(datetime(),E8601DT26.6)" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
@@ -25382,8 +25887,16 @@ data _null_;
|
|||||||
put 'io.close(file) ';
|
put 'io.close(file) ';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
/* ensure big enough lrecl to avoid lua compilation issues */
|
||||||
|
%local optval;
|
||||||
|
%let optval=%sysfunc(getoption(lrecl));
|
||||||
|
options lrecl=1024;
|
||||||
|
|
||||||
|
/* execute the lua code by using a .lua extension */
|
||||||
%inc "%sysfunc(pathname(work))/ml_gsubfile.lua" /source2;
|
%inc "%sysfunc(pathname(work))/ml_gsubfile.lua" /source2;
|
||||||
|
|
||||||
|
options lrecl=&optval;
|
||||||
|
|
||||||
%mend ml_gsubfile;
|
%mend ml_gsubfile;
|
||||||
/**
|
/**
|
||||||
@file ml_json.sas
|
@file ml_json.sas
|
||||||
@@ -25776,8 +26289,16 @@ data _null_;
|
|||||||
put '-- JSON.LUA ENDS HERE ';
|
put '-- JSON.LUA ENDS HERE ';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
/* ensure big enough lrecl to avoid lua compilation issues */
|
||||||
|
%local optval;
|
||||||
|
%let optval=%sysfunc(getoption(lrecl));
|
||||||
|
options lrecl=1024;
|
||||||
|
|
||||||
|
/* execute the lua code by using a .lua extension */
|
||||||
%inc "%sysfunc(pathname(work))/ml_json.lua" /source2;
|
%inc "%sysfunc(pathname(work))/ml_json.lua" /source2;
|
||||||
|
|
||||||
|
options lrecl=&optval;
|
||||||
|
|
||||||
%mend ml_json;
|
%mend ml_json;
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
|
|||||||
Reference in New Issue
Block a user