mirror of
https://github.com/sasjs/core.git
synced 2026-06-09 04:10:20 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f484d10913 | |||
| 70efaf84e1 | |||
| 6c6c45b85c | |||
| 5453b76fe6 | |||
| c8e1126a40 | |||
| 872353dc8d | |||
| 9b44875142 | |||
| c5a681e6ed | |||
| a759aa9915 |
@@ -26312,13 +26312,13 @@ data _null_;
|
|||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
||||||
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
put '%if %index("&_debug",log) %then %let _debug=128; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%local i tempds table; ';
|
put '%local i tempds table; ';
|
||||||
put '%let action=%upcase(&action); ';
|
put '%let action=%upcase(&action); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=FETCH %then %do; ';
|
put '%if &action=FETCH %then %do; ';
|
||||||
put ' %if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 131 %then %do; ';
|
put ' %if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 128 %then %do; ';
|
||||||
put ' options mprint notes mprintnest; ';
|
put ' options mprint notes mprintnest; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -26381,7 +26381,7 @@ data _null_;
|
|||||||
put ' infile indata termstr=crlf lrecl=32767; ';
|
put ' infile indata termstr=crlf lrecl=32767; ';
|
||||||
put ' input; ';
|
put ' input; ';
|
||||||
put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
|
put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 128 %then %do; ';
|
||||||
put ' if _n_<20 then putlog _infile_; ';
|
put ' if _n_<20 then putlog _infile_; ';
|
||||||
put ' else stop; ';
|
put ' else stop; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -26414,7 +26414,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put ' /* setup json */ ';
|
put ' /* setup json */ ';
|
||||||
put ' data _null_;file &fref; ';
|
put ' data _null_;file &fref; ';
|
||||||
put ' %if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do; ';
|
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||||
put ' put ''>>weboutBEGIN<<''; ';
|
put ' put ''>>weboutBEGIN<<''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||||
@@ -26529,7 +26529,7 @@ data _null_;
|
|||||||
put ' memsize=quote(cats(memsize)); ';
|
put ' memsize=quote(cats(memsize)); ';
|
||||||
put ' put '',"MEMSIZE" : '' memsize; ';
|
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do; ';
|
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||||
put ' put ''>>weboutEND<<''; ';
|
put ' put ''>>weboutEND<<''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||||
@@ -29281,7 +29281,7 @@ run;
|
|||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_existvarlist.sas
|
@li mf_existvarlist.sas
|
||||||
@li mv_jobwaitfor.sas
|
@li mv_jobwaitfor.sas
|
||||||
@li mv_jobexecute.sas
|
@li mv_jobexecute.sas
|
||||||
@@ -29394,14 +29394,12 @@ data _null_;
|
|||||||
if last then call symputx('flowcnt',cnt,'l');
|
if last then call symputx('flowcnt',cnt,'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* prepare temporary datasets and frefs */
|
/* prepare temporary datasets */
|
||||||
%local fid jid jds jjson jdsapp jdsrunning jdswaitfor jfref;
|
%local fid jid jds jdsapp jdsrunning jdswaitfor;
|
||||||
data;run;%let jds=&syslast;
|
data;run;%let jds=&syslast;
|
||||||
data;run;%let jjson=&syslast;
|
|
||||||
data;run;%let jdsapp=&syslast;
|
data;run;%let jdsapp=&syslast;
|
||||||
data;run;%let jdsrunning=&syslast;
|
data;run;%let jdsrunning=&syslast;
|
||||||
data;run;%let jdswaitfor=&syslast;
|
data;run;%let jdswaitfor=&syslast;
|
||||||
%let jfref=%mf_getuniquefileref();
|
|
||||||
|
|
||||||
/* start loop */
|
/* start loop */
|
||||||
%do fid=1 %to &flowcnt;
|
%do fid=1 %to &flowcnt;
|
||||||
@@ -29419,23 +29417,39 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
&dbg. if _n_= 1 then putlog "Loop &fid";
|
&dbg. if _n_= 1 then putlog "Loop &fid";
|
||||||
&dbg. putlog (_all_)(=);
|
&dbg. putlog (_all_)(=);
|
||||||
run;
|
run;
|
||||||
|
/* build list of char and num vars in json format */
|
||||||
|
/* Viya 2026 expects all values to be strings */
|
||||||
|
%local nvars cvars ii _vnm;
|
||||||
|
%let cvars=%mf_getvarlist(&jds,typefilter=C);
|
||||||
|
%let nvars=%mf_getvarlist(&jds,typefilter=N);
|
||||||
%put exporting job variables in json format;
|
%put exporting job variables in json format;
|
||||||
%do jid=1 %to &jcnt;
|
%do jid=1 %to &jcnt;
|
||||||
data &jjson;
|
|
||||||
set &jds;
|
|
||||||
if _n_=&jid then do;
|
|
||||||
output;
|
|
||||||
stop;
|
|
||||||
end;
|
|
||||||
run;
|
|
||||||
proc json out=&jfref;
|
|
||||||
export &jjson / nosastags fmtnumeric;
|
|
||||||
run;
|
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &jfref lrecl=32767;
|
set &jds;
|
||||||
input;
|
if _n_=&jid;
|
||||||
jparams=cats('jparams',symget('jid'));
|
length _param $32767;
|
||||||
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
_param='';
|
||||||
|
%if %length(&cvars)>0 %then %do ii=1 %to %sysfunc(countw(&cvars,%str( )));
|
||||||
|
%let _vnm=%scan(&cvars,&ii,%str( ));
|
||||||
|
if _param ne '' then _param=cats(_param,',');
|
||||||
|
_param=cats(_param,'"'
|
||||||
|
,"%lowcase(&_vnm)"
|
||||||
|
,'":'
|
||||||
|
,quote(trim(&_vnm))
|
||||||
|
);
|
||||||
|
%end;
|
||||||
|
%if %length(&nvars)>0 %then %do ii=1 %to %sysfunc(countw(&nvars,%str( )));
|
||||||
|
%let _vnm=%scan(&nvars,&ii,%str( ));
|
||||||
|
if _param ne '' then _param=cats(_param,',');
|
||||||
|
_param=cats(_param,'"'
|
||||||
|
,"%lowcase(&_vnm)"
|
||||||
|
,'":"'
|
||||||
|
,strip(put(&_vnm,best32.))
|
||||||
|
,'"'
|
||||||
|
);
|
||||||
|
%end;
|
||||||
|
call symputx(cats('jparams',&jid),_param,'l');
|
||||||
|
stop;
|
||||||
run;
|
run;
|
||||||
%local jobuid&jid;
|
%local jobuid&jid;
|
||||||
%let jobuid&jid=0; /* used in next loop */
|
%let jobuid&jid=0; /* used in next loop */
|
||||||
@@ -29480,6 +29494,7 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
,paramstring=%superq(jparams&jid)
|
,paramstring=%superq(jparams&jid)
|
||||||
,outds=&jdsapp
|
,outds=&jdsapp
|
||||||
,contextname=&&context&jid
|
,contextname=&&context&jid
|
||||||
|
,mdebug=&mdebug
|
||||||
)
|
)
|
||||||
data &jdsapp;
|
data &jdsapp;
|
||||||
format jobparams $32767.;
|
format jobparams $32767.;
|
||||||
@@ -30443,13 +30458,13 @@ filename &fref1 clear;
|
|||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
||||||
%if %index("&_debug",log) %then %let _debug=131;
|
%if %index("&_debug",log) %then %let _debug=128;
|
||||||
|
|
||||||
%local i tempds table;
|
%local i tempds table;
|
||||||
%let action=%upcase(&action);
|
%let action=%upcase(&action);
|
||||||
|
|
||||||
%if &action=FETCH %then %do;
|
%if &action=FETCH %then %do;
|
||||||
%if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 131 %then %do;
|
%if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 128 %then %do;
|
||||||
options mprint notes mprintnest;
|
options mprint notes mprintnest;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
@@ -30512,7 +30527,7 @@ filename &fref1 clear;
|
|||||||
infile indata termstr=crlf lrecl=32767;
|
infile indata termstr=crlf lrecl=32767;
|
||||||
input;
|
input;
|
||||||
if _n_=1 then call symputx('input_statement',_infile_);
|
if _n_=1 then call symputx('input_statement',_infile_);
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&_debug) ge 128 %then %do;
|
||||||
if _n_<20 then putlog _infile_;
|
if _n_<20 then putlog _infile_;
|
||||||
else stop;
|
else stop;
|
||||||
%end;
|
%end;
|
||||||
@@ -30545,7 +30560,7 @@ filename &fref1 clear;
|
|||||||
|
|
||||||
/* setup json */
|
/* setup json */
|
||||||
data _null_;file &fref;
|
data _null_;file &fref;
|
||||||
%if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do;
|
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||||
put '>>weboutBEGIN<<';
|
put '>>weboutBEGIN<<';
|
||||||
%end;
|
%end;
|
||||||
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
@@ -30660,7 +30675,7 @@ filename &fref1 clear;
|
|||||||
memsize=quote(cats(memsize));
|
memsize=quote(cats(memsize));
|
||||||
put ',"MEMSIZE" : ' memsize;
|
put ',"MEMSIZE" : ' memsize;
|
||||||
put "}";
|
put "}";
|
||||||
%if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do;
|
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||||
put '>>weboutEND<<';
|
put '>>weboutEND<<';
|
||||||
%end;
|
%end;
|
||||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||||
@@ -31469,6 +31484,155 @@ endsub;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend mcf_string2file;/**
|
%mend mcf_string2file;/**
|
||||||
|
@file
|
||||||
|
@brief Appends a text file to a SASjs Stored Program, Viya SAS program, or
|
||||||
|
SAS 9 Stored Process
|
||||||
|
@details Extracts the source code from a SASjs Stored Program, Viya SAS
|
||||||
|
program (file in SAS Drive), or SAS 9 Stored Process, appends the contents
|
||||||
|
of a provided text file, then deletes and recreates the target item with the
|
||||||
|
combined content.
|
||||||
|
|
||||||
|
This is useful for dynamically modifying deployed programs, for example to
|
||||||
|
add test-specific configuration or runtime settings.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%* compile macros ;
|
||||||
|
filename mc url
|
||||||
|
"https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||||
|
%inc mc;
|
||||||
|
|
||||||
|
%* write some content to append;
|
||||||
|
filename append temp;
|
||||||
|
data _null_;
|
||||||
|
file append;
|
||||||
|
put "libname mylib '/some/path';";
|
||||||
|
run;
|
||||||
|
|
||||||
|
%* append to existing program;
|
||||||
|
%mx_append2pgm(/Public/app/common/settings, inref=append)
|
||||||
|
|
||||||
|
@param [in] loc The full path to the Viya SAS program, SAS 9 Stored Process,
|
||||||
|
or SASjs Stored Program in Drive or Metadata, WITHOUT the .sas extension
|
||||||
|
(SASjs only)
|
||||||
|
@param [in] inref= (0) Fileref pointing to the content to be appended to the
|
||||||
|
target program.
|
||||||
|
@param [in] mdebug= (0) Set to 1 to show debug messages in the log
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getplatform.sas
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mm_deletestp.sas
|
||||||
|
@li mm_getstpcode.sas
|
||||||
|
@li ms_createfile.sas
|
||||||
|
@li ms_deletefile.sas
|
||||||
|
@li mv_createfile.sas
|
||||||
|
@li mv_deletefoldermember.sas
|
||||||
|
@li mx_getcode.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mx_append2pgm.test.sas
|
||||||
|
@li mx_getcode.sas
|
||||||
|
@li mx_createjob.sas
|
||||||
|
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mx_append2pgm(loc
|
||||||
|
,inref=0
|
||||||
|
,mdebug=0
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%local platform name shortloc coderef combref work tmpfile viyaref;
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%if &syscc ne 0 %then %do;
|
||||||
|
%put syscc=&syscc - &sysmacroname will not execute in this state;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* extract name & path from loc */
|
||||||
|
data _null_;
|
||||||
|
length name shortloc $500;
|
||||||
|
loc=symget('loc');
|
||||||
|
name=scan(loc,-1,'/');
|
||||||
|
shortloc=substr(loc,1,length(loc)-length(name)-1);
|
||||||
|
call symputx('name',name,'l');
|
||||||
|
call symputx('shortloc',shortloc,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* create a combined fileref with original + appended content */
|
||||||
|
%let combref=%mf_getuniquefileref();
|
||||||
|
%let work=%sysfunc(pathname(work));
|
||||||
|
%let tmpfile=&combref..sas;
|
||||||
|
filename &combref "&work/&tmpfile" lrecl=32000;
|
||||||
|
|
||||||
|
%if &platform=SASVIYA %then %do;
|
||||||
|
/* On Viya, read the SAS program file from SAS Drive using filesrvc */
|
||||||
|
%let viyaref=%mf_getuniquefileref();
|
||||||
|
filename &viyaref filesrvc folderpath="&shortloc";
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf;
|
||||||
|
infile &viyaref("&name..sas") lrecl=32000 end=last;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
filename &viyaref clear;
|
||||||
|
%symdel _FILESRVC_&viyaref._URI;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* For SAS9 and SASJS, use mx_getcode */
|
||||||
|
%let coderef=%mf_getuniquefileref();
|
||||||
|
%mx_getcode(&loc, outref=&coderef)
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf;
|
||||||
|
infile &coderef lrecl=32000 end=last;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
filename &coderef clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* append the new content */
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf mod;
|
||||||
|
infile &inref lrecl=32000;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* delete and recreate the target item */
|
||||||
|
%if &platform=SASJS %then %do;
|
||||||
|
%ms_deletefile(&loc..sas)
|
||||||
|
%ms_createfile(&loc..sas, inref=&combref, mdebug=&mdebug)
|
||||||
|
%end;
|
||||||
|
%else %if &platform=SASVIYA %then %do;
|
||||||
|
%mv_deletefoldermember(path=&shortloc, name=&name..sas, contenttype=file)
|
||||||
|
%mv_createfile(path=&shortloc, name=&name..sas, inref=&combref)
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* SAS 9 */
|
||||||
|
%mm_deletestp(target=&loc)
|
||||||
|
%mm_createstp(stpname=&name
|
||||||
|
,filename=&tmpfile
|
||||||
|
,directory=&work
|
||||||
|
,tree=&shortloc
|
||||||
|
,stptype=2
|
||||||
|
,mDebug=&mdebug
|
||||||
|
,minify=NO
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
|
||||||
|
filename &combref clear;
|
||||||
|
|
||||||
|
%mend mx_append2pgm;
|
||||||
|
/**
|
||||||
@file mx_createjob.sas
|
@file mx_createjob.sas
|
||||||
@brief Create a job in SAS 9, Viya or SASjs
|
@brief Create a job in SAS 9, Viya or SASjs
|
||||||
@details Creates a Stored Process in SAS 9, a Job Execution Service in SAS
|
@details Creates a Stored Process in SAS 9, a Job Execution Service in SAS
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
/* location in metadata or SAS Drive for temporary files */
|
/* location in metadata or SAS Drive for temporary files */
|
||||||
%let mcTestAppLoc=/Users/&sysuserid/testresults/sasjs_core/%mf_uid();
|
%let mcTestAppLoc=/Users/&sysuserid/testresults/sasjs_core/%mf_uid();
|
||||||
|
|
||||||
|
%let mcTestContext=SAS Job Execution compute context;
|
||||||
|
|
||||||
/* set defaults */
|
/* set defaults */
|
||||||
%mp_init()
|
%mp_init()
|
||||||
|
|
||||||
@@ -23,6 +25,7 @@ options lrecl=80;
|
|||||||
|
|
||||||
%macro loglevel();
|
%macro loglevel();
|
||||||
%if "&_debug"="2477" or "&_debug"="fields,log,trace" or "&_debug"="131"
|
%if "&_debug"="2477" or "&_debug"="fields,log,trace" or "&_debug"="131"
|
||||||
|
or "&_debug"="128"
|
||||||
%then %do;
|
%then %do;
|
||||||
%put debug mode activated;
|
%put debug mode activated;
|
||||||
options mprint mprintnest;
|
options mprint mprintnest;
|
||||||
|
|||||||
@@ -33,19 +33,19 @@ data _null_;
|
|||||||
;
|
;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
%mv_createjob(path=&mcTestAppLoc,name=demo1,code=testprog)
|
||||||
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
%mv_createjob(path=&mcTestAppLoc,name=demo2,code=testprog)
|
||||||
|
|
||||||
data work.inputjobs;
|
data work.inputjobs;
|
||||||
_contextName='SAS Job Execution compute context';
|
_contextName="&mcTestContext";
|
||||||
do flow_id=1 to 2;
|
do flow_id=1 to 2;
|
||||||
do i=1 to 4;
|
do i=1 to 4;
|
||||||
_program='/Public/temp/demo1';
|
_program="&mcTestAppLoc/demo1";
|
||||||
macrovar1=10*i;
|
macrovar1=10*i;
|
||||||
macrovar2=4*i;
|
macrovar2=4*i;
|
||||||
output;
|
output;
|
||||||
i+1;
|
i+1;
|
||||||
_program='/Public/temp/demo2';
|
_program="&mcTestAppLoc/demo2";
|
||||||
macrovar1=40*i;
|
macrovar1=40*i;
|
||||||
macrovar2=44*i;
|
macrovar2=44*i;
|
||||||
output;
|
output;
|
||||||
|
|||||||
@@ -29,19 +29,19 @@ data _null_;
|
|||||||
;
|
;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
%mv_createjob(path=&mcTestAppLoc,name=demo1,code=testprog)
|
||||||
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
%mv_createjob(path=&mcTestAppLoc,name=demo2,code=testprog)
|
||||||
|
|
||||||
data work.inputjobs;
|
data work.inputjobs;
|
||||||
_contextName='SAS Job Execution compute context';
|
_contextName="&mcTestContext";
|
||||||
do flow_id=1 to 2;
|
do flow_id=1 to 2;
|
||||||
do i=1 to 4;
|
do i=1 to 4;
|
||||||
_program='/Public/temp/demo1';
|
_program="&mcTestAppLoc/demo1";
|
||||||
macrovar1=10*i;
|
macrovar1=10*i;
|
||||||
macrovar2=4*i;
|
macrovar2=4*i;
|
||||||
output;
|
output;
|
||||||
i+1;
|
i+1;
|
||||||
_program='/Public/temp/demo2';
|
_program="&mcTestAppLoc/demo2";
|
||||||
macrovar1=40*i;
|
macrovar1=40*i;
|
||||||
macrovar2=44*i;
|
macrovar2=44*i;
|
||||||
output;
|
output;
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mx_append2pgm.sas macro
|
||||||
|
|
||||||
|
Be sure to run <code>%let mcTestAppLoc=/Public/temp/macrocore;</code> when
|
||||||
|
running in Studio
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getplatform.sas
|
||||||
|
@li mf_uid.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
@li ms_createfile.sas
|
||||||
|
@li mv_createfile.sas
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mx_append2pgm.sas
|
||||||
|
@li mx_getcode.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 1 - Append content to an existing program and verify combined output
|
||||||
|
* Also checking for scope leakage
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* create a unique name for the program */
|
||||||
|
%let item=test_%mf_uid();
|
||||||
|
|
||||||
|
/* create the initial program with some code */
|
||||||
|
filename initpgm temp;
|
||||||
|
data _null_;
|
||||||
|
file initpgm;
|
||||||
|
put '%put ORIGINAL LINE;';
|
||||||
|
run;
|
||||||
|
|
||||||
|
%macro setup_pgm();
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
%if &platform=SASJS %then %do;
|
||||||
|
%ms_createfile(&mcTestAppLoc/temp/&item..sas, inref=initpgm)
|
||||||
|
%end;
|
||||||
|
%else %if &platform=SASVIYA %then %do;
|
||||||
|
%mv_createfile(path=&mcTestAppLoc/temp, name=&item..sas, inref=initpgm)
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%let work=%sysfunc(pathname(work));
|
||||||
|
data _null_;
|
||||||
|
file "&work/&item..sas";
|
||||||
|
infile initpgm;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
%mm_createstp(stpname=&item
|
||||||
|
,filename=&item..sas
|
||||||
|
,directory=&work
|
||||||
|
,tree=&mcTestAppLoc/temp
|
||||||
|
,stptype=2
|
||||||
|
,minify=NO
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
%mend setup_pgm;
|
||||||
|
%setup_pgm()
|
||||||
|
|
||||||
|
/* create the content to append */
|
||||||
|
filename toappnd temp;
|
||||||
|
data _null_;
|
||||||
|
file toappnd;
|
||||||
|
put '%put APPENDED LINE;';
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* run the macro under test with scope checks */
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mx_append2pgm(&mcTestAppLoc/temp/&item, inref=toappnd)
|
||||||
|
%mp_assertscope(COMPARE,
|
||||||
|
desc=Test 1: mx_append2pgm does not leak scope,
|
||||||
|
outds=work.test_results,
|
||||||
|
ignorelist=MC2_JADP1LEN MC2_JADP2LEN MC2_JADPNUM MC2_JADVLEN MC2_JADP3LEN
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=Test 1: No errors after appending content to program,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 2 - Verify the appended content is present
|
||||||
|
* Fetch the modified program and check both original and appended lines exist
|
||||||
|
*/
|
||||||
|
|
||||||
|
%let test2_orig=0;
|
||||||
|
%let test2_appd=0;
|
||||||
|
|
||||||
|
%macro verify_test2();
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
%if &platform=SASVIYA %then %do;
|
||||||
|
filename verifrf filesrvc folderpath="&mcTestAppLoc/temp";
|
||||||
|
data _null_;
|
||||||
|
infile verifrf("&item..sas") lrecl=32000;
|
||||||
|
input;
|
||||||
|
if index(_infile_,'ORIGINAL LINE') then call symputx('test2_orig','1');
|
||||||
|
if index(_infile_,'APPENDED LINE') then call symputx('test2_appd','1');
|
||||||
|
run;
|
||||||
|
filename verifrf clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%mx_getcode(&mcTestAppLoc/temp/&item, outref=verifrf)
|
||||||
|
data _null_;
|
||||||
|
infile verifrf lrecl=32000;
|
||||||
|
input;
|
||||||
|
if index(_infile_,'ORIGINAL LINE') then call symputx('test2_orig','1');
|
||||||
|
if index(_infile_,'APPENDED LINE') then call symputx('test2_appd','1');
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%mend verify_test2;
|
||||||
|
%verify_test2()
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test2_orig=1),
|
||||||
|
desc=Test 2a: Original content is preserved after append,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test2_appd=1),
|
||||||
|
desc=Test 2b: Appended content is present in modified program,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 3 - Append multiple times to ensure repeated appends work
|
||||||
|
*/
|
||||||
|
filename toappd2 temp;
|
||||||
|
data _null_;
|
||||||
|
file toappd2;
|
||||||
|
put '%put SECOND APPEND;';
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mx_append2pgm(&mcTestAppLoc/temp/&item, inref=toappd2)
|
||||||
|
%mp_assertscope(COMPARE,
|
||||||
|
desc=Test 3: mx_append2pgm does not leak scope on second call,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/* verify all three pieces of content exist */
|
||||||
|
%let test3_orig=0;
|
||||||
|
%let test3_appd=0;
|
||||||
|
%let test3_app2=0;
|
||||||
|
|
||||||
|
%macro verify_test3();
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
%if &platform=SASVIYA %then %do;
|
||||||
|
filename verifr2 filesrvc folderpath="&mcTestAppLoc/temp";
|
||||||
|
data _null_;
|
||||||
|
infile verifr2("&item..sas") lrecl=32000;
|
||||||
|
input;
|
||||||
|
if index(_infile_,'ORIGINAL LINE') then call symputx('test3_orig','1');
|
||||||
|
if index(_infile_,'APPENDED LINE') then call symputx('test3_appd','1');
|
||||||
|
if index(_infile_,'SECOND APPEND') then call symputx('test3_app2','1');
|
||||||
|
run;
|
||||||
|
filename verifr2 clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%mx_getcode(&mcTestAppLoc/temp/&item, outref=verifr2)
|
||||||
|
data _null_;
|
||||||
|
infile verifr2 lrecl=32000;
|
||||||
|
input;
|
||||||
|
if index(_infile_,'ORIGINAL LINE') then call symputx('test3_orig','1');
|
||||||
|
if index(_infile_,'APPENDED LINE') then call symputx('test3_appd','1');
|
||||||
|
if index(_infile_,'SECOND APPEND') then call symputx('test3_app2','1');
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%mend verify_test3;
|
||||||
|
%verify_test3()
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test3_orig=1),
|
||||||
|
desc=Test 3a: Original content still present after second append,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test3_appd=1),
|
||||||
|
desc=Test 3b: First appended content still present after second append,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&test3_app2=1),
|
||||||
|
desc=Test 3c: Second appended content is present,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -595,13 +595,13 @@ data _null_;
|
|||||||
put '); ';
|
put '); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
||||||
put '%if %index("&_debug",log) %then %let _debug=131; ';
|
put '%if %index("&_debug",log) %then %let _debug=128; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%local i tempds table; ';
|
put '%local i tempds table; ';
|
||||||
put '%let action=%upcase(&action); ';
|
put '%let action=%upcase(&action); ';
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%if &action=FETCH %then %do; ';
|
put '%if &action=FETCH %then %do; ';
|
||||||
put ' %if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 131 %then %do; ';
|
put ' %if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 128 %then %do; ';
|
||||||
put ' options mprint notes mprintnest; ';
|
put ' options mprint notes mprintnest; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' ';
|
put ' ';
|
||||||
@@ -664,7 +664,7 @@ data _null_;
|
|||||||
put ' infile indata termstr=crlf lrecl=32767; ';
|
put ' infile indata termstr=crlf lrecl=32767; ';
|
||||||
put ' input; ';
|
put ' input; ';
|
||||||
put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
|
put ' if _n_=1 then call symputx(''input_statement'',_infile_); ';
|
||||||
put ' %if %str(&_debug) ge 131 %then %do; ';
|
put ' %if %str(&_debug) ge 128 %then %do; ';
|
||||||
put ' if _n_<20 then putlog _infile_; ';
|
put ' if _n_<20 then putlog _infile_; ';
|
||||||
put ' else stop; ';
|
put ' else stop; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
@@ -697,7 +697,7 @@ data _null_;
|
|||||||
put ' ';
|
put ' ';
|
||||||
put ' /* setup json */ ';
|
put ' /* setup json */ ';
|
||||||
put ' data _null_;file &fref; ';
|
put ' data _null_;file &fref; ';
|
||||||
put ' %if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do; ';
|
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||||
put ' put ''>>weboutBEGIN<<''; ';
|
put ' put ''>>weboutBEGIN<<''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||||
@@ -812,7 +812,7 @@ data _null_;
|
|||||||
put ' memsize=quote(cats(memsize)); ';
|
put ' memsize=quote(cats(memsize)); ';
|
||||||
put ' put '',"MEMSIZE" : '' memsize; ';
|
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' %if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do; ';
|
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||||
put ' put ''>>weboutEND<<''; ';
|
put ' put ''>>weboutEND<<''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||||
|
|||||||
+34
-19
@@ -121,7 +121,7 @@
|
|||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_existvarlist.sas
|
@li mf_existvarlist.sas
|
||||||
@li mv_jobwaitfor.sas
|
@li mv_jobwaitfor.sas
|
||||||
@li mv_jobexecute.sas
|
@li mv_jobexecute.sas
|
||||||
@@ -234,14 +234,12 @@ data _null_;
|
|||||||
if last then call symputx('flowcnt',cnt,'l');
|
if last then call symputx('flowcnt',cnt,'l');
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* prepare temporary datasets and frefs */
|
/* prepare temporary datasets */
|
||||||
%local fid jid jds jjson jdsapp jdsrunning jdswaitfor jfref;
|
%local fid jid jds jdsapp jdsrunning jdswaitfor;
|
||||||
data;run;%let jds=&syslast;
|
data;run;%let jds=&syslast;
|
||||||
data;run;%let jjson=&syslast;
|
|
||||||
data;run;%let jdsapp=&syslast;
|
data;run;%let jdsapp=&syslast;
|
||||||
data;run;%let jdsrunning=&syslast;
|
data;run;%let jdsrunning=&syslast;
|
||||||
data;run;%let jdswaitfor=&syslast;
|
data;run;%let jdswaitfor=&syslast;
|
||||||
%let jfref=%mf_getuniquefileref();
|
|
||||||
|
|
||||||
/* start loop */
|
/* start loop */
|
||||||
%do fid=1 %to &flowcnt;
|
%do fid=1 %to &flowcnt;
|
||||||
@@ -259,23 +257,39 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
&dbg. if _n_= 1 then putlog "Loop &fid";
|
&dbg. if _n_= 1 then putlog "Loop &fid";
|
||||||
&dbg. putlog (_all_)(=);
|
&dbg. putlog (_all_)(=);
|
||||||
run;
|
run;
|
||||||
|
/* build list of char and num vars in json format */
|
||||||
|
/* Viya 2026 expects all values to be strings */
|
||||||
|
%local nvars cvars ii _vnm;
|
||||||
|
%let cvars=%mf_getvarlist(&jds,typefilter=C);
|
||||||
|
%let nvars=%mf_getvarlist(&jds,typefilter=N);
|
||||||
%put exporting job variables in json format;
|
%put exporting job variables in json format;
|
||||||
%do jid=1 %to &jcnt;
|
%do jid=1 %to &jcnt;
|
||||||
data &jjson;
|
|
||||||
set &jds;
|
|
||||||
if _n_=&jid then do;
|
|
||||||
output;
|
|
||||||
stop;
|
|
||||||
end;
|
|
||||||
run;
|
|
||||||
proc json out=&jfref;
|
|
||||||
export &jjson / nosastags fmtnumeric;
|
|
||||||
run;
|
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &jfref lrecl=32767;
|
set &jds;
|
||||||
input;
|
if _n_=&jid;
|
||||||
jparams=cats('jparams',symget('jid'));
|
length _param $32767;
|
||||||
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
_param='';
|
||||||
|
%if %length(&cvars)>0 %then %do ii=1 %to %sysfunc(countw(&cvars,%str( )));
|
||||||
|
%let _vnm=%scan(&cvars,&ii,%str( ));
|
||||||
|
if _param ne '' then _param=cats(_param,',');
|
||||||
|
_param=cats(_param,'"'
|
||||||
|
,"%lowcase(&_vnm)"
|
||||||
|
,'":'
|
||||||
|
,quote(trim(&_vnm))
|
||||||
|
);
|
||||||
|
%end;
|
||||||
|
%if %length(&nvars)>0 %then %do ii=1 %to %sysfunc(countw(&nvars,%str( )));
|
||||||
|
%let _vnm=%scan(&nvars,&ii,%str( ));
|
||||||
|
if _param ne '' then _param=cats(_param,',');
|
||||||
|
_param=cats(_param,'"'
|
||||||
|
,"%lowcase(&_vnm)"
|
||||||
|
,'":"'
|
||||||
|
,strip(put(&_vnm,best32.))
|
||||||
|
,'"'
|
||||||
|
);
|
||||||
|
%end;
|
||||||
|
call symputx(cats('jparams',&jid),_param,'l');
|
||||||
|
stop;
|
||||||
run;
|
run;
|
||||||
%local jobuid&jid;
|
%local jobuid&jid;
|
||||||
%let jobuid&jid=0; /* used in next loop */
|
%let jobuid&jid=0; /* used in next loop */
|
||||||
@@ -320,6 +334,7 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
,paramstring=%superq(jparams&jid)
|
,paramstring=%superq(jparams&jid)
|
||||||
,outds=&jdsapp
|
,outds=&jdsapp
|
||||||
,contextname=&&context&jid
|
,contextname=&&context&jid
|
||||||
|
,mdebug=&mdebug
|
||||||
)
|
)
|
||||||
data &jdsapp;
|
data &jdsapp;
|
||||||
format jobparams $32767.;
|
format jobparams $32767.;
|
||||||
|
|||||||
+5
-5
@@ -56,13 +56,13 @@
|
|||||||
);
|
);
|
||||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||||
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
||||||
%if %index("&_debug",log) %then %let _debug=131;
|
%if %index("&_debug",log) %then %let _debug=128;
|
||||||
|
|
||||||
%local i tempds table;
|
%local i tempds table;
|
||||||
%let action=%upcase(&action);
|
%let action=%upcase(&action);
|
||||||
|
|
||||||
%if &action=FETCH %then %do;
|
%if &action=FETCH %then %do;
|
||||||
%if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 131 %then %do;
|
%if %upcase(&_omittextlog)=FALSE or %str(&_debug) ge 128 %then %do;
|
||||||
options mprint notes mprintnest;
|
options mprint notes mprintnest;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
infile indata termstr=crlf lrecl=32767;
|
infile indata termstr=crlf lrecl=32767;
|
||||||
input;
|
input;
|
||||||
if _n_=1 then call symputx('input_statement',_infile_);
|
if _n_=1 then call symputx('input_statement',_infile_);
|
||||||
%if %str(&_debug) ge 131 %then %do;
|
%if %str(&_debug) ge 128 %then %do;
|
||||||
if _n_<20 then putlog _infile_;
|
if _n_<20 then putlog _infile_;
|
||||||
else stop;
|
else stop;
|
||||||
%end;
|
%end;
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
|
|
||||||
/* setup json */
|
/* setup json */
|
||||||
data _null_;file &fref;
|
data _null_;file &fref;
|
||||||
%if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do;
|
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||||
put '>>weboutBEGIN<<';
|
put '>>weboutBEGIN<<';
|
||||||
%end;
|
%end;
|
||||||
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
memsize=quote(cats(memsize));
|
memsize=quote(cats(memsize));
|
||||||
put ',"MEMSIZE" : ' memsize;
|
put ',"MEMSIZE" : ' memsize;
|
||||||
put "}";
|
put "}";
|
||||||
%if %str(&_debug) ge 131 and &_EXECUTIONTASKS=true %then %do;
|
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||||
put '>>weboutEND<<';
|
put '>>weboutEND<<';
|
||||||
%end;
|
%end;
|
||||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Appends a text file to a SASjs Stored Program, Viya SAS program, or
|
||||||
|
SAS 9 Stored Process
|
||||||
|
@details Extracts the source code from a SASjs Stored Program, Viya SAS
|
||||||
|
program (file in SAS Drive), or SAS 9 Stored Process, appends the contents
|
||||||
|
of a provided text file, then deletes and recreates the target item with the
|
||||||
|
combined content.
|
||||||
|
|
||||||
|
This is useful for dynamically modifying deployed programs, for example to
|
||||||
|
add test-specific configuration or runtime settings.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%* compile macros ;
|
||||||
|
filename mc url
|
||||||
|
"https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||||
|
%inc mc;
|
||||||
|
|
||||||
|
%* write some content to append;
|
||||||
|
filename append temp;
|
||||||
|
data _null_;
|
||||||
|
file append;
|
||||||
|
put "libname mylib '/some/path';";
|
||||||
|
run;
|
||||||
|
|
||||||
|
%* append to existing program;
|
||||||
|
%mx_append2pgm(/Public/app/common/settings, inref=append)
|
||||||
|
|
||||||
|
@param [in] loc The full path to the Viya SAS program, SAS 9 Stored Process,
|
||||||
|
or SASjs Stored Program in Drive or Metadata, WITHOUT the .sas extension
|
||||||
|
(SASjs only)
|
||||||
|
@param [in] inref= (0) Fileref pointing to the content to be appended to the
|
||||||
|
target program.
|
||||||
|
@param [in] mdebug= (0) Set to 1 to show debug messages in the log
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getplatform.sas
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mm_createstp.sas
|
||||||
|
@li mm_deletestp.sas
|
||||||
|
@li mm_getstpcode.sas
|
||||||
|
@li ms_createfile.sas
|
||||||
|
@li ms_deletefile.sas
|
||||||
|
@li mv_createfile.sas
|
||||||
|
@li mv_deletefoldermember.sas
|
||||||
|
@li mx_getcode.sas
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mx_append2pgm.test.sas
|
||||||
|
@li mx_getcode.sas
|
||||||
|
@li mx_createjob.sas
|
||||||
|
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mx_append2pgm(loc
|
||||||
|
,inref=0
|
||||||
|
,mdebug=0
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%local platform name shortloc coderef combref work tmpfile viyaref;
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%if &syscc ne 0 %then %do;
|
||||||
|
%put syscc=&syscc - &sysmacroname will not execute in this state;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* extract name & path from loc */
|
||||||
|
data _null_;
|
||||||
|
length name shortloc $500;
|
||||||
|
loc=symget('loc');
|
||||||
|
name=scan(loc,-1,'/');
|
||||||
|
shortloc=substr(loc,1,length(loc)-length(name)-1);
|
||||||
|
call symputx('name',name,'l');
|
||||||
|
call symputx('shortloc',shortloc,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* create a combined fileref with original + appended content */
|
||||||
|
%let combref=%mf_getuniquefileref();
|
||||||
|
%let work=%sysfunc(pathname(work));
|
||||||
|
%let tmpfile=&combref..sas;
|
||||||
|
filename &combref "&work/&tmpfile" lrecl=32000;
|
||||||
|
|
||||||
|
%if &platform=SASVIYA %then %do;
|
||||||
|
/* On Viya, read the SAS program file from SAS Drive using filesrvc */
|
||||||
|
%let viyaref=%mf_getuniquefileref();
|
||||||
|
filename &viyaref filesrvc folderpath="&shortloc";
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf;
|
||||||
|
infile &viyaref("&name..sas") lrecl=32000 end=last;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
filename &viyaref clear;
|
||||||
|
%symdel _FILESRVC_&viyaref._URI;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* For SAS9 and SASJS, use mx_getcode */
|
||||||
|
%let coderef=%mf_getuniquefileref();
|
||||||
|
%mx_getcode(&loc, outref=&coderef)
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf;
|
||||||
|
infile &coderef lrecl=32000 end=last;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
filename &coderef clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* append the new content */
|
||||||
|
data _null_;
|
||||||
|
file &combref lrecl=32000 termstr=crlf mod;
|
||||||
|
infile &inref lrecl=32000;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* delete and recreate the target item */
|
||||||
|
%if &platform=SASJS %then %do;
|
||||||
|
%ms_deletefile(&loc..sas)
|
||||||
|
%ms_createfile(&loc..sas, inref=&combref, mdebug=&mdebug)
|
||||||
|
%end;
|
||||||
|
%else %if &platform=SASVIYA %then %do;
|
||||||
|
%mv_deletefoldermember(path=&shortloc, name=&name..sas, contenttype=file)
|
||||||
|
%mv_createfile(path=&shortloc, name=&name..sas, inref=&combref)
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* SAS 9 */
|
||||||
|
%mm_deletestp(target=&loc)
|
||||||
|
%mm_createstp(stpname=&name
|
||||||
|
,filename=&tmpfile
|
||||||
|
,directory=&work
|
||||||
|
,tree=&shortloc
|
||||||
|
,stptype=2
|
||||||
|
,mDebug=&mdebug
|
||||||
|
,minify=NO
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
|
||||||
|
filename &combref clear;
|
||||||
|
|
||||||
|
%mend mx_append2pgm;
|
||||||
Reference in New Issue
Block a user