1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-05 00:20:05 +00:00

Compare commits

...

12 Commits

14 changed files with 187 additions and 3503 deletions

10
.gitpod.dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM gitpod/workspace-full
RUN sudo apt-get update \
&& sudo apt-get install -y \
doxygen \
&& npm i -g npm@latest \
&& npm i -g @sasjs/cli \
&& npm i \
&& sudo rm -rf /var/lib/apt/lists/*

8
.gitpod.yml Normal file
View File

@@ -0,0 +1,8 @@
tasks:
- init: npm i && clear
image:
file: .gitpod.dockerfile
vscode:
extensions:
- sasjs.sasjs-for-vscode@1.4.3:LY5VLf6H5R3u7nqVRnCQRw==

126
all.sas
View File

@@ -1426,12 +1426,12 @@ Usage:
%mend;/** %mend;/**
@file @file
@brief Creates a Unique ID based on system time in a friendly format @brief Creates a unique ID based on system time in friendly format
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits> @details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
%put %mf_uid(); %put %mf_uid();
@version 9.2 @version 9.3
@author Allan Bowe @author Allan Bowe
**/ **/
@@ -1440,7 +1440,7 @@ Usage:
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local today now; %local today now;
%let today=%sysfunc(today(),yymmddn8.); %let today=%sysfunc(today(),yymmddn8.);
%let now=%sysfunc(compress(%sysfunc(time(),time12.3),:.)); %let now=%sysfunc(compress(%sysfunc(time(),tod12.3),:.));
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL) &today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
@@ -10301,16 +10301,15 @@ run;
%end; %end;
%mend;/** %mend;/**
@file mm_updatestpservertype.sas @file
@brief Updates a type 2 stored process to run on STP or WKS context @brief Updates a type 2 stored process to run on STP or WKS context
@details Only works on Type 2 (9.3 compatible) STPs @details Only works on Type 2 (9.3 compatible) STPs
Usage: Usage:
%mm_updatestpservertype(target=/some/meta/path/myStoredProcess %mm_updatestpservertype(target=/some/meta/path/myStoredProcess
,type=WKS) ,type=WKS)
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted @param target= full path to the STP being deleted
@param type= Either WKS or STP depending on whether Workspace or Stored Process @param type= Either WKS or STP depending on whether Workspace or Stored Process
@@ -10375,31 +10374,40 @@ run;
Usage: Usage:
%mm_updatestpsourcecode(stp=/my/metadata/path/mystpname %mm_updatestpsourcecode(stp=/my/metadata/path/mystpname
,stpcode="/file/system/source.sas") ,stpcode="/file/system/source.sas")
@param [in] stp= the BIP Tree folder path plus Stored Process Name
@param stp= the BIP Tree folder path plus Stored Process Name @param [in] stpcode= the source file (or fileref) containing the SAS code to load
@param stpcode= the source file (or fileref) containing the SAS code to load
into the stp. For multiple files, they should simply be concatenated first. into the stp. For multiple files, they should simply be concatenated first.
@param minify= set to YES in order to strip comments, blank lines, and CRLFs. @param [in] minify= set to YES in order to strip comments, blank lines, and CRLFs.
@param frefin= change default inref if it clashes with an existing one @param frefin= deprecated - a unique fileref is now always used
@param frefout= change default outref if it clashes with an existing one @param frefout= deprecated - a unique fileref is now always used
@param mDebug= set to 1 to show debug messages in the log @param mDebug= set to 1 to show debug messages in the log
@version 9.3 @version 9.3
@author Allan Bowe @author Allan Bowe
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
**/ **/
%macro mm_updatestpsourcecode(stp= %macro mm_updatestpsourcecode(stp=
,stpcode= ,stpcode=
,minify=NO ,minify=NO
,mdebug=0
/* deprecated */
,frefin=inmeta ,frefin=inmeta
,frefout=outmeta ,frefout=outmeta
,mdebug=0
); );
%if &frefin ne inmeta or &frefout ne outmeta %then %do;
%put %str(WARN)ING: the frefin and frefout parameters will be deprecated in
an upcoming release.;
%end;
/* first, check if STP exists */ /* first, check if STP exists */
%local tsuri; %local tsuri;
%let tsuri=stopifempty ; %let tsuri=stopifempty ;
@@ -10437,7 +10445,9 @@ run;
%return; %return;
%end; %end;
filename &frefin temp lrecl=32767; %local frefin frefout;
%let frefin=%mf_getuniquefileref();
%let frefout=%mf_getuniquefileref();
/* write header XML */ /* write header XML */
data _null_; data _null_;
@@ -10450,7 +10460,7 @@ run;
/* write contents */ /* write contents */
%if %length(&stpcode)>2 %then %do; %if %length(&stpcode)>2 %then %do;
data _null_; data _null_;
file &frefin mod; file &frefin lrecl=32767 mod;
infile &stpcode lrecl=32767; infile &stpcode lrecl=32767;
length outstr $32767; length outstr $32767;
input outstr ; input outstr ;
@@ -10479,9 +10489,6 @@ data _null_;
</UpdateMetadata>"; </UpdateMetadata>";
run; run;
filename &frefout temp;
proc metadata in= &frefin out=&frefout; proc metadata in= &frefin out=&frefout;
run; run;
@@ -10493,6 +10500,10 @@ run;
put _infile_; put _infile_;
run; run;
%end; %end;
%else %do;
filename &frefin clear;
filename &frefout clear;
%end;
%mend;/** %mend;/**
@file mm_webout.sas @file mm_webout.sas
@@ -11153,23 +11164,23 @@ run;
rec = "20"x; rec = "20"x;
do while(fread(filein)=0); do while(fread(filein)=0);
rc = fget(filein,rec,1); rc = fget(filein,rec,1);
if rec='"' then do; if rec='"' then do; /* DOUBLE QUOTE */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'"');rc =fwrite(fileid); rc =fput(fileid,'"');rc =fwrite(fileid);
end; end;
else if rec='0A'x then do; else if rec='0A'x then do; /* LF */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='0D'x then do;
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'n');rc =fwrite(fileid); rc =fput(fileid,'n');rc =fwrite(fileid);
end; end;
else if rec='09'x then do; else if rec='0D'x then do; /* CR */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='09'x then do; /* TAB */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'t');rc =fwrite(fileid); rc =fput(fileid,'t');rc =fwrite(fileid);
end; end;
else if rec='5C'x then do; else if rec='5C'x then do; /* BACKSLASH */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
end; end;
@@ -11809,23 +11820,23 @@ run;
rec = "20"x; rec = "20"x;
do while(fread(filein)=0); do while(fread(filein)=0);
rc = fget(filein,rec,1); rc = fget(filein,rec,1);
if rec='"' then do; if rec='"' then do; /* DOUBLE QUOTE */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'"');rc =fwrite(fileid); rc =fput(fileid,'"');rc =fwrite(fileid);
end; end;
else if rec='0A'x then do; else if rec='0A'x then do; /* LF */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='0D'x then do;
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'n');rc =fwrite(fileid); rc =fput(fileid,'n');rc =fwrite(fileid);
end; end;
else if rec='09'x then do; else if rec='0D'x then do; /* CR */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='09'x then do; /* TAB */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'t');rc =fwrite(fileid); rc =fput(fileid,'t');rc =fwrite(fileid);
end; end;
else if rec='5C'x then do; else if rec='5C'x then do; /* BACKSLASH */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
end; end;
@@ -13899,6 +13910,8 @@ libname &libref;
@li sas_services - will use oauth_bearer=sas_services @li sas_services - will use oauth_bearer=sas_services
@param [in] inds= The input dataset containing a list of jobs and parameters @param [in] inds= The input dataset containing a list of jobs and parameters
@param [in] maxconcurrency= The max number of parallel jobs to run. Default=8. @param [in] maxconcurrency= The max number of parallel jobs to run. Default=8.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully
@param [in] mdebug= set to 1 to enable DEBUG messages @param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing the results @param [out] outds= The output dataset containing the results
@param [out] outref= The output fileref to which to append the log file(s). @param [out] outref= The output fileref to which to append the log file(s).
@@ -13922,6 +13935,7 @@ libname &libref;
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,outref=0 ,outref=0
,raise_err=0
,mdebug=0 ,mdebug=0
); );
%local oauth_bearer; %local oauth_bearer;
@@ -14100,7 +14114,8 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &jid=&jcnt %then %do; %if &jid=&jcnt %then %do;
/* we are at the end of the loop - time to see which jobs have finished */ /* we are at the end of the loop - time to see which jobs have finished */
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref) %mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref
,raise_err=&raise_err)
%local done; %local done;
%let done=%mf_nobs(&jdswaitfor); %let done=%mf_nobs(&jdswaitfor);
%if &done>0 %then %do; %if &done>0 %then %do;
@@ -14207,6 +14222,8 @@ data;run;%let jdswaitfor=&syslast;
following format: `/jobExecution/jobs/&JOBID./state` and the corresponding following format: `/jobExecution/jobs/&JOBID./state` and the corresponding
job name. The uri should be in a `uri` variable, and the job path/name job name. The uri should be in a `uri` variable, and the job path/name
should be in a `_program` variable. should be in a `_program` variable.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully
@param [out] outds= The output dataset containing the list of states by job @param [out] outds= The output dataset containing the list of states by job
(default=work.mv_jobexecute) (default=work.mv_jobexecute)
@param [out] outref= A fileref to which the spawned job logs should be appended. @param [out] outref= A fileref to which the spawned job logs should be appended.
@@ -14218,6 +14235,7 @@ data;run;%let jdswaitfor=&syslast;
@li mp_abort.sas @li mp_abort.sas
@li mf_getplatform.sas @li mf_getplatform.sas
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_existvar.sas @li mf_existvar.sas
@li mf_nobs.sas @li mf_nobs.sas
@li mv_getjoblog.sas @li mv_getjoblog.sas
@@ -14230,6 +14248,7 @@ data;run;%let jdswaitfor=&syslast;
,inds=0 ,inds=0
,outds=work.mv_jobwaitfor ,outds=work.mv_jobwaitfor
,outref=0 ,outref=0
,raise_err=0
); );
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
@@ -14273,7 +14292,7 @@ options noquotelenmax;
data _null_; data _null_;
length jobparams $32767; length jobparams $32767;
set &inds end=last; set &inds end=last;
call symputx(cats('joburi',_n_),substr(uri,1,55)!!'/state','l'); call symputx(cats('joburi',_n_),substr(uri,1,55),'l');
call symputx(cats('jobname',_n_),_program,'l'); call symputx(cats('jobname',_n_),_program,'l');
call symputx(cats('jobparams',_n_),jobparams,'l'); call symputx(cats('jobparams',_n_),jobparams,'l');
if last then call symputx('uricnt',_n_,'l'); if last then call symputx('uricnt',_n_,'l');
@@ -14288,7 +14307,7 @@ run;
%let fname0=%mf_getuniquefileref(); %let fname0=%mf_getuniquefileref();
data &outds; data &outds;
format _program uri $128. state $32. timestamp datetime19. jobparams $32767.; format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.;
stop; stop;
run; run;
@@ -14296,7 +14315,7 @@ run;
%do i=1 %to &uricnt; %do i=1 %to &uricnt;
%if "&&joburi&i" ne "0" %then %do; %if "&&joburi&i" ne "0" %then %do;
proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i"; proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i";
headers "Accept"="text/plain" headers "Accept"="application/json"
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; ; %end; ;
@@ -14310,12 +14329,20 @@ run;
%end; %end;
%let status=notset; %let status=notset;
%local libref1;
%let libref1=%mf_getuniquelibref();
libname &libref1 json fileref=&fname0;
data _null_; data _null_;
infile &fname0; length state stateDetails $32;
input; set &libref1..root;
call symputx('status',_infile_,'l'); call symputx('status',state,'l');
call symputx('stateDetails',stateDetails,'l');
run; run;
libname &libref1 clear;
%if &status=completed or &status=failed or &status=canceled %then %do; %if &status=completed or &status=failed or &status=canceled %then %do;
%local plainuri; %local plainuri;
%let plainuri=%substr(&&joburi&i,1,55); %let plainuri=%substr(&&joburi&i,1,55);
@@ -14324,6 +14351,7 @@ run;
_program="&&jobname&i", _program="&&jobname&i",
uri="&plainuri", uri="&plainuri",
state="&status", state="&status",
stateDetails=symget("stateDetails"),
timestamp=datetime(), timestamp=datetime(),
jobparams=symget("jobparams&i"); jobparams=symget("jobparams&i");
%let joburi&i=0; /* do not re-check */ %let joburi&i=0; /* do not re-check */
@@ -14342,6 +14370,16 @@ run;
,msg=%str(status &status not expected!!) ,msg=%str(status &status not expected!!)
) )
%end; %end;
%if (&raise_err) %then %do;
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do;
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
%else %let SYSCC=5;
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails;
%return;
%end;
%end;
%end; %end;
%if &i=&uricnt %then %do; %if &i=&uricnt %then %do;
%local goback; %local goback;

