mirror of
https://github.com/sasjs/core.git
synced 2025-12-24 03:31:19 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c1f69da3a | ||
|
|
f160ebe705 | ||
|
|
53ed5dc916 | ||
|
|
808b24e31b | ||
|
|
4d6edf5566 | ||
|
|
41a24677f5 | ||
|
|
e7d8d8ffb3 | ||
|
|
60d23dd618 | ||
|
|
d2764c3cd1 | ||
|
|
f9f4355143 | ||
|
|
18bc6c889d | ||
|
|
42a16ef496 | ||
|
|
8178b801fb | ||
|
|
ce331a23c8 | ||
|
|
1cc9213467 | ||
|
|
aabbf4d0f9 | ||
|
|
2bea8be70d | ||
|
|
9b2368443e | ||
|
|
7915ba2c41 | ||
|
|
cc61e48868 | ||
|
|
62db83dcf6 |
@@ -1,5 +1,5 @@
|
||||
tasks:
|
||||
- init: npm i -g @sasjs/cli
|
||||
- init: nvm install --latest-npm && npm i -g @sasjs/cli
|
||||
|
||||
image:
|
||||
file: .gitpod.dockerfile
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"hasMacroParentheses": true,
|
||||
"noNestedMacros": false,
|
||||
"noSpacesInFileNames": true,
|
||||
"maxLineLength": 135,
|
||||
"maxLineLength": 230,
|
||||
"lowerCaseFileNames": true,
|
||||
"noTabIndentation": true,
|
||||
"indentationMultiple": 2
|
||||
|
||||
535
all.sas
535
all.sas
@@ -18,19 +18,18 @@
|
||||
options noquotelenmax;
|
||||
/**
|
||||
@file
|
||||
@brief to be deprecated
|
||||
@details We will deprecate this macro in 2022
|
||||
@brief Abort, ungracefully
|
||||
@details Will abort with a straightforward %abort if the condition is true.
|
||||
|
||||
As you can see, it's not a macro function.
|
||||
|
||||
Use mp_abort.sas instead.
|
||||
<h4> Related Macros </h4>
|
||||
@li mp_abort.sas
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
@cond
|
||||
**/
|
||||
|
||||
%macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
|
||||
%macro mf_abort(mac=mf_abort.sas, type=deprecated, msg=, iftrue=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||
@@ -39,117 +38,9 @@ options noquotelenmax;
|
||||
%if %length(&mac)>0 %then %put NOTE- called by &mac;
|
||||
%put NOTE - &msg;
|
||||
|
||||
/* Stored Process Server web app context */
|
||||
%if %symexist(_metaperson) or "&SYSPROCESSNAME"="Compute Server" %then %do;
|
||||
options obs=max replace nosyntaxcheck mprint;
|
||||
/* extract log err / warn, if exist */
|
||||
%local logloc logline;
|
||||
%global logmsg; /* capture global messages */
|
||||
%if %symexist(SYSPRINTTOLOG) %then %let logloc=&SYSPRINTTOLOG;
|
||||
%else %let logloc=%qsysfunc(getoption(LOG));
|
||||
proc printto log=log;run;
|
||||
%if %length(&logloc)>0 %then %do;
|
||||
%let logline=0;
|
||||
data _null_;
|
||||
infile &logloc lrecl=5000;
|
||||
input; putlog _infile_;
|
||||
i=1;
|
||||
retain logonce 0;
|
||||
if (
|
||||
_infile_=:"%str(WARN)ING" or _infile_=:"%str(ERR)OR"
|
||||
) and logonce=0
|
||||
then do;
|
||||
call symputx('logline',_n_);
|
||||
logonce+1;
|
||||
end;
|
||||
run;
|
||||
/* capture log including lines BEFORE the err */
|
||||
%if &logline>0 %then %do;
|
||||
data _null_;
|
||||
infile &logloc lrecl=5000;
|
||||
input;
|
||||
i=1;
|
||||
stoploop=0;
|
||||
if _n_ ge &logline-5 and stoploop=0 then do until (i>12);
|
||||
call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
|
||||
input;
|
||||
i+1;
|
||||
stoploop=1;
|
||||
end;
|
||||
if stoploop=1 then stop;
|
||||
run;
|
||||
%end;
|
||||
%end;
|
||||
%abort;
|
||||
|
||||
/* send response in SASjs JSON format */
|
||||
data _null_;
|
||||
file _webout mod lrecl=32000;
|
||||
length msg $32767;
|
||||
sasdatetime=datetime();
|
||||
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
||||
/* escape the quotes */
|
||||
msg=tranwrd(msg,'"','\"');
|
||||
/* ditch the CRLFs as chrome complains */
|
||||
msg=compress(msg,,'kw');
|
||||
/* quote without quoting the quotes (which are escaped instead) */
|
||||
msg=cats('"',msg,'"');
|
||||
if symexist('_debug') then debug=symget('_debug');
|
||||
if debug ge 131 then put '>>weboutBEGIN<<';
|
||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
||||
put ',"sasjsAbort" : [{';
|
||||
put ' "MSG":' msg ;
|
||||
put ' ,"MAC": "' "&mac" '"}]';
|
||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||
if symexist('_metauser') then do;
|
||||
_METAUSER=quote(trim(symget('_METAUSER')));
|
||||
put ",""_METAUSER"": " _METAUSER;
|
||||
_METAPERSON=quote(trim(symget('_METAPERSON')));
|
||||
put ',"_METAPERSON": ' _METAPERSON;
|
||||
end;
|
||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||
put ",""SYSCC"" : ""&syscc"" ";
|
||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||
put "}" @;
|
||||
%if &_debug ge 131 %then %do;
|
||||
put '>>weboutEND<<';
|
||||
%end;
|
||||
run;
|
||||
%let syscc=0;
|
||||
%if %symexist(SYS_JES_JOB_URI) %then %do;
|
||||
/* refer web service output to file service in one hit */
|
||||
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
|
||||
name="_webout.json";
|
||||
%let rc=%sysfunc(fcopy(_web,_webout));
|
||||
%end;
|
||||
%else %do;
|
||||
data _null_;
|
||||
if symexist('sysprocessmode')
|
||||
then if symget("sysprocessmode")="SAS Stored Process Server"
|
||||
then rc=stpsrvset('program error', 0);
|
||||
run;
|
||||
%end;
|
||||
/**
|
||||
* endsas is reliable but kills some deployments.
|
||||
* Abort variants are ungraceful (non zero return code)
|
||||
* This approach lets SAS run silently until the end :-)
|
||||
*/
|
||||
%put _all_;
|
||||
filename skip temp;
|
||||
data _null_;
|
||||
file skip;
|
||||
put '%macro skip(); %macro skippy();';
|
||||
run;
|
||||
%inc skip;
|
||||
%end;
|
||||
%else %do;
|
||||
%put _all_;
|
||||
%abort cancel;
|
||||
%end;
|
||||
%mend;
|
||||
%mend mf_abort;
|
||||
|
||||
/** @endcond *//**
|
||||
@file mf_existds.sas
|
||||
@@ -176,7 +67,8 @@ options noquotelenmax;
|
||||
%if %sysfunc(exist(&libds)) ne 1 & %sysfunc(exist(&libds,VIEW)) ne 1 %then 0;
|
||||
%else 1;
|
||||
|
||||
%mend;/**
|
||||
%mend mf_existds;
|
||||
/**
|
||||
@file
|
||||
@brief Checks whether a feature exists
|
||||
@details Check to see if a feature is supported in your environment.
|
||||
@@ -1084,7 +976,8 @@ options noquotelenmax;
|
||||
%let rc=%sysfunc(close(&dsid));
|
||||
%end;
|
||||
%else %do;
|
||||
%put unable to open &libds (rc=&dsid);
|
||||
%put &sysmacroname: Unable to open &libds (rc=&dsid);
|
||||
%put &sysmacroname: SYSMSG= %sysfunc(sysmsg());
|
||||
%let rc=%sysfunc(close(&dsid));
|
||||
%end;
|
||||
&outvar
|
||||
@@ -1719,7 +1612,7 @@ Usage:
|
||||
|
||||
/* send response in SASjs JSON format */
|
||||
data _null_;
|
||||
file _webout mod lrecl=32000;
|
||||
file _webout mod lrecl=32000 encoding='utf-8';
|
||||
length msg $32767 debug $8;
|
||||
sasdatetime=datetime();
|
||||
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
||||
@@ -1753,6 +1646,8 @@ Usage:
|
||||
put ",""SYSCC"" : ""&syscc"" ";
|
||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||
sysvlong=quote(trim(symget('sysvlong')));
|
||||
put ',"SYSVLONG" : ' sysvlong;
|
||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||
put "}" @;
|
||||
@@ -3795,7 +3690,8 @@ run;
|
||||
|
||||
data &outds;
|
||||
if &sqlrc or &syscc or &syserr then do;
|
||||
REASON_CD=coalescec(symget('SYSERRORTEXT'),symget('SYSWARNINGTEXT'));
|
||||
REASON_CD='VALIDATION_ERROR: '!!
|
||||
coalescec(symget('SYSERRORTEXT'),symget('SYSWARNINGTEXT'));
|
||||
output;
|
||||
end;
|
||||
else stop;
|
||||
@@ -3819,7 +3715,7 @@ filename &fref1 clear;
|
||||
%let syscc=1008;
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
%mend mp_filtervalidate;
|
||||
/**
|
||||
@file mp_getconstraints.sas
|
||||
@brief Get constraint details at column level
|
||||
@@ -5146,7 +5042,8 @@ create table &outds (rename=(
|
||||
%let fmtds=%scan(&syslast,2,.);
|
||||
/* prepare formats and varnames */
|
||||
data _null_;
|
||||
set &fmtds end=last;
|
||||
if _n_=1 then call symputx('nobs',nobs,'l');
|
||||
set &fmtds end=last nobs=nobs;
|
||||
name=upcase(name);
|
||||
/* fix formats */
|
||||
if type=2 or type=6 then do;
|
||||
@@ -5172,7 +5069,6 @@ create table &outds (rename=(
|
||||
call symputx(cats('len',_n_),newlen,'l');
|
||||
call symputx(cats('fmt',_n_),fmt,'l');
|
||||
call symputx(cats('type',_n_),type,'l');
|
||||
if last then call symputx('nobs',_n_,'l');
|
||||
run;
|
||||
data &fmtds;
|
||||
/* rename on entry */
|
||||
@@ -5191,7 +5087,7 @@ create table &outds (rename=(
|
||||
run;
|
||||
%let ds=&fmtds;
|
||||
%end; /* &fmt=Y */
|
||||
data _null_;file &jref mod ;
|
||||
data _null_;file &jref mod encoding='utf-8';
|
||||
put "["; call symputx('cols',0,'l');
|
||||
proc sort
|
||||
data=sashelp.vcolumn(where=(libname='WORK' & memname="%upcase(&ds)"))
|
||||
@@ -8898,7 +8794,7 @@ Usage:
|
||||
%webout(OBJ,example2) * Object format, easier to work with ;
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=appInit)
|
||||
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mm_createstp.sas
|
||||
@@ -8913,12 +8809,15 @@ Usage:
|
||||
@param desc= The description of the service (optional)
|
||||
@param precode= Space separated list of filerefs, pointing to the code that
|
||||
needs to be attached to the beginning of the service (optional)
|
||||
@param code= Space seperated fileref(s) of the actual code to be added
|
||||
@param server= The server which will run the STP. Server name or uri is fine.
|
||||
@param mDebug= set to 1 to show debug messages in the log
|
||||
@param replace= select YES to replace any existing service in that location
|
||||
@param adapter= the macro uses the sasjs adapter by default. To use another
|
||||
adapter, add a (different) fileref here.
|
||||
@param code=(ft15f001) Space seperated fileref(s) of the actual code to be
|
||||
added
|
||||
@param server=(SASApp) The server which will run the STP. Server name or uri
|
||||
is fine.
|
||||
@param mDebug=(0) set to 1 to show debug messages in the log
|
||||
@param replace=(YES) select NO to avoid replacing an existing service in that
|
||||
location
|
||||
@param adapter=(sasjs) the macro uses the sasjs adapter by default. To use
|
||||
another adapter, add a (different) fileref here.
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
@@ -8928,11 +8827,11 @@ Usage:
|
||||
%macro mm_createwebservice(path=
|
||||
,name=initService
|
||||
,precode=
|
||||
,code=
|
||||
,code=ft15f001
|
||||
,desc=This stp was created automagically by the mm_createwebservice macro
|
||||
,mDebug=0
|
||||
,server=SASApp
|
||||
,replace=NO
|
||||
,replace=YES
|
||||
,adapter=sasjs
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
@@ -9007,7 +8906,8 @@ data _null_;
|
||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||
put ' /* prepare formats and varnames */ ';
|
||||
put ' data _null_; ';
|
||||
put ' set &fmtds end=last; ';
|
||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
||||
put ' set &fmtds end=last nobs=nobs; ';
|
||||
put ' name=upcase(name); ';
|
||||
put ' /* fix formats */ ';
|
||||
put ' if type=2 or type=6 then do; ';
|
||||
@@ -9033,7 +8933,6 @@ data _null_;
|
||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||
put ' run; ';
|
||||
put ' data &fmtds; ';
|
||||
put ' /* rename on entry */ ';
|
||||
@@ -9052,7 +8951,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put ' %let ds=&fmtds; ';
|
||||
put ' %end; /* &fmt=Y */ ';
|
||||
put ' data _null_;file &jref mod ; ';
|
||||
put ' data _null_;file &jref mod encoding=''utf-8''; ';
|
||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||
put ' proc sort ';
|
||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
||||
@@ -9139,7 +9038,12 @@ data _null_;
|
||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||
put ' sasjs_tables; ';
|
||||
put '%local i tempds; ';
|
||||
put '%local i tempds jsonengine; ';
|
||||
put ' ';
|
||||
put '/* see https://github.com/sasjs/core/issues/41 */ ';
|
||||
put '%if %upcase(&SYSENCODING)=WLATIN1 %then %let jsonengine=PROCJSON; ';
|
||||
put '%else %let jsonengine=DATASTEP; ';
|
||||
put ' ';
|
||||
put ' ';
|
||||
put '%if &action=FETCH %then %do; ';
|
||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||
@@ -9174,7 +9078,7 @@ data _null_;
|
||||
put ' OPTIONS NOBOMFILE; ';
|
||||
put ' ';
|
||||
put ' /** ';
|
||||
put ' * check engine type to avoid the below err message: ';
|
||||
put ' * check xengine type to avoid the below err message: ';
|
||||
put ' * > Function is only valid for filerefs using the CACHE access method. ';
|
||||
put ' */ ';
|
||||
put ' data _null_; ';
|
||||
@@ -9195,8 +9099,8 @@ data _null_;
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
||||
put ' ,engine=DATASTEP,dbg=%str(&_debug) ';
|
||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||
put ' ,engine=&jsonengine,dbg=%str(&_debug) ';
|
||||
put ' ) ';
|
||||
put '%end; ';
|
||||
put '%else %if &action=CLOSE %then %do; ';
|
||||
@@ -9209,7 +9113,7 @@ data _null_;
|
||||
put ' %local wtcnt;%let wtcnt=0; ';
|
||||
put ' data _null_; ';
|
||||
put ' set &tempds; ';
|
||||
put ' if not (name =:"DATA"); ';
|
||||
put ' if not (upcase(name) =:"DATA"); /* ignore temp datasets */ ';
|
||||
put ' i+1; ';
|
||||
put ' call symputx(''wt''!!left(i),name,''l''); ';
|
||||
put ' call symputx(''wtcnt'',i,''l''); ';
|
||||
@@ -9229,8 +9133,8 @@ data _null_;
|
||||
put ' put " ""&wt"" : {"; ';
|
||||
put ' put ''"nlobs":'' nlobs; ';
|
||||
put ' put '',"nvars":'' nvars; ';
|
||||
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP) ';
|
||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP) ';
|
||||
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine) ';
|
||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine) ';
|
||||
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
||||
put ' put "}"; ';
|
||||
put ' %end; ';
|
||||
@@ -9254,6 +9158,8 @@ data _null_;
|
||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||
put ' put "}" @; ';
|
||||
@@ -9263,7 +9169,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%mend; ';
|
||||
put '%mend mm_webout; ';
|
||||
put ' ';
|
||||
put '%macro mf_getuser(type=META ';
|
||||
put ')/*/STORE SOURCE*/; ';
|
||||
@@ -9342,7 +9248,7 @@ run;
|
||||
%put &url?_PROGRAM=&path/&name;
|
||||
%put ;%put ;%put ;%put ;%put ;%put ;
|
||||
|
||||
%mend;
|
||||
%mend mm_createwebservice;
|
||||
/**
|
||||
@file mm_deletedocument.sas
|
||||
@brief Deletes a Document using path as reference
|
||||
@@ -11640,7 +11546,7 @@ libname _XML_ clear;
|
||||
|
||||
Usage:
|
||||
|
||||
%mm_getusers()
|
||||
%mm_getusers()
|
||||
|
||||
@param outds the dataset to create that contains the list of libraries
|
||||
|
||||
@@ -11702,7 +11608,7 @@ filename sxlemap clear;
|
||||
filename response clear;
|
||||
libname _XML_ clear;
|
||||
|
||||
%mend;
|
||||
%mend mm_getusers;
|
||||
/**
|
||||
@file
|
||||
@brief Retrieves properties of the SAS web app server
|
||||
@@ -12613,7 +12519,8 @@ run;
|
||||
@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= set to N to send back unformatted values
|
||||
@param fmt=(Y) Set to N to send back unformatted values
|
||||
@param fref=(_webout) The fileref to which to write the JSON
|
||||
|
||||
@version 9.3
|
||||
@author Allan Bowe
|
||||
@@ -12622,7 +12529,12 @@ run;
|
||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
|
||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||
sasjs_tables;
|
||||
%local i tempds;
|
||||
%local i tempds jsonengine;
|
||||
|
||||
/* see https://github.com/sasjs/core/issues/41 */
|
||||
%if %upcase(&SYSENCODING)=WLATIN1 %then %let jsonengine=PROCJSON;
|
||||
%else %let jsonengine=DATASTEP;
|
||||
|
||||
|
||||
%if &action=FETCH %then %do;
|
||||
%if %str(&_debug) ge 131 %then %do;
|
||||
@@ -12657,7 +12569,7 @@ run;
|
||||
OPTIONS NOBOMFILE;
|
||||
|
||||
/**
|
||||
* check engine type to avoid the below err message:
|
||||
* check xengine type to avoid the below err message:
|
||||
* > Function is only valid for filerefs using the CACHE access method.
|
||||
*/
|
||||
data _null_;
|
||||
@@ -12678,8 +12590,8 @@ run;
|
||||
%end;
|
||||
|
||||
%else %if &action=ARR or &action=OBJ %then %do;
|
||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt
|
||||
,engine=DATASTEP,dbg=%str(&_debug)
|
||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||
,engine=&jsonengine,dbg=%str(&_debug)
|
||||
)
|
||||
%end;
|
||||
%else %if &action=CLOSE %then %do;
|
||||
@@ -12692,7 +12604,7 @@ run;
|
||||
%local wtcnt;%let wtcnt=0;
|
||||
data _null_;
|
||||
set &tempds;
|
||||
if not (name =:"DATA");
|
||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||
i+1;
|
||||
call symputx('wt'!!left(i),name,'l');
|
||||
call symputx('wtcnt',i,'l');
|
||||
@@ -12712,8 +12624,8 @@ run;
|
||||
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)
|
||||
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine)
|
||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine)
|
||||
data _null_; file &fref mod encoding='utf-8';
|
||||
put "}";
|
||||
%end;
|
||||
@@ -12737,6 +12649,8 @@ run;
|
||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||
put ",""SYSSITE"" : ""&syssite"" ";
|
||||
sysvlong=quote(trim(symget('sysvlong')));
|
||||
put ',"SYSVLONG" : ' sysvlong;
|
||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||
put "}" @;
|
||||
@@ -12746,7 +12660,7 @@ run;
|
||||
run;
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
%mend mm_webout;
|
||||
/**
|
||||
@file
|
||||
@brief Deletes a metadata folder
|
||||
@@ -12879,19 +12793,233 @@ run;
|
||||
%inc &fref1;
|
||||
|
||||
%mend;/**
|
||||
@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
|
||||
attempting to assign a fileref with the filesrvc engine. If not found, the
|
||||
syscc is automatically set to a non zero value - so in this case it is reset.
|
||||
To avoid hiding issues, there is therefore a test at the start to ensure the
|
||||
syscc is zero.
|
||||
|
||||
Usage:
|
||||
|
||||
%put %mfv_existfile(/does/exist.txt);
|
||||
%put %mfv_existfile(/does/not/exist.txt);
|
||||
|
||||
@param filepath The full path to the file on SAS drive (eg /Public/myfile.txt)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mfv_existfolder.sas
|
||||
|
||||
@version 3.5
|
||||
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
|
||||
**/
|
||||
|
||||
%macro mfv_existfile(filepath
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mf_abort(
|
||||
iftrue=(&syscc ne 0),
|
||||
msg=Cannot enter mfv_existfile.sas with syscc=&syscc
|
||||
)
|
||||
|
||||
%local fref rc path name;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
%let name=%scan(&filepath,-1,/);
|
||||
%let path=%substr(&filepath,1,%length(&filepath)-%length(&name)-1);
|
||||
|
||||
%if %sysfunc(filename(fref,,filesrvc,folderPath="&path" filename="&name"))=0
|
||||
%then %do;
|
||||
%sysfunc(fexist(&fref))
|
||||
%let rc=%sysfunc(filename(fref));
|
||||
%end;
|
||||
%else %do;
|
||||
0
|
||||
%let syscc=0;
|
||||
%end;
|
||||
|
||||
%mend mfv_existfile;/**
|
||||
@file
|
||||
@brief Checks whether a folder exists in SAS Drive
|
||||
@details Returns 1 if the folder exists, and 0 if it doesn't. Works by
|
||||
attempting to assign a fileref with the filesrvc engine. If not found, the
|
||||
syscc is automatically set to a non zero value - so in this case it is reset.
|
||||
To avoid hiding issues, there is therefore a test at the start to ensure the
|
||||
syscc is zero.
|
||||
|
||||
Usage:
|
||||
|
||||
%put %mfv_existfolder(/does/exist);
|
||||
%put %mfv_existfolder(/does/not/exist);
|
||||
|
||||
@param path The path to the folder on SAS drive
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mfv_existfile.sas
|
||||
|
||||
@version 3.5
|
||||
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
|
||||
**/
|
||||
|
||||
%macro mfv_existfolder(path
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mf_abort(
|
||||
iftrue=(&syscc ne 0),
|
||||
msg=Cannot enter mfv_existfolder.sas with syscc=&syscc
|
||||
)
|
||||
|
||||
%local fref rc;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
|
||||
%if %sysfunc(filename(fref,,filesrvc,folderPath="&path"))=0 %then %do;
|
||||
1
|
||||
%let rc=%sysfunc(filename(fref));
|
||||
%end;
|
||||
%else %do;
|
||||
0
|
||||
%let syscc=0;
|
||||
%end;
|
||||
|
||||
%mend mfv_existfolder;/**
|
||||
@file
|
||||
@brief Creates a file in SAS Drive
|
||||
@details Creates a file in SAS Drive and adds the appropriate content type.
|
||||
If the parent folder does not exist, it is created.
|
||||
|
||||
Usage:
|
||||
|
||||
filename myfile temp;
|
||||
data _null_;
|
||||
file myfile;
|
||||
put 'something';
|
||||
run;
|
||||
%mv_createfile(path=/Public/temp,name=newfile.txt,inref=myfile)
|
||||
|
||||
|
||||
@param [in] path= The parent folder in which to create the file
|
||||
@param [in] name= The name of the file to be created
|
||||
@param [in] inref= The fileref pointing to the file to be uploaded
|
||||
@param [in] contentdisp= (inline) Content Disposition. Example values:
|
||||
@li inline
|
||||
@li attachment
|
||||
|
||||
@param [in] access_token_var= The global macro variable to contain the access
|
||||
token, if using authorization_code grant type.
|
||||
@param [in] grant_type= (sas_services) Valid values are:
|
||||
@li password
|
||||
@li authorization_code
|
||||
@li sas_services
|
||||
|
||||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||
|
||||
@version VIYA V.03.05
|
||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_isblank.sas
|
||||
@li mp_abort.sas
|
||||
@li mp_binarycopy.sas
|
||||
@li mv_createfolder.sas
|
||||
|
||||
**/
|
||||
|
||||
%macro mv_createfile(path=
|
||||
,name=
|
||||
,inref=
|
||||
,contentdisp=inline
|
||||
,access_token_var=ACCESS_TOKEN
|
||||
,grant_type=sas_services
|
||||
,mdebug=0
|
||||
);
|
||||
%local dbg;
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname entry vars:;
|
||||
%put _local_;
|
||||
%end;
|
||||
%else %let dbg=*;
|
||||
|
||||
%local oauth_bearer;
|
||||
%if &grant_type=detect %then %do;
|
||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||
%else %let grant_type=sas_services;
|
||||
%end;
|
||||
%if &grant_type=sas_services %then %do;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%end;
|
||||
|
||||
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
|
||||
and &grant_type ne sas_services
|
||||
)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(Invalid value for grant_type: &grant_type)
|
||||
)
|
||||
|
||||
%mp_abort(iftrue=(%mf_isblank(&path)=1 or %length(&path)=1)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(path value must be provided)
|
||||
)
|
||||
%mp_abort(iftrue=(%mf_isblank(&name)=1 or %length(&name)=1)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(name value with length >1 must be provided)
|
||||
)
|
||||
|
||||
/* create folder if it does not already exist */
|
||||
%mv_createfolder(path=&path
|
||||
,access_token_var=&access_token_var
|
||||
,grant_type=&grant_type
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
|
||||
/* create file with relevant options */
|
||||
%local fref;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
filename &fref filesrvc
|
||||
folderPath="&path"
|
||||
filename="&name"
|
||||
cdisp="&contentdisp";
|
||||
|
||||
%mp_binarycopy(inref=&inref, outref=&fref)
|
||||
|
||||
filename &fref clear;
|
||||
|
||||
%local base_uri; /* location of rest apis */
|
||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||
|
||||
%put &sysmacroname: File &name successfully created in &path;
|
||||
%put &sysmacroname:;%put;
|
||||
%put &base_uri/SASJobExecution?_file=&path/&name;%put;
|
||||
%put &sysmacroname:;
|
||||
|
||||
%mend mv_createfile;/**
|
||||
@file mv_createfolder.sas
|
||||
@brief Creates a viya folder if that folder does not already exist
|
||||
@details Expects oauth token in a global macro variable (default
|
||||
ACCESS_TOKEN).
|
||||
@details Creates a viya folder by checking if each parent folder exists, and
|
||||
recursively creating children if needed.
|
||||
Usage:
|
||||
|
||||
%mv_createfolder(path=/Public)
|
||||
|
||||
|
||||
@param path= The full path of the folder to be created
|
||||
@param access_token_var= The global macro variable to contain the access token
|
||||
@param grant_type= (authorization_code) Valid values are "password" or
|
||||
"authorization_code" (unquoted).
|
||||
@param [in] path= The full path of the folder to be created
|
||||
@param [in] access_token_var= The global macro variable to contain the access
|
||||
token, if using authorization_code grant type.
|
||||
@param [in] grant_type= (sas_services) Valid values are:
|
||||
@li password
|
||||
@li authorization_code
|
||||
@li sas_services
|
||||
|
||||
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
||||
|
||||
@version VIYA V.03.04
|
||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||
@@ -12902,21 +13030,36 @@ run;
|
||||
@li mf_getuniquelibref.sas
|
||||
@li mf_isblank.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mfv_existfolder.sas
|
||||
|
||||
|
||||
**/
|
||||
|
||||
%macro mv_createfolder(path=
|
||||
,access_token_var=ACCESS_TOKEN
|
||||
,grant_type=sas_services
|
||||
,mdebug=0
|
||||
);
|
||||
%local dbg;
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname entry vars:;
|
||||
%put _local_;
|
||||
%end;
|
||||
%else %let dbg=*;
|
||||
|
||||
%if %mfv_existfolder(&path)=1 %then %do;
|
||||
%put &sysmacroname: &path already exists;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%local oauth_bearer;
|
||||
%if &grant_type=detect %then %do;
|
||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||
%else %let grant_type=sas_services;
|
||||
%end;
|
||||
%if &grant_type=sas_services %then %do;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%end;
|
||||
|
||||
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
|
||||
@@ -12971,12 +13114,21 @@ options noquotelenmax;
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||
)
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname following check to see if &newpath exists:;
|
||||
%put _local_;
|
||||
data _null_;
|
||||
set &fname1;
|
||||
input;
|
||||
putlog _infile_;
|
||||
run;
|
||||
%end;
|
||||
%if &SYS_PROCHTTP_STATUS_CODE=200 %then %do;
|
||||
%*put &sysmacroname &newpath exists so grab the follow on link ;
|
||||
data _null_;
|
||||
set &libref1..links;
|
||||
if rel='createChild' then
|
||||
call symputx('href',quote("&base_uri"!!trim(href)),'l');
|
||||
call symputx('href',quote(cats("&base_uri",href)),'l');
|
||||
run;
|
||||
%end;
|
||||
%else %if &SYS_PROCHTTP_STATUS_CODE=404 %then %do;
|
||||
@@ -13020,8 +13172,10 @@ options noquotelenmax;
|
||||
%put &sysmacroname &newpath now created. Grabbing the follow on link ;
|
||||
data _null_;
|
||||
set &libref2..links;
|
||||
if rel='createChild' then
|
||||
call symputx('href',quote(trim(href)),'l');
|
||||
if rel='createChild' then do;
|
||||
call symputx('href',quote(cats("&base_uri",href)),'l');
|
||||
&dbg put (_all_)(=);
|
||||
end;
|
||||
run;
|
||||
|
||||
libname &libref2 clear;
|
||||
@@ -13030,7 +13184,7 @@ options noquotelenmax;
|
||||
filename &fname1 clear;
|
||||
libname &libref1 clear;
|
||||
%end;
|
||||
%mend;/**
|
||||
%mend mv_createfolder;/**
|
||||
@file
|
||||
@brief Creates a Viya Job
|
||||
@details
|
||||
@@ -13621,7 +13775,8 @@ data _null_;
|
||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||
put ' /* prepare formats and varnames */ ';
|
||||
put ' data _null_; ';
|
||||
put ' set &fmtds end=last; ';
|
||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
||||
put ' set &fmtds end=last nobs=nobs; ';
|
||||
put ' name=upcase(name); ';
|
||||
put ' /* fix formats */ ';
|
||||
put ' if type=2 or type=6 then do; ';
|
||||
@@ -13647,7 +13802,6 @@ data _null_;
|
||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||
put ' run; ';
|
||||
put ' data &fmtds; ';
|
||||
put ' /* rename on entry */ ';
|
||||
@@ -13666,7 +13820,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put ' %let ds=&fmtds; ';
|
||||
put ' %end; /* &fmt=Y */ ';
|
||||
put ' data _null_;file &jref mod ; ';
|
||||
put ' data _null_;file &jref mod encoding=''utf-8''; ';
|
||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||
put ' proc sort ';
|
||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
||||
@@ -13750,7 +13904,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put '%end; ';
|
||||
put '%mend mp_jsonout; ';
|
||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); ';
|
||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y); ';
|
||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
||||
@@ -13888,8 +14042,9 @@ data _null_;
|
||||
put ' ods output Members=&tempds; ';
|
||||
put ' proc datasets library=WORK memtype=data; ';
|
||||
put ' %local wtcnt;%let wtcnt=0; ';
|
||||
put ' data _null_; set &tempds; ';
|
||||
put ' if not (name =:"DATA"); ';
|
||||
put ' data _null_; ';
|
||||
put ' set &tempds; ';
|
||||
put ' if not (upcase(name) =:"DATA"); /* ignore temp datasets */ ';
|
||||
put ' i+1; ';
|
||||
put ' call symputx(''wt''!!left(i),name); ';
|
||||
put ' call symputx(''wtcnt'',i); ';
|
||||
@@ -13929,17 +14084,19 @@ data _null_;
|
||||
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
|
||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||
put ' put "}"; ';
|
||||
put ' ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT %then %do; ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||
put ' data _null_; rc=fcopy("&fref","_webout");run; ';
|
||||
put ' %end; ';
|
||||
put ' ';
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%mend; ';
|
||||
put '%mend mv_webout; ';
|
||||
put ' ';
|
||||
put '%macro mf_getuser(type=META ';
|
||||
put ')/*/STORE SOURCE*/; ';
|
||||
@@ -14694,7 +14851,11 @@ libname &libref1 clear;
|
||||
|
||||
|
||||
@param root= The path for which to return the list of folders
|
||||
@param outds= The output dataset to create (default is work.mv_getfolders)
|
||||
@param outds= The output dataset to create (default is work.mv_getfolders). Format:
|
||||
|ordinal_root|ordinal_items|creationTimeStamp| modifiedTimeStamp|createdBy|modifiedBy|id| uri|added| type|name|description|
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
|1|1|2021-05-25T11:15:04.204Z|2021-05-25T11:15:04.204Z|allbow|allbow|4f1e3945-9655-462b-90f2-c31534b3ca47|/folders/folders/ed701ff3-77e8-468d-a4f5-8c43dec0fd9e|2021-05-25T11:15:04.212Z|child|my_folder_name|My folder Description|
|
||||
|
||||
@param access_token_var= The global macro variable to contain the access token
|
||||
@param grant_type= valid values are "password" or "authorization_code" (unquoted).
|
||||
The default is authorization_code.
|
||||
@@ -14802,7 +14963,7 @@ options noquotelenmax;
|
||||
filename &fname1 clear;
|
||||
libname &libref1 clear;
|
||||
|
||||
%mend;/**
|
||||
%mend mv_getfoldermembers;/**
|
||||
@file mv_getgroupmembers.sas
|
||||
@brief Creates a dataset with a list of group members
|
||||
@details First, be sure you have an access token (which requires an app token).
|
||||
@@ -17531,9 +17692,10 @@ filename &fref1 clear;
|
||||
@param action Either OPEN, ARR, OBJ or CLOSE
|
||||
@param ds The dataset to send back to the frontend
|
||||
@param _webout= fileref for returning the json
|
||||
@param fref= temp fref
|
||||
@param fref=(_mvwtemp) Temp fileref to which to write the output
|
||||
@param dslabel= value to use instead of the real name for sending to JSON
|
||||
@param fmt= change to N to strip formats from output
|
||||
@param fmt=(Y) change to N to strip formats from output
|
||||
@param stream=(Y) Change to N if not streaming to _webout
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mp_jsonout.sas
|
||||
@@ -17543,7 +17705,7 @@ filename &fref1 clear;
|
||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||
|
||||
**/
|
||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y);
|
||||
%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y);
|
||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||
sasjs_tables SYS_JES_JOB_URI;
|
||||
%if %index("&_debug",log) %then %let _debug=131;
|
||||
@@ -17681,8 +17843,9 @@ filename &fref1 clear;
|
||||
ods output Members=&tempds;
|
||||
proc datasets library=WORK memtype=data;
|
||||
%local wtcnt;%let wtcnt=0;
|
||||
data _null_; set &tempds;
|
||||
if not (name =:"DATA");
|
||||
data _null_;
|
||||
set &tempds;
|
||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||
i+1;
|
||||
call symputx('wt'!!left(i),name);
|
||||
call symputx('wtcnt',i);
|
||||
@@ -17722,17 +17885,19 @@ filename &fref1 clear;
|
||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||
put ",""SYSHOSTNAME"" : ""&syshostname"" ";
|
||||
put ",""SYSSITE"" : ""&syssite"" ";
|
||||
sysvlong=quote(trim(symget('sysvlong')));
|
||||
put ',"SYSVLONG" : ' sysvlong;
|
||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||
put "}";
|
||||
|
||||
%if %upcase(&fref) ne _WEBOUT %then %do;
|
||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||
data _null_; rc=fcopy("&fref","_webout");run;
|
||||
%end;
|
||||
|
||||
%end;
|
||||
|
||||
%mend;
|
||||
%mend mv_webout;
|
||||
/**
|
||||
@file ml_json.sas
|
||||
@brief Compiles the json.lua lua file
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
/**
|
||||
@file
|
||||
@brief to be deprecated
|
||||
@details We will deprecate this macro in 2022
|
||||
@brief Abort, ungracefully
|
||||
@details Will abort with a straightforward %abort if the condition is true.
|
||||
|
||||
As you can see, it's not a macro function.
|
||||
|
||||
Use mp_abort.sas instead.
|
||||
<h4> Related Macros </h4>
|
||||
@li mp_abort.sas
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
@cond
|
||||
**/
|
||||
|
||||
%macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
|
||||
%macro mf_abort(mac=mf_abort.sas, type=deprecated, msg=, iftrue=%str(1=1)
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||
@@ -21,116 +20,8 @@
|
||||
%if %length(&mac)>0 %then %put NOTE- called by &mac;
|
||||
%put NOTE - &msg;
|
||||
|
||||
/* Stored Process Server web app context */
|
||||
%if %symexist(_metaperson) or "&SYSPROCESSNAME"="Compute Server" %then %do;
|
||||
options obs=max replace nosyntaxcheck mprint;
|
||||
/* extract log err / warn, if exist */
|
||||
%local logloc logline;
|
||||
%global logmsg; /* capture global messages */
|
||||
%if %symexist(SYSPRINTTOLOG) %then %let logloc=&SYSPRINTTOLOG;
|
||||
%else %let logloc=%qsysfunc(getoption(LOG));
|
||||
proc printto log=log;run;
|
||||
%if %length(&logloc)>0 %then %do;
|
||||
%let logline=0;
|
||||
data _null_;
|
||||
infile &logloc lrecl=5000;
|
||||
input; putlog _infile_;
|
||||
i=1;
|
||||
retain logonce 0;
|
||||
if (
|
||||
_infile_=:"%str(WARN)ING" or _infile_=:"%str(ERR)OR"
|
||||
) and logonce=0
|
||||
then do;
|
||||
call symputx('logline',_n_);
|
||||
logonce+1;
|
||||
end;
|
||||
run;
|
||||
/* capture log including lines BEFORE the err */
|
||||
%if &logline>0 %then %do;
|
||||
data _null_;
|
||||
infile &logloc lrecl=5000;
|
||||
input;
|
||||
i=1;
|
||||
stoploop=0;
|
||||
if _n_ ge &logline-5 and stoploop=0 then do until (i>12);
|
||||
call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
|
||||
input;
|
||||
i+1;
|
||||
stoploop=1;
|
||||
end;
|
||||
if stoploop=1 then stop;
|
||||
run;
|
||||
%end;
|
||||
%end;
|
||||
%abort;
|
||||
|
||||
/* send response in SASjs JSON format */
|
||||
data _null_;
|
||||
file _webout mod lrecl=32000;
|
||||
length msg $32767;
|
||||
sasdatetime=datetime();
|
||||
msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
|
||||
/* escape the quotes */
|
||||
msg=tranwrd(msg,'"','\"');
|
||||
/* ditch the CRLFs as chrome complains */
|
||||
msg=compress(msg,,'kw');
|
||||
/* quote without quoting the quotes (which are escaped instead) */
|
||||
msg=cats('"',msg,'"');
|
||||
if symexist('_debug') then debug=symget('_debug');
|
||||
if debug ge 131 then put '>>weboutBEGIN<<';
|
||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
||||
put ',"sasjsAbort" : [{';
|
||||
put ' "MSG":' msg ;
|
||||
put ' ,"MAC": "' "&mac" '"}]';
|
||||
put ",""SYSUSERID"" : ""&sysuserid"" ";
|
||||
if symexist('_metauser') then do;
|
||||
_METAUSER=quote(trim(symget('_METAUSER')));
|
||||
put ",""_METAUSER"": " _METAUSER;
|
||||
_METAPERSON=quote(trim(symget('_METAPERSON')));
|
||||
put ',"_METAPERSON": ' _METAPERSON;
|
||||
end;
|
||||
_PROGRAM=quote(trim(resolve(symget('_PROGRAM'))));
|
||||
put ',"_PROGRAM" : ' _PROGRAM ;
|
||||
put ",""SYSCC"" : ""&syscc"" ";
|
||||
put ",""SYSERRORTEXT"" : ""&syserrortext"" ";
|
||||
put ",""SYSJOBID"" : ""&sysjobid"" ";
|
||||
put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" ";
|
||||
put ',"END_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '" ';
|
||||
put "}" @;
|
||||
%if &_debug ge 131 %then %do;
|
||||
put '>>weboutEND<<';
|
||||
%end;
|
||||
run;
|
||||
%let syscc=0;
|
||||
%if %symexist(SYS_JES_JOB_URI) %then %do;
|
||||
/* refer web service output to file service in one hit */
|
||||
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI"
|
||||
name="_webout.json";
|
||||
%let rc=%sysfunc(fcopy(_web,_webout));
|
||||
%end;
|
||||
%else %do;
|
||||
data _null_;
|
||||
if symexist('sysprocessmode')
|
||||
then if symget("sysprocessmode")="SAS Stored Process Server"
|
||||
then rc=stpsrvset('program error', 0);
|
||||
run;
|
||||
%end;
|
||||
/**
|
||||
* endsas is reliable but kills some deployments.
|
||||
* Abort variants are ungraceful (non zero return code)
|
||||
* This approach lets SAS run silently until the end :-)
|
||||
*/
|
||||
%put _all_;
|
||||
filename skip temp;
|
||||
data _null_;
|
||||
file skip;
|
||||
put '%macro skip(); %macro skippy();';
|
||||
run;
|
||||
%inc skip;
|
||||
%end;
|
||||
%else %do;
|
||||
%put _all_;
|
||||
%abort cancel;
|
||||
%end;
|
||||
%mend;
|
||||
%mend mf_abort;
|
||||
|
||||
/** @endcond */
|
||||
@@ -23,4 +23,4 @@
|
||||
%if %sysfunc(exist(&libds)) ne 1 & %sysfunc(exist(&libds,VIEW)) ne 1 %then 0;
|
||||
%else 1;
|
||||
|
||||
%mend;
|
||||
%mend mf_existds;
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
%let rc=%sysfunc(close(&dsid));
|
||||
%end;
|
||||
%else %do;
|
||||
%put unable to open &libds (rc=&dsid);
|
||||
%put &sysmacroname: Unable to open &libds (rc=&dsid);
|
||||
%put &sysmacroname: SYSMSG= %sysfunc(sysmsg());
|
||||
%let rc=%sysfunc(close(&dsid));
|
||||
%end;
|
||||
&outvar
|
||||
|
||||
@@ -102,7 +102,8 @@
|
||||
%let fmtds=%scan(&syslast,2,.);
|
||||
/* prepare formats and varnames */
|
||||
data _null_;
|
||||
set &fmtds end=last;
|
||||
if _n_=1 then call symputx('nobs',nobs,'l');
|
||||
set &fmtds end=last nobs=nobs;
|
||||
name=upcase(name);
|
||||
/* fix formats */
|
||||
if type=2 or type=6 then do;
|
||||
@@ -128,7 +129,6 @@
|
||||
call symputx(cats('len',_n_),newlen,'l');
|
||||
call symputx(cats('fmt',_n_),fmt,'l');
|
||||
call symputx(cats('type',_n_),type,'l');
|
||||
if last then call symputx('nobs',_n_,'l');
|
||||
run;
|
||||
data &fmtds;
|
||||
/* rename on entry */
|
||||
|
||||
7
main.dox
7
main.dox
@@ -42,6 +42,13 @@
|
||||
|
||||
*/
|
||||
|
||||
/*! \dir Tests
|
||||
* \brief SASjs Tests
|
||||
* \details These folders contain the macro tests. They are first compiled
|
||||
and deployed (sasjs cbd) then executed (sasjs test).
|
||||
|
||||
*/
|
||||
|
||||
/*! \dir viya
|
||||
* \brief Viya macros
|
||||
* \details These macros have the following attributes:
|
||||
|
||||
@@ -22,7 +22,7 @@ Usage:
|
||||
%webout(OBJ,example2) * Object format, easier to work with ;
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mm_createwebservice(path=/Public/app/common,name=appInit)
|
||||
%mm_createwebservice(path=/Public/app/common,name=appInit,code=ft15f001)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mm_createstp.sas
|
||||
@@ -37,12 +37,15 @@ Usage:
|
||||
@param desc= The description of the service (optional)
|
||||
@param precode= Space separated list of filerefs, pointing to the code that
|
||||
needs to be attached to the beginning of the service (optional)
|
||||
@param code= Space seperated fileref(s) of the actual code to be added
|
||||
@param server= The server which will run the STP. Server name or uri is fine.
|
||||
@param mDebug= set to 1 to show debug messages in the log
|
||||
@param replace= select YES to replace any existing service in that location
|
||||
@param adapter= the macro uses the sasjs adapter by default. To use another
|
||||
adapter, add a (different) fileref here.
|
||||
@param code=(ft15f001) Space seperated fileref(s) of the actual code to be
|
||||
added
|
||||
@param server=(SASApp) The server which will run the STP. Server name or uri
|
||||
is fine.
|
||||
@param mDebug=(0) set to 1 to show debug messages in the log
|
||||
@param replace=(YES) select NO to avoid replacing an existing service in that
|
||||
location
|
||||
@param adapter=(sasjs) the macro uses the sasjs adapter by default. To use
|
||||
another adapter, add a (different) fileref here.
|
||||
|
||||
@version 9.2
|
||||
@author Allan Bowe
|
||||
@@ -52,11 +55,11 @@ Usage:
|
||||
%macro mm_createwebservice(path=
|
||||
,name=initService
|
||||
,precode=
|
||||
,code=
|
||||
,code=ft15f001
|
||||
,desc=This stp was created automagically by the mm_createwebservice macro
|
||||
,mDebug=0
|
||||
,server=SASApp
|
||||
,replace=NO
|
||||
,replace=YES
|
||||
,adapter=sasjs
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
@@ -131,7 +134,8 @@ data _null_;
|
||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||
put ' /* prepare formats and varnames */ ';
|
||||
put ' data _null_; ';
|
||||
put ' set &fmtds end=last; ';
|
||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
||||
put ' set &fmtds end=last nobs=nobs; ';
|
||||
put ' name=upcase(name); ';
|
||||
put ' /* fix formats */ ';
|
||||
put ' if type=2 or type=6 then do; ';
|
||||
@@ -157,7 +161,6 @@ data _null_;
|
||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||
put ' run; ';
|
||||
put ' data &fmtds; ';
|
||||
put ' /* rename on entry */ ';
|
||||
@@ -176,7 +179,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put ' %let ds=&fmtds; ';
|
||||
put ' %end; /* &fmt=Y */ ';
|
||||
put ' data _null_;file &jref mod ; ';
|
||||
put ' data _null_;file &jref mod encoding=''utf-8''; ';
|
||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||
put ' proc sort ';
|
||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
||||
@@ -263,7 +266,12 @@ data _null_;
|
||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||
put ' sasjs_tables; ';
|
||||
put '%local i tempds; ';
|
||||
put '%local i tempds jsonengine; ';
|
||||
put ' ';
|
||||
put '/* see https://github.com/sasjs/core/issues/41 */ ';
|
||||
put '%if %upcase(&SYSENCODING)=WLATIN1 %then %let jsonengine=PROCJSON; ';
|
||||
put '%else %let jsonengine=DATASTEP; ';
|
||||
put ' ';
|
||||
put ' ';
|
||||
put '%if &action=FETCH %then %do; ';
|
||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
||||
@@ -298,7 +306,7 @@ data _null_;
|
||||
put ' OPTIONS NOBOMFILE; ';
|
||||
put ' ';
|
||||
put ' /** ';
|
||||
put ' * check engine type to avoid the below err message: ';
|
||||
put ' * check xengine type to avoid the below err message: ';
|
||||
put ' * > Function is only valid for filerefs using the CACHE access method. ';
|
||||
put ' */ ';
|
||||
put ' data _null_; ';
|
||||
@@ -319,8 +327,8 @@ data _null_;
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%else %if &action=ARR or &action=OBJ %then %do; ';
|
||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt ';
|
||||
put ' ,engine=DATASTEP,dbg=%str(&_debug) ';
|
||||
put ' %mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref ';
|
||||
put ' ,engine=&jsonengine,dbg=%str(&_debug) ';
|
||||
put ' ) ';
|
||||
put '%end; ';
|
||||
put '%else %if &action=CLOSE %then %do; ';
|
||||
@@ -333,7 +341,7 @@ data _null_;
|
||||
put ' %local wtcnt;%let wtcnt=0; ';
|
||||
put ' data _null_; ';
|
||||
put ' set &tempds; ';
|
||||
put ' if not (name =:"DATA"); ';
|
||||
put ' if not (upcase(name) =:"DATA"); /* ignore temp datasets */ ';
|
||||
put ' i+1; ';
|
||||
put ' call symputx(''wt''!!left(i),name,''l''); ';
|
||||
put ' call symputx(''wtcnt'',i,''l''); ';
|
||||
@@ -353,8 +361,8 @@ data _null_;
|
||||
put ' put " ""&wt"" : {"; ';
|
||||
put ' put ''"nlobs":'' nlobs; ';
|
||||
put ' put '',"nvars":'' nvars; ';
|
||||
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=DATASTEP) ';
|
||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=DATASTEP) ';
|
||||
put ' %mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine) ';
|
||||
put ' %mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine) ';
|
||||
put ' data _null_; file &fref mod encoding=''utf-8''; ';
|
||||
put ' put "}"; ';
|
||||
put ' %end; ';
|
||||
@@ -378,6 +386,8 @@ data _null_;
|
||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||
put ' put ",""SYSJOBID"" : ""&sysjobid"" "; ';
|
||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||
put ' put "}" @; ';
|
||||
@@ -387,7 +397,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%mend; ';
|
||||
put '%mend mm_webout; ';
|
||||
put ' ';
|
||||
put '%macro mf_getuser(type=META ';
|
||||
put ')/*/STORE SOURCE*/; ';
|
||||
@@ -466,4 +476,4 @@ run;
|
||||
%put &url?_PROGRAM=&path/&name;
|
||||
%put ;%put ;%put ;%put ;%put ;%put ;
|
||||
|
||||
%mend;
|
||||
%mend mm_createwebservice;
|
||||
|
||||
@@ -36,7 +36,12 @@
|
||||
%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y);
|
||||
%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug
|
||||
sasjs_tables;
|
||||
%local i tempds;
|
||||
%local i tempds jsonengine;
|
||||
|
||||
/* see https://github.com/sasjs/core/issues/41 */
|
||||
%if %upcase(&SYSENCODING)=WLATIN1 %then %let jsonengine=PROCJSON;
|
||||
%else %let jsonengine=DATASTEP;
|
||||
|
||||
|
||||
%if &action=FETCH %then %do;
|
||||
%if %str(&_debug) ge 131 %then %do;
|
||||
@@ -71,7 +76,7 @@
|
||||
OPTIONS NOBOMFILE;
|
||||
|
||||
/**
|
||||
* check engine type to avoid the below err message:
|
||||
* check xengine type to avoid the below err message:
|
||||
* > Function is only valid for filerefs using the CACHE access method.
|
||||
*/
|
||||
data _null_;
|
||||
@@ -93,7 +98,7 @@
|
||||
|
||||
%else %if &action=ARR or &action=OBJ %then %do;
|
||||
%mp_jsonout(&action,&ds,dslabel=&dslabel,fmt=&fmt,jref=&fref
|
||||
,engine=DATASTEP,dbg=%str(&_debug)
|
||||
,engine=&jsonengine,dbg=%str(&_debug)
|
||||
)
|
||||
%end;
|
||||
%else %if &action=CLOSE %then %do;
|
||||
@@ -106,7 +111,7 @@
|
||||
%local wtcnt;%let wtcnt=0;
|
||||
data _null_;
|
||||
set &tempds;
|
||||
if not (name =:"DATA");
|
||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||
i+1;
|
||||
call symputx('wt'!!left(i),name,'l');
|
||||
call symputx('wtcnt',i,'l');
|
||||
@@ -126,8 +131,8 @@
|
||||
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)
|
||||
%mp_jsonout(OBJ,&tempds,jref=&fref,dslabel=colattrs,engine=&jsonengine)
|
||||
%mp_jsonout(OBJ,&wt,jref=&fref,dslabel=first10rows,engine=&jsonengine)
|
||||
data _null_; file &fref mod encoding='utf-8';
|
||||
put "}";
|
||||
%end;
|
||||
|
||||
34
tests/viya/mfv_existfile.test.sas
Normal file
34
tests/viya/mfv_existfile.test.sas
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mfv_existfile macro function
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_uid.sas
|
||||
@li mfv_existfile.sas
|
||||
@li mp_assert.sas
|
||||
@li mv_createfile.sas
|
||||
|
||||
**/
|
||||
|
||||
options mprint sgen;
|
||||
|
||||
%let file=%mf_uid();
|
||||
|
||||
/* create a folder */
|
||||
filename somefile temp;
|
||||
data _null_;
|
||||
file somefile;
|
||||
put 'hello testings';
|
||||
run;
|
||||
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..txt,inref=somefile)
|
||||
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/&file..txt)=1),
|
||||
desc=Check if created file exists
|
||||
)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/%mf_uid().txt)=0),
|
||||
desc=Check if non created file does not exist
|
||||
)
|
||||
29
tests/viya/mfv_existfolder.test.sas
Normal file
29
tests/viya/mfv_existfolder.test.sas
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mfv_existfolder macro function
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_uid.sas
|
||||
@li mfv_existfolder.sas
|
||||
@li mp_assert.sas
|
||||
@li mv_createfolder.sas
|
||||
|
||||
**/
|
||||
|
||||
options mprint sgen;
|
||||
|
||||
%let folder=%mf_uid();
|
||||
|
||||
/* create a folder */
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&folder)
|
||||
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfolder(&mcTestAppLoc/temp/&folder)=1),
|
||||
desc=Check if created folder exists
|
||||
)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfolder(&mcTestAppLoc/temp/&folder/%mf_uid()/noway)=0),
|
||||
desc=Check if non created folder does not exist
|
||||
)
|
||||
42
tests/viya/mv_createfile.test.sas
Normal file
42
tests/viya/mv_createfile.test.sas
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mv_createfile macro
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_uid.sas
|
||||
@li mfv_existfile.sas
|
||||
@li mp_assert.sas
|
||||
@li mv_createfile.sas
|
||||
|
||||
|
||||
**/
|
||||
|
||||
options mprint;
|
||||
|
||||
%let file=%mf_uid();
|
||||
|
||||
%put TEST 1 - basic file upload ;
|
||||
filename somefile temp;
|
||||
data _null_;
|
||||
file somefile;
|
||||
put 'hello testings';
|
||||
run;
|
||||
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..txt,inref=somefile)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/&file..txt)=1),
|
||||
desc=Check if created file exists
|
||||
)
|
||||
|
||||
%put TEST 2 - dataset upload ;
|
||||
data temp;
|
||||
x=1;
|
||||
run;
|
||||
filename ds "%sysfunc(pathname(work))/temp.sas7bdat";
|
||||
|
||||
%mv_createfile(path=&mcTestAppLoc/temp, name=&file..sas7bdat,inref=ds)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mfv_existfile(&mcTestAppLoc/temp/&file..sas7bdat)=1),
|
||||
desc=Check if created dataset exists
|
||||
)
|
||||
32
tests/viya/mv_createfolder.test.sas
Normal file
32
tests/viya/mv_createfolder.test.sas
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mv_createfolder macro
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_uid.sas
|
||||
@li mp_assert.sas
|
||||
@li mv_createfolder.sas
|
||||
@li mv_deleteviyafolder.sas
|
||||
@li mv_getfoldermembers.sas
|
||||
|
||||
**/
|
||||
|
||||
|
||||
%let folder=%mf_uid();
|
||||
|
||||
/* create a folder */
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&folder/&folder)
|
||||
|
||||
%mv_getfoldermembers(root=&mcTestAppLoc/temp/&folder, outds=work.folders)
|
||||
|
||||
%let test=0;
|
||||
data _null_;
|
||||
set work.folders;
|
||||
putlog (_all_)(=);
|
||||
if name="&folder" then call symputx('test',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&test=1),
|
||||
desc=Check if temp folder can be successfully created
|
||||
)
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
**/
|
||||
|
||||
options mprint notes;
|
||||
|
||||
/**
|
||||
* Test Case 1
|
||||
*/
|
||||
|
||||
51
viya/mfv_existfile.sas
Normal file
51
viya/mfv_existfile.sas
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
@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
|
||||
attempting to assign a fileref with the filesrvc engine. If not found, the
|
||||
syscc is automatically set to a non zero value - so in this case it is reset.
|
||||
To avoid hiding issues, there is therefore a test at the start to ensure the
|
||||
syscc is zero.
|
||||
|
||||
Usage:
|
||||
|
||||
%put %mfv_existfile(/does/exist.txt);
|
||||
%put %mfv_existfile(/does/not/exist.txt);
|
||||
|
||||
@param filepath The full path to the file on SAS drive (eg /Public/myfile.txt)
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mfv_existfolder.sas
|
||||
|
||||
@version 3.5
|
||||
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
|
||||
**/
|
||||
|
||||
%macro mfv_existfile(filepath
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mf_abort(
|
||||
iftrue=(&syscc ne 0),
|
||||
msg=Cannot enter mfv_existfile.sas with syscc=&syscc
|
||||
)
|
||||
|
||||
%local fref rc path name;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
%let name=%scan(&filepath,-1,/);
|
||||
%let path=%substr(&filepath,1,%length(&filepath)-%length(&name)-1);
|
||||
|
||||
%if %sysfunc(filename(fref,,filesrvc,folderPath="&path" filename="&name"))=0
|
||||
%then %do;
|
||||
%sysfunc(fexist(&fref))
|
||||
%let rc=%sysfunc(filename(fref));
|
||||
%end;
|
||||
%else %do;
|
||||
0
|
||||
%let syscc=0;
|
||||
%end;
|
||||
|
||||
%mend mfv_existfile;
|
||||
48
viya/mfv_existfolder.sas
Normal file
48
viya/mfv_existfolder.sas
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
@file
|
||||
@brief Checks whether a folder exists in SAS Drive
|
||||
@details Returns 1 if the folder exists, and 0 if it doesn't. Works by
|
||||
attempting to assign a fileref with the filesrvc engine. If not found, the
|
||||
syscc is automatically set to a non zero value - so in this case it is reset.
|
||||
To avoid hiding issues, there is therefore a test at the start to ensure the
|
||||
syscc is zero.
|
||||
|
||||
Usage:
|
||||
|
||||
%put %mfv_existfolder(/does/exist);
|
||||
%put %mfv_existfolder(/does/not/exist);
|
||||
|
||||
@param path The path to the folder on SAS drive
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_abort.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
|
||||
<h4> Related Macros </h4>
|
||||
@li mfv_existfile.sas
|
||||
|
||||
@version 3.5
|
||||
@author [Allan Bowe](https://www.linkedin.com/in/allanbowe/)
|
||||
**/
|
||||
|
||||
%macro mfv_existfolder(path
|
||||
)/*/STORE SOURCE*/;
|
||||
|
||||
%mf_abort(
|
||||
iftrue=(&syscc ne 0),
|
||||
msg=Cannot enter mfv_existfolder.sas with syscc=&syscc
|
||||
)
|
||||
|
||||
%local fref rc;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
|
||||
%if %sysfunc(filename(fref,,filesrvc,folderPath="&path"))=0 %then %do;
|
||||
1
|
||||
%let rc=%sysfunc(filename(fref));
|
||||
%end;
|
||||
%else %do;
|
||||
0
|
||||
%let syscc=0;
|
||||
%end;
|
||||
|
||||
%mend mfv_existfolder;
|
||||
113
viya/mv_createfile.sas
Normal file
113
viya/mv_createfile.sas
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
@file
|
||||
@brief Creates a file in SAS Drive
|
||||
@details Creates a file in SAS Drive and adds the appropriate content type.
|
||||
If the parent folder does not exist, it is created.
|
||||
|
||||
Usage:
|
||||
|
||||
filename myfile temp;
|
||||
data _null_;
|
||||
file myfile;
|
||||
put 'something';
|
||||
run;
|
||||
%mv_createfile(path=/Public/temp,name=newfile.txt,inref=myfile)
|
||||
|
||||
|
||||
@param [in] path= The parent folder in which to create the file
|
||||
@param [in] name= The name of the file to be created
|
||||
@param [in] inref= The fileref pointing to the file to be uploaded
|
||||
@param [in] contentdisp= (inline) Content Disposition. Example values:
|
||||
@li inline
|
||||
@li attachment
|
||||
|
||||
@param [in] access_token_var= The global macro variable to contain the access
|
||||
token, if using authorization_code grant type.
|
||||
@param [in] grant_type= (sas_services) Valid values are:
|
||||
@li password
|
||||
@li authorization_code
|
||||
@li sas_services
|
||||
|
||||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||
|
||||
@version VIYA V.03.05
|
||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_isblank.sas
|
||||
@li mp_abort.sas
|
||||
@li mp_binarycopy.sas
|
||||
@li mv_createfolder.sas
|
||||
|
||||
**/
|
||||
|
||||
%macro mv_createfile(path=
|
||||
,name=
|
||||
,inref=
|
||||
,contentdisp=inline
|
||||
,access_token_var=ACCESS_TOKEN
|
||||
,grant_type=sas_services
|
||||
,mdebug=0
|
||||
);
|
||||
%local dbg;
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname entry vars:;
|
||||
%put _local_;
|
||||
%end;
|
||||
%else %let dbg=*;
|
||||
|
||||
%local oauth_bearer;
|
||||
%if &grant_type=detect %then %do;
|
||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||
%else %let grant_type=sas_services;
|
||||
%end;
|
||||
%if &grant_type=sas_services %then %do;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%end;
|
||||
|
||||
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
|
||||
and &grant_type ne sas_services
|
||||
)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(Invalid value for grant_type: &grant_type)
|
||||
)
|
||||
|
||||
%mp_abort(iftrue=(%mf_isblank(&path)=1 or %length(&path)=1)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(path value must be provided)
|
||||
)
|
||||
%mp_abort(iftrue=(%mf_isblank(&name)=1 or %length(&name)=1)
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(name value with length >1 must be provided)
|
||||
)
|
||||
|
||||
/* create folder if it does not already exist */
|
||||
%mv_createfolder(path=&path
|
||||
,access_token_var=&access_token_var
|
||||
,grant_type=&grant_type
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
|
||||
/* create file with relevant options */
|
||||
%local fref;
|
||||
%let fref=%mf_getuniquefileref();
|
||||
filename &fref filesrvc
|
||||
folderPath="&path"
|
||||
filename="&name"
|
||||
cdisp="&contentdisp";
|
||||
|
||||
%mp_binarycopy(inref=&inref, outref=&fref)
|
||||
|
||||
filename &fref clear;
|
||||
|
||||
%local base_uri; /* location of rest apis */
|
||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||
|
||||
%put &sysmacroname: File &name successfully created in &path;
|
||||
%put &sysmacroname:;%put;
|
||||
%put &base_uri/SASJobExecution?_file=&path/&name;%put;
|
||||
%put &sysmacroname:;
|
||||
|
||||
%mend mv_createfile;
|
||||
@@ -1,17 +1,22 @@
|
||||
/**
|
||||
@file mv_createfolder.sas
|
||||
@brief Creates a viya folder if that folder does not already exist
|
||||
@details Expects oauth token in a global macro variable (default
|
||||
ACCESS_TOKEN).
|
||||
@details Creates a viya folder by checking if each parent folder exists, and
|
||||
recursively creating children if needed.
|
||||
Usage:
|
||||
|
||||
%mv_createfolder(path=/Public)
|
||||
|
||||
|
||||
@param path= The full path of the folder to be created
|
||||
@param access_token_var= The global macro variable to contain the access token
|
||||
@param grant_type= (authorization_code) Valid values are "password" or
|
||||
"authorization_code" (unquoted).
|
||||
@param [in] path= The full path of the folder to be created
|
||||
@param [in] access_token_var= The global macro variable to contain the access
|
||||
token, if using authorization_code grant type.
|
||||
@param [in] grant_type= (sas_services) Valid values are:
|
||||
@li password
|
||||
@li authorization_code
|
||||
@li sas_services
|
||||
|
||||
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
||||
|
||||
@version VIYA V.03.04
|
||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||
@@ -22,21 +27,36 @@
|
||||
@li mf_getuniquelibref.sas
|
||||
@li mf_isblank.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mfv_existfolder.sas
|
||||
|
||||
|
||||
**/
|
||||
|
||||
%macro mv_createfolder(path=
|
||||
,access_token_var=ACCESS_TOKEN
|
||||
,grant_type=sas_services
|
||||
,mdebug=0
|
||||
);
|
||||
%local dbg;
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname entry vars:;
|
||||
%put _local_;
|
||||
%end;
|
||||
%else %let dbg=*;
|
||||
|
||||
%if %mfv_existfolder(&path)=1 %then %do;
|
||||
%put &sysmacroname: &path already exists;
|
||||
%return;
|
||||
%end;
|
||||
|
||||
%local oauth_bearer;
|
||||
%if &grant_type=detect %then %do;
|
||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||
%else %let grant_type=sas_services;
|
||||
%end;
|
||||
%if &grant_type=sas_services %then %do;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%let oauth_bearer=oauth_bearer=sas_services;
|
||||
%let &access_token_var=;
|
||||
%end;
|
||||
|
||||
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
|
||||
@@ -91,12 +111,21 @@ options noquotelenmax;
|
||||
,mac=&sysmacroname
|
||||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||
)
|
||||
%if &mdebug=1 %then %do;
|
||||
%put &sysmacroname following check to see if &newpath exists:;
|
||||
%put _local_;
|
||||
data _null_;
|
||||
set &fname1;
|
||||
input;
|
||||
putlog _infile_;
|
||||
run;
|
||||
%end;
|
||||
%if &SYS_PROCHTTP_STATUS_CODE=200 %then %do;
|
||||
%*put &sysmacroname &newpath exists so grab the follow on link ;
|
||||
data _null_;
|
||||
set &libref1..links;
|
||||
if rel='createChild' then
|
||||
call symputx('href',quote("&base_uri"!!trim(href)),'l');
|
||||
call symputx('href',quote(cats("&base_uri",href)),'l');
|
||||
run;
|
||||
%end;
|
||||
%else %if &SYS_PROCHTTP_STATUS_CODE=404 %then %do;
|
||||
@@ -140,8 +169,10 @@ options noquotelenmax;
|
||||
%put &sysmacroname &newpath now created. Grabbing the follow on link ;
|
||||
data _null_;
|
||||
set &libref2..links;
|
||||
if rel='createChild' then
|
||||
call symputx('href',quote(trim(href)),'l');
|
||||
if rel='createChild' then do;
|
||||
call symputx('href',quote(cats("&base_uri",href)),'l');
|
||||
&dbg put (_all_)(=);
|
||||
end;
|
||||
run;
|
||||
|
||||
libname &libref2 clear;
|
||||
@@ -150,4 +181,4 @@ options noquotelenmax;
|
||||
filename &fname1 clear;
|
||||
libname &libref1 clear;
|
||||
%end;
|
||||
%mend;
|
||||
%mend mv_createfolder;
|
||||
@@ -282,7 +282,8 @@ data _null_;
|
||||
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||
put ' /* prepare formats and varnames */ ';
|
||||
put ' data _null_; ';
|
||||
put ' set &fmtds end=last; ';
|
||||
put ' if _n_=1 then call symputx(''nobs'',nobs,''l''); ';
|
||||
put ' set &fmtds end=last nobs=nobs; ';
|
||||
put ' name=upcase(name); ';
|
||||
put ' /* fix formats */ ';
|
||||
put ' if type=2 or type=6 then do; ';
|
||||
@@ -308,7 +309,6 @@ data _null_;
|
||||
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||
put ' run; ';
|
||||
put ' data &fmtds; ';
|
||||
put ' /* rename on entry */ ';
|
||||
@@ -327,7 +327,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put ' %let ds=&fmtds; ';
|
||||
put ' %end; /* &fmt=Y */ ';
|
||||
put ' data _null_;file &jref mod ; ';
|
||||
put ' data _null_;file &jref mod encoding=''utf-8''; ';
|
||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||
put ' proc sort ';
|
||||
put ' data=sashelp.vcolumn(where=(libname=''WORK'' & memname="%upcase(&ds)")) ';
|
||||
@@ -411,7 +411,7 @@ data _null_;
|
||||
put ' run; ';
|
||||
put '%end; ';
|
||||
put '%mend mp_jsonout; ';
|
||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); ';
|
||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y); ';
|
||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
||||
@@ -549,8 +549,9 @@ data _null_;
|
||||
put ' ods output Members=&tempds; ';
|
||||
put ' proc datasets library=WORK memtype=data; ';
|
||||
put ' %local wtcnt;%let wtcnt=0; ';
|
||||
put ' data _null_; set &tempds; ';
|
||||
put ' if not (name =:"DATA"); ';
|
||||
put ' data _null_; ';
|
||||
put ' set &tempds; ';
|
||||
put ' if not (upcase(name) =:"DATA"); /* ignore temp datasets */ ';
|
||||
put ' i+1; ';
|
||||
put ' call symputx(''wt''!!left(i),name); ';
|
||||
put ' call symputx(''wtcnt'',i); ';
|
||||
@@ -590,17 +591,19 @@ data _null_;
|
||||
put ' put ",""SYSERRORTEXT"" : ""&syserrortext"" "; ';
|
||||
put ' put ",""SYSHOSTNAME"" : ""&syshostname"" "; ';
|
||||
put ' put ",""SYSSITE"" : ""&syssite"" "; ';
|
||||
put ' sysvlong=quote(trim(symget(''sysvlong''))); ';
|
||||
put ' put '',"SYSVLONG" : '' sysvlong; ';
|
||||
put ' put ",""SYSWARNINGTEXT"" : ""&syswarningtext"" "; ';
|
||||
put ' put '',"END_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''" ''; ';
|
||||
put ' put "}"; ';
|
||||
put ' ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT %then %do; ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||
put ' data _null_; rc=fcopy("&fref","_webout");run; ';
|
||||
put ' %end; ';
|
||||
put ' ';
|
||||
put '%end; ';
|
||||
put ' ';
|
||||
put '%mend; ';
|
||||
put '%mend mv_webout; ';
|
||||
put ' ';
|
||||
put '%macro mf_getuser(type=META ';
|
||||
put ')/*/STORE SOURCE*/; ';
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
|
||||
@param root= The path for which to return the list of folders
|
||||
@param outds= The output dataset to create (default is work.mv_getfolders)
|
||||
@param outds= The output dataset to create (default is work.mv_getfolders). Format:
|
||||
|ordinal_root|ordinal_items|creationTimeStamp| modifiedTimeStamp|createdBy|modifiedBy|id| uri|added| type|name|description|
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
|1|1|2021-05-25T11:15:04.204Z|2021-05-25T11:15:04.204Z|allbow|allbow|4f1e3945-9655-462b-90f2-c31534b3ca47|/folders/folders/ed701ff3-77e8-468d-a4f5-8c43dec0fd9e|2021-05-25T11:15:04.212Z|child|my_folder_name|My folder Description|
|
||||
|
||||
@param access_token_var= The global macro variable to contain the access token
|
||||
@param grant_type= valid values are "password" or "authorization_code" (unquoted).
|
||||
The default is authorization_code.
|
||||
@@ -116,4 +120,4 @@ options noquotelenmax;
|
||||
filename &fname1 clear;
|
||||
libname &libref1 clear;
|
||||
|
||||
%mend;
|
||||
%mend mv_getfoldermembers;
|
||||
@@ -174,8 +174,9 @@
|
||||
ods output Members=&tempds;
|
||||
proc datasets library=WORK memtype=data;
|
||||
%local wtcnt;%let wtcnt=0;
|
||||
data _null_; set &tempds;
|
||||
if not (name =:"DATA");
|
||||
data _null_;
|
||||
set &tempds;
|
||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||
i+1;
|
||||
call symputx('wt'!!left(i),name);
|
||||
call symputx('wtcnt',i);
|
||||
|
||||
Reference in New Issue
Block a user