View File

@@ -1,11 +1,11 @@
/** /**
@file @file
@brief Creates a Unique ID based on system time in a friendly format @brief Creates a unique ID based on system time in friendly format
@details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits> @details format = YYYYMMDD_HHMMSSmmm_<sysjobid>_<3randomDigits>
%put %mf_uid(); %put %mf_uid();
@version 9.2 @version 9.3
@author Allan Bowe @author Allan Bowe
**/ **/
@@ -14,7 +14,7 @@
)/*/STORE SOURCE*/; )/*/STORE SOURCE*/;
%local today now; %local today now;
%let today=%sysfunc(today(),yymmddn8.); %let today=%sysfunc(today(),yymmddn8.);
%let now=%sysfunc(compress(%sysfunc(time(),time12.3),:.)); %let now=%sysfunc(compress(%sysfunc(time(),tod12.3),:.));
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL) &today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)

View File

@@ -1,14 +1,13 @@
/** /**
@file mm_updatestpservertype.sas @file
@brief Updates a type 2 stored process to run on STP or WKS context @brief Updates a type 2 stored process to run on STP or WKS context
@details Only works on Type 2 (9.3 compatible) STPs @details Only works on Type 2 (9.3 compatible) STPs
Usage: Usage:
%mm_updatestpservertype(target=/some/meta/path/myStoredProcess %mm_updatestpservertype(target=/some/meta/path/myStoredProcess
,type=WKS) ,type=WKS)
<h4> SAS Macros </h4>
@param target= full path to the STP being deleted @param target= full path to the STP being deleted
@param type= Either WKS or STP depending on whether Workspace or Stored Process @param type= Either WKS or STP depending on whether Workspace or Stored Process

View File

@@ -6,31 +6,40 @@
Usage: Usage:
%mm_updatestpsourcecode(stp=/my/metadata/path/mystpname %mm_updatestpsourcecode(stp=/my/metadata/path/mystpname
,stpcode="/file/system/source.sas") ,stpcode="/file/system/source.sas")
@param [in] stp= the BIP Tree folder path plus Stored Process Name
@param stp= the BIP Tree folder path plus Stored Process Name @param [in] stpcode= the source file (or fileref) containing the SAS code to load
@param stpcode= the source file (or fileref) containing the SAS code to load
into the stp. For multiple files, they should simply be concatenated first. into the stp. For multiple files, they should simply be concatenated first.
@param minify= set to YES in order to strip comments, blank lines, and CRLFs. @param [in] minify= set to YES in order to strip comments, blank lines, and CRLFs.
@param frefin= change default inref if it clashes with an existing one @param frefin= deprecated - a unique fileref is now always used
@param frefout= change default outref if it clashes with an existing one @param frefout= deprecated - a unique fileref is now always used
@param mDebug= set to 1 to show debug messages in the log @param mDebug= set to 1 to show debug messages in the log
@version 9.3 @version 9.3
@author Allan Bowe @author Allan Bowe
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
**/ **/
%macro mm_updatestpsourcecode(stp= %macro mm_updatestpsourcecode(stp=
,stpcode= ,stpcode=
,minify=NO ,minify=NO
,mdebug=0
/* deprecated */
,frefin=inmeta ,frefin=inmeta
,frefout=outmeta ,frefout=outmeta
,mdebug=0
); );
%if &frefin ne inmeta or &frefout ne outmeta %then %do;
%put %str(WARN)ING: the frefin and frefout parameters will be deprecated in
an upcoming release.;
%end;
/* first, check if STP exists */ /* first, check if STP exists */
%local tsuri; %local tsuri;
%let tsuri=stopifempty ; %let tsuri=stopifempty ;
@@ -68,7 +77,9 @@ run;
%return; %return;
%end; %end;
filename &frefin temp lrecl=32767; %local frefin frefout;
%let frefin=%mf_getuniquefileref();
%let frefout=%mf_getuniquefileref();
/* write header XML */ /* write header XML */
data _null_; data _null_;
@@ -81,7 +92,7 @@ run;
/* write contents */ /* write contents */
%if %length(&stpcode)>2 %then %do; %if %length(&stpcode)>2 %then %do;
data _null_; data _null_;
file &frefin mod; file &frefin lrecl=32767 mod;
infile &stpcode lrecl=32767; infile &stpcode lrecl=32767;
length outstr $32767; length outstr $32767;
input outstr ; input outstr ;
@@ -110,9 +121,6 @@ data _null_;
</UpdateMetadata>"; </UpdateMetadata>";
run; run;
filename &frefout temp;
proc metadata in= &frefin out=&frefout; proc metadata in= &frefin out=&frefout;
run; run;
@@ -124,5 +132,9 @@ run;
put _infile_; put _infile_;
run; run;
%end; %end;
%else %do;
filename &frefin clear;
filename &frefout clear;
%end;
%mend; %mend;

3408
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,9 +28,6 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"docs": "./sasjs/utils/build.sh" "docs": "sasjs doc && ./sasjs/utils/build.sh"
},
"devDependencies": {
"@sasjs/cli": "^2.4.0"
} }
} }

View File

@@ -4,6 +4,8 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=9" /> <meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta property="og:type" content="website">
<meta name="author" content="Allan Bowe">
<meta name="generator" content="Doxygen $doxygenversion" /> <meta name="generator" content="Doxygen $doxygenversion" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<!--BEGIN PROJECT_NAME--> <!--BEGIN PROJECT_NAME-->

View File

@@ -1,12 +1,9 @@
#!/bin/bash #!/bin/bash
#################################################################### ####################################################################
# PROJECT: Macro Core Docs Build # # PROJECT: Macro Core Docs Build #
# To execute, use the npm command (npm run docs) #
#################################################################### ####################################################################
cd ../..
sasjs doc
# refresh github pages site # refresh github pages site
rm -rf sasjsbuild/docsite rm -rf sasjsbuild/docsite
git clone git@github.com:sasjs/core.github.io.git sasjsbuild/docsite git clone git@github.com:sasjs/core.github.io.git sasjsbuild/docsite

View File

@@ -217,23 +217,23 @@ run;
rec = "20"x; rec = "20"x;
do while(fread(filein)=0); do while(fread(filein)=0);
rc = fget(filein,rec,1); rc = fget(filein,rec,1);
if rec='"' then do; if rec='"' then do; /* DOUBLE QUOTE */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'"');rc =fwrite(fileid); rc =fput(fileid,'"');rc =fwrite(fileid);
end; end;
else if rec='0A'x then do; else if rec='0A'x then do; /* LF */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='0D'x then do;
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'n');rc =fwrite(fileid); rc =fput(fileid,'n');rc =fwrite(fileid);
end; end;
else if rec='09'x then do; else if rec='0D'x then do; /* CR */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='09'x then do; /* TAB */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'t');rc =fwrite(fileid); rc =fput(fileid,'t');rc =fwrite(fileid);
end; end;
else if rec='5C'x then do; else if rec='5C'x then do; /* BACKSLASH */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
end; end;

View File

@@ -566,23 +566,23 @@ run;
rec = "20"x; rec = "20"x;
do while(fread(filein)=0); do while(fread(filein)=0);
rc = fget(filein,rec,1); rc = fget(filein,rec,1);
if rec='"' then do; if rec='"' then do; /* DOUBLE QUOTE */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'"');rc =fwrite(fileid); rc =fput(fileid,'"');rc =fwrite(fileid);
end; end;
else if rec='0A'x then do; else if rec='0A'x then do; /* LF */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='0D'x then do;
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'n');rc =fwrite(fileid); rc =fput(fileid,'n');rc =fwrite(fileid);
end; end;
else if rec='09'x then do; else if rec='0D'x then do; /* CR */
rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'r');rc =fwrite(fileid);
end;
else if rec='09'x then do; /* TAB */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'t');rc =fwrite(fileid); rc =fput(fileid,'t');rc =fwrite(fileid);
end; end;
else if rec='5C'x then do; else if rec='5C'x then do; /* BACKSLASH */
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
rc =fput(fileid,'\');rc =fwrite(fileid); rc =fput(fileid,'\');rc =fwrite(fileid);
end; end;

View File

@@ -106,6 +106,8 @@
@li sas_services - will use oauth_bearer=sas_services @li sas_services - will use oauth_bearer=sas_services
@param [in] inds= The input dataset containing a list of jobs and parameters @param [in] inds= The input dataset containing a list of jobs and parameters
@param [in] maxconcurrency= The max number of parallel jobs to run. Default=8. @param [in] maxconcurrency= The max number of parallel jobs to run. Default=8.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully
@param [in] mdebug= set to 1 to enable DEBUG messages @param [in] mdebug= set to 1 to enable DEBUG messages
@param [out] outds= The output dataset containing the results @param [out] outds= The output dataset containing the results
@param [out] outref= The output fileref to which to append the log file(s). @param [out] outref= The output fileref to which to append the log file(s).
@@ -129,6 +131,7 @@
,access_token_var=ACCESS_TOKEN ,access_token_var=ACCESS_TOKEN
,grant_type=sas_services ,grant_type=sas_services
,outref=0 ,outref=0
,raise_err=0
,mdebug=0 ,mdebug=0
); );
%local oauth_bearer; %local oauth_bearer;
@@ -307,7 +310,8 @@ data;run;%let jdswaitfor=&syslast;
%end; %end;
%if &jid=&jcnt %then %do; %if &jid=&jcnt %then %do;
/* we are at the end of the loop - time to see which jobs have finished */ /* we are at the end of the loop - time to see which jobs have finished */
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref) %mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref
,raise_err=&raise_err)
%local done; %local done;
%let done=%mf_nobs(&jdswaitfor); %let done=%mf_nobs(&jdswaitfor);
%if &done>0 %then %do; %if &done>0 %then %do;

View File

@@ -70,6 +70,8 @@
following format: `/jobExecution/jobs/&JOBID./state` and the corresponding following format: `/jobExecution/jobs/&JOBID./state` and the corresponding
job name. The uri should be in a `uri` variable, and the job path/name job name. The uri should be in a `uri` variable, and the job path/name
should be in a `_program` variable. should be in a `_program` variable.
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
succcessfully
@param [out] outds= The output dataset containing the list of states by job @param [out] outds= The output dataset containing the list of states by job
(default=work.mv_jobexecute) (default=work.mv_jobexecute)
@param [out] outref= A fileref to which the spawned job logs should be appended. @param [out] outref= A fileref to which the spawned job logs should be appended.
@@ -81,6 +83,7 @@
@li mp_abort.sas @li mp_abort.sas
@li mf_getplatform.sas @li mf_getplatform.sas
@li mf_getuniquefileref.sas @li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mf_existvar.sas @li mf_existvar.sas
@li mf_nobs.sas @li mf_nobs.sas
@li mv_getjoblog.sas @li mv_getjoblog.sas
@@ -93,6 +96,7 @@
,inds=0 ,inds=0
,outds=work.mv_jobwaitfor ,outds=work.mv_jobwaitfor
,outref=0 ,outref=0
,raise_err=0
); );
%local oauth_bearer; %local oauth_bearer;
%if &grant_type=detect %then %do; %if &grant_type=detect %then %do;
@@ -136,7 +140,7 @@ options noquotelenmax;
data _null_; data _null_;
length jobparams $32767; length jobparams $32767;
set &inds end=last; set &inds end=last;
call symputx(cats('joburi',_n_),substr(uri,1,55)!!'/state','l'); call symputx(cats('joburi',_n_),substr(uri,1,55),'l');
call symputx(cats('jobname',_n_),_program,'l'); call symputx(cats('jobname',_n_),_program,'l');
call symputx(cats('jobparams',_n_),jobparams,'l'); call symputx(cats('jobparams',_n_),jobparams,'l');
if last then call symputx('uricnt',_n_,'l'); if last then call symputx('uricnt',_n_,'l');
@@ -151,7 +155,7 @@ run;
%let fname0=%mf_getuniquefileref(); %let fname0=%mf_getuniquefileref();
data &outds; data &outds;
format _program uri $128. state $32. timestamp datetime19. jobparams $32767.; format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.;
stop; stop;
run; run;
@@ -159,7 +163,7 @@ run;
%do i=1 %to &uricnt; %do i=1 %to &uricnt;
%if "&&joburi&i" ne "0" %then %do; %if "&&joburi&i" ne "0" %then %do;
proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i"; proc http method='GET' out=&fname0 &oauth_bearer url="&base_uri/&&joburi&i";
headers "Accept"="text/plain" headers "Accept"="application/json"
%if &grant_type=authorization_code %then %do; %if &grant_type=authorization_code %then %do;
"Authorization"="Bearer &&&access_token_var" "Authorization"="Bearer &&&access_token_var"
%end; ; %end; ;
@@ -173,12 +177,20 @@ run;
%end; %end;
%let status=notset; %let status=notset;
%local libref1;
%let libref1=%mf_getuniquelibref();
libname &libref1 json fileref=&fname0;
data _null_; data _null_;
infile &fname0; length state stateDetails $32;
input; set &libref1..root;
call symputx('status',_infile_,'l'); call symputx('status',state,'l');
call symputx('stateDetails',stateDetails,'l');
run; run;
libname &libref1 clear;
%if &status=completed or &status=failed or &status=canceled %then %do; %if &status=completed or &status=failed or &status=canceled %then %do;
%local plainuri; %local plainuri;
%let plainuri=%substr(&&joburi&i,1,55); %let plainuri=%substr(&&joburi&i,1,55);
@@ -187,6 +199,7 @@ run;
_program="&&jobname&i", _program="&&jobname&i",
uri="&plainuri", uri="&plainuri",
state="&status", state="&status",
stateDetails=symget("stateDetails"),
timestamp=datetime(), timestamp=datetime(),
jobparams=symget("jobparams&i"); jobparams=symget("jobparams&i");
%let joburi&i=0; /* do not re-check */ %let joburi&i=0; /* do not re-check */
@@ -205,6 +218,16 @@ run;
,msg=%str(status &status not expected!!) ,msg=%str(status &status not expected!!)
) )
%end; %end;
%if (&raise_err) %then %do;
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do;
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
%else %let SYSCC=5;
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails;
%return;
%end;
%end;
%end; %end;
%if &i=&uricnt %then %do; %if &i=&uricnt %then %do;
%local goback; %local goback;