mirror of
https://github.com/sasjs/core.git
synced 2026-06-09 20:20:22 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f484d10913 | |||
| 70efaf84e1 | |||
| 6c6c45b85c | |||
| 5453b76fe6 | |||
| c8e1126a40 | |||
| 872353dc8d | |||
| 9b44875142 | |||
| c5a681e6ed | |||
| a759aa9915 | |||
| 1244aff5e4 | |||
| 4934e6675e | |||
| 5f5fb0116a | |||
| 9a725b9770 | |||
| 6c77556fdb | |||
| 0e37bff1ee | |||
| bb6aced478 | |||
| 96d42b9f66 | |||
| 59f8303b19 | |||
| 0599c4d597 | |||
| 356d3644e5 | |||
| ef7e8e051f | |||
| aa35317126 | |||
| f474076a41 | |||
| 98bd198dfc | |||
| 15e3a560b0 | |||
| 7448252b22 | |||
| 1fb52d5f73 | |||
| 0c90ac8deb | |||
| fdf0a1b514 | |||
| 4d15f4ebf5 | |||
| 402337a952 |
@@ -54,6 +54,7 @@ jobs:
|
||||
echo "REFRESH_TOKEN=${{secrets.SAS9_4GL_IO_REFRESH_TOKEN}}" >> .env.server
|
||||
|
||||
- name: Semantic Release
|
||||
id: makerelease
|
||||
uses: cycjimmy/semantic-release-action@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -64,3 +65,27 @@ jobs:
|
||||
npx @sasjs/cli compile job -s sasjs/utils/create_sas_package.sas -o sasjsbuild -t server
|
||||
# need long duration token per https://github.com/sasjs/server/issues/307
|
||||
# npx @sasjs/cli run sasjsbuild/jobs/utils/create_sas_package.sas -t server
|
||||
|
||||
- name: Update Docs Site
|
||||
if: steps.makerelease.outputs.new_release_published == 'true'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y doxygen
|
||||
npx @sasjs/cli doc -t docsonly
|
||||
git clone https://x-access-token:${{ secrets.CORESASJSIO_PAT }}@github.com/sasjs/core.github.io.git
|
||||
cd core.github.io
|
||||
rm -rf *.html
|
||||
rm -rf *.js
|
||||
rm -rf *.png
|
||||
rm -rf *.dot
|
||||
rm -rf *.css
|
||||
rm -rf *.svg
|
||||
rm -rf search
|
||||
cp -R ../sasjsbuild/docs/* .
|
||||
ls
|
||||
git config user.name sasjs
|
||||
echo 'core.sasjs.io' > CNAME
|
||||
git add .
|
||||
git commit -m "core pipeline build on $(date +%F:%H:%M:%S)"
|
||||
git push
|
||||
echo "check it out: https://sasjs.github.io/core.github.io/files.html"
|
||||
|
||||
@@ -26,6 +26,7 @@ jobs:
|
||||
git config user.email github-actions@github.com
|
||||
python3 build.py
|
||||
git add all.sas
|
||||
git add viya/mv_createwebservice.sas
|
||||
git commit -m "chore: updating all.sas" --allow-empty
|
||||
git push
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||

|
||||

|
||||
[](https://github.com/sasjs/core/issues?q=is%3Aissue+is%3Aclosed)
|
||||
[](https://github.com/sasjs/core/issues)
|
||||

|
||||
|
||||
|
||||
Much quality. Many standards. The **Macro Core** library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of [Application Development](https://sasapps.io) on the SAS platform (eg https://datacontroller.io). [Contributions](https://github.com/sasjs/core/blob/main/.github/CONTRIBUTING.md) are welcome.
|
||||
|
||||
@@ -25014,9 +25014,10 @@ run;
|
||||
|
||||
/* Get Viya file-extension details into some macro variables */
|
||||
%mv_getViyaFileExtParms(&ext
|
||||
,propertiesVar=viyaProperties
|
||||
,typeDefNameVar=viyaTypeDefName
|
||||
,mdebug=&mdebug);
|
||||
,propertiesVar=viyaProperties
|
||||
,typeDefNameVar=viyaTypeDefName
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
|
||||
/* fetch job info */
|
||||
%local fname1;
|
||||
@@ -25084,9 +25085,9 @@ run;
|
||||
|
||||
/* If properties were found then patch the file to include them */
|
||||
%if not %mf_isBlank(%superq(viyaProperties)) %then %do;
|
||||
/* Wrap the properties object in a root object also containing the file name */
|
||||
/* Wrap the properties object in a root object also containing the filename */
|
||||
%local viyapatch;
|
||||
%let viyapatch = %sysfunc(pathname(work))/%mf_getuniquename(prefix=patch_json_);
|
||||
%let viyapatch=%sysfunc(pathname(work))/%mf_getuniquename(prefix=patch_json_);
|
||||
data _null_;
|
||||
length line $32767;
|
||||
file "&viyapatch" lrecl=32767;
|
||||
@@ -25106,7 +25107,7 @@ run;
|
||||
run;
|
||||
%end;
|
||||
|
||||
/* And apply the properties to the newly created file, using the PATCH method */
|
||||
/* Apply the properties to the newly created file, using the PATCH method */
|
||||
%let fref=%mf_getuniquefileref();
|
||||
filename &fref "&viyapatch";
|
||||
%let url=&base_uri&fileuri;
|
||||
@@ -25290,7 +25291,6 @@ options noquotelenmax;
|
||||
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
|
||||
@@ -26311,14 +26311,14 @@ data _null_;
|
||||
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||
put '); ';
|
||||
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; ';
|
||||
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
||||
put '%if %index("&_debug",log) %then %let _debug=128; ';
|
||||
put ' ';
|
||||
put '%local i tempds table; ';
|
||||
put '%let action=%upcase(&action); ';
|
||||
put ' ';
|
||||
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 ' %end; ';
|
||||
put ' ';
|
||||
@@ -26326,6 +26326,11 @@ data _null_;
|
||||
put ' %let _webin_file_count=%eval(&_webin_file_count+0); ';
|
||||
put ' %let _webin_fileuri1=&_webin_fileuri; ';
|
||||
put ' %let _webin_name1=&_webin_name; ';
|
||||
put ' %if &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' /* TODO - remove this once SAS Track CS0409737 is resolved */ ';
|
||||
put ' /* links: https://github.com/sasjs/adapter/issues/884 */ ';
|
||||
put ' %if %upcase(&_webin_name)=_SASJS_NOOP %then %let _webin_file_count=0; ';
|
||||
put ' %end; ';
|
||||
put ' %end; ';
|
||||
put ' ';
|
||||
put ' /* if the sasjs_tables param is passed, we expect param based upload */ ';
|
||||
@@ -26366,13 +26371,17 @@ data _null_;
|
||||
put ' %end; ';
|
||||
put ' %else %do i=1 %to &_webin_file_count; ';
|
||||
put ' /* read in any files that are sent */ ';
|
||||
put ' /* this part needs refactoring for wide files */ ';
|
||||
put ' filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999; ';
|
||||
put ' %if &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' filename indata "%sysfunc(pathname(&&_webin_fileref&i))" lrecl=999999; ';
|
||||
put ' %end; ';
|
||||
put ' %else %do; ';
|
||||
put ' filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999; ';
|
||||
put ' %end; ';
|
||||
put ' data _null_; ';
|
||||
put ' infile indata termstr=crlf lrecl=32767; ';
|
||||
put ' input; ';
|
||||
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 ' else stop; ';
|
||||
put ' %end; ';
|
||||
@@ -26405,6 +26414,9 @@ data _null_;
|
||||
put ' ';
|
||||
put ' /* setup json */ ';
|
||||
put ' data _null_;file &fref; ';
|
||||
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' put ''>>weboutBEGIN<<''; ';
|
||||
put ' %end; ';
|
||||
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
||||
put ' run; ';
|
||||
@@ -26517,7 +26529,9 @@ data _null_;
|
||||
put ' memsize=quote(cats(memsize)); ';
|
||||
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||
put ' put "}"; ';
|
||||
put ' ';
|
||||
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' put ''>>weboutEND<<''; ';
|
||||
put ' %end; ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||
put ' data _null_; rc=fcopy("&fref","_webout");run; ';
|
||||
put ' %end; ';
|
||||
@@ -28727,6 +28741,7 @@ libname &libref1 clear;
|
||||
@li mf_existds.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_getuniquelibref.sas
|
||||
@li mf_getuniquename.sas
|
||||
@li mf_getvalue.sas
|
||||
@li mf_getvarlist.sas
|
||||
@@ -28752,7 +28767,7 @@ libname &libref1 clear;
|
||||
iftrue=(%mf_isBlank(&ext))
|
||||
,msg=%str(No file extension provided.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
%mp_abort(
|
||||
iftrue=(%mf_isBlank(&typeDefNameVar) and
|
||||
@@ -28760,13 +28775,13 @@ libname &libref1 clear;
|
||||
%mf_isBlank(&mediaTypeVar))
|
||||
,msg=%str(MV_GETVIYAFILEEXTPARMS - No parameter was requested.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
%mp_abort(
|
||||
iftrue=(%mf_isBlank(&viyaFileExtRespLibDs))
|
||||
,msg=%str(No <libname.>dataset name provided to cache inital response.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
/* Declare requested parameters as global macro vars and initialize blank */
|
||||
%if not %mf_isBlank(&typeDefNameVar) %then %do;
|
||||
@@ -28783,9 +28798,7 @@ libname &libref1 clear;
|
||||
%end;
|
||||
|
||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||
%if &mdebug=1 %then %do;
|
||||
%put DEBUG: &=base_uri;
|
||||
%end;
|
||||
%if &mdebug=1 %then %put DEBUG: &=base_uri;
|
||||
|
||||
%let ext=%lowcase(&ext);
|
||||
|
||||
@@ -28809,7 +28822,7 @@ libname &libref1 clear;
|
||||
|
||||
%if (&SYS_PROCHTTP_STATUS_CODE ne 200) %then %do;
|
||||
/* To avoid a breaking change, exit early if the request failed.
|
||||
The calling process will proceed with empty requested macro variables. */
|
||||
The calling process will proceed with empty macro variables. */
|
||||
%put INFO: &sysmacroname File extension details were not retrieved.;
|
||||
filename &viyatypedefs clear;
|
||||
%return;
|
||||
@@ -28830,11 +28843,12 @@ libname &libref1 clear;
|
||||
/* Convert the content of that JSON into SAS datasets */
|
||||
/* First prepare a new WORK-based folder to receive the datasets */
|
||||
%local jsonworkfolder jsonlib opt_dlcreatedir;
|
||||
%let jsonworkfolder=%sysfunc(pathname(work))/%mf_getuniquename(prefix=json_);
|
||||
%let jsonworkfolder=%sysfunc(pathname(work))/%mf_getuniquename(prefix=jsn_);
|
||||
%let jsonlib=%mf_getuniquelibref(prefix=json);
|
||||
/* And point a libname at it */
|
||||
/* And point a libname at it */
|
||||
%let opt_dlcreatedir = %sysfunc(getoption(dlcreatedir));
|
||||
options dlcreatedir; libname &jsonlib "&jsonworkfolder"; options &opt_dlcreatedir;
|
||||
options dlcreatedir; libname &jsonlib "&jsonworkfolder";
|
||||
options &opt_dlcreatedir;
|
||||
|
||||
/* Read the json output once and copy datasets to its work folder */
|
||||
%local libref1;
|
||||
@@ -28863,20 +28877,22 @@ libname &libref1 clear;
|
||||
|
||||
%end; /* If initial filetype query response didn't exist */
|
||||
|
||||
/* Find the row-group for the current file extension */
|
||||
%if &mdebug %then %put DEBUG: Find the row-group for extension &ext;
|
||||
%local itemRowGroup;
|
||||
%let itemRowGroup =
|
||||
%mf_getValue(
|
||||
&viyaFileExtRespLibDs
|
||||
,_viyaItemIdx
|
||||
,filter=%quote(p1='items' and p2='extensions' and value="&ext")
|
||||
);
|
||||
data _null_;
|
||||
set &viyaFileExtRespLibDs;
|
||||
where p1='items' and p2='extensions' and value="&ext";
|
||||
call symputx('itemRowGroup',_viyaItemIdx,'l');
|
||||
%if &mdebug %then %do;
|
||||
putlog (_all_)(=);
|
||||
%end;
|
||||
run;
|
||||
|
||||
%if &mdebug %then %put DEBUG: &=itemRowGroup;
|
||||
|
||||
%if %mf_isBlank(&itemRowGroup) %then %do;
|
||||
/* extension was not found */
|
||||
%if(&mdebug=1) %then %put DEBUG: No type details found for extension "&ext".;
|
||||
%if &mdebug %then %put DEBUG: No type details found for extension "&ext";
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -28890,14 +28906,17 @@ libname &libref1 clear;
|
||||
|
||||
/* Populate typeDefName, if requested */
|
||||
%if (not %mf_isBlank(&typeDefNameVar)) %then %do;
|
||||
%let &typeDefNameVar = %mf_getvalue(&dsItems,value,filter=%quote(p1="items" and p2="name"));
|
||||
%if &mdebug=1 %then %put DEBUG: &=typeDefNameVar &typeDefNameVar=&&&typeDefNameVar;
|
||||
%let &typeDefNameVar = %mf_getvalue(
|
||||
&dsItems,value,filter=%quote(p1="items" and p2="name"));
|
||||
%if &mdebug %then
|
||||
%put DEBUG: &=typeDefNameVar &typeDefNameVar=&&&typeDefNameVar;
|
||||
%end;
|
||||
|
||||
/* Populate mediaType, if requested */
|
||||
%if (not %mf_isBlank(&mediaTypeVar)) %then %do;
|
||||
%let &mediaTypeVar = %mf_getvalue(&dsItems,value,filter=%quote(p1="items" and p2="mediaType"));
|
||||
%if &mdebug=1 %then %put DEBUG: &=mediaTypeVar &mediaTypeVar=&&&mediaTypeVar;
|
||||
%let &mediaTypeVar = %mf_getvalue(
|
||||
&dsItems,value,filter=%quote(p1="items" and p2="mediaType"));
|
||||
%if &mdebug %then %put DEBUG: &=mediaTypeVar &mediaTypeVar=&&&mediaTypeVar;
|
||||
%end;
|
||||
|
||||
/* Populate properties macro variable, if requested */
|
||||
@@ -28914,7 +28933,8 @@ libname &libref1 clear;
|
||||
/* Check for 1+ properties */
|
||||
%if ( %mf_nobs(&dsProperties) = 0 ) %then %do;
|
||||
%let &propertiesVar = %str();
|
||||
%if &mdebug=1 %then %put DEBUG: &SYSMACRONAME - No Viya properties found for file suffix %str(%')&ext%str(%');
|
||||
%if &mdebug %then %put DEBUG: &SYSMACRONAME - No Viya properties %trim(
|
||||
)found for file suffix %str(%')&ext%str(%');
|
||||
%end;
|
||||
%else %do;
|
||||
/* Properties potentially span multiple rows in the input table */
|
||||
@@ -28944,7 +28964,8 @@ libname &libref1 clear;
|
||||
end;
|
||||
run;
|
||||
|
||||
%if &mdebug=1 %then %put DEBUG: &=propertiesVar &propertiesVar=&&&propertiesVar;
|
||||
%if &mdebug %then
|
||||
%put DEBUG: &=propertiesVar &propertiesVar=&&&propertiesVar;
|
||||
%end;
|
||||
|
||||
%end;
|
||||
@@ -29260,7 +29281,7 @@ run;
|
||||
@li mf_nobs.sas
|
||||
@li mp_abort.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_existvarlist.sas
|
||||
@li mv_jobwaitfor.sas
|
||||
@li mv_jobexecute.sas
|
||||
@@ -29373,14 +29394,12 @@ data _null_;
|
||||
if last then call symputx('flowcnt',cnt,'l');
|
||||
run;
|
||||
|
||||
/* prepare temporary datasets and frefs */
|
||||
%local fid jid jds jjson jdsapp jdsrunning jdswaitfor jfref;
|
||||
/* prepare temporary datasets */
|
||||
%local fid jid jds jdsapp jdsrunning jdswaitfor;
|
||||
data;run;%let jds=&syslast;
|
||||
data;run;%let jjson=&syslast;
|
||||
data;run;%let jdsapp=&syslast;
|
||||
data;run;%let jdsrunning=&syslast;
|
||||
data;run;%let jdswaitfor=&syslast;
|
||||
%let jfref=%mf_getuniquefileref();
|
||||
|
||||
/* start loop */
|
||||
%do fid=1 %to &flowcnt;
|
||||
@@ -29398,23 +29417,39 @@ data;run;%let jdswaitfor=&syslast;
|
||||
&dbg. if _n_= 1 then putlog "Loop &fid";
|
||||
&dbg. putlog (_all_)(=);
|
||||
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;
|
||||
%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_;
|
||||
infile &jfref lrecl=32767;
|
||||
input;
|
||||
jparams=cats('jparams',symget('jid'));
|
||||
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
||||
set &jds;
|
||||
if _n_=&jid;
|
||||
length _param $32767;
|
||||
_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;
|
||||
%local jobuid&jid;
|
||||
%let jobuid&jid=0; /* used in next loop */
|
||||
@@ -29459,6 +29494,7 @@ data;run;%let jdswaitfor=&syslast;
|
||||
,paramstring=%superq(jparams&jid)
|
||||
,outds=&jdsapp
|
||||
,contextname=&&context&jid
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
data &jdsapp;
|
||||
format jobparams $32767.;
|
||||
@@ -30421,14 +30457,14 @@ filename &fref1 clear;
|
||||
,showmeta=N,maxobs=MAX,workobs=0
|
||||
);
|
||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||
sasjs_tables SYS_JES_JOB_URI;
|
||||
%if %index("&_debug",log) %then %let _debug=131;
|
||||
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
||||
%if %index("&_debug",log) %then %let _debug=128;
|
||||
|
||||
%local i tempds table;
|
||||
%let action=%upcase(&action);
|
||||
|
||||
%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;
|
||||
%end;
|
||||
|
||||
@@ -30436,6 +30472,11 @@ filename &fref1 clear;
|
||||
%let _webin_file_count=%eval(&_webin_file_count+0);
|
||||
%let _webin_fileuri1=&_webin_fileuri;
|
||||
%let _webin_name1=&_webin_name;
|
||||
%if &_EXECUTIONTASKS=true %then %do;
|
||||
/* TODO - remove this once SAS Track CS0409737 is resolved */
|
||||
/* links: https://github.com/sasjs/adapter/issues/884 */
|
||||
%if %upcase(&_webin_name)=_SASJS_NOOP %then %let _webin_file_count=0;
|
||||
%end;
|
||||
%end;
|
||||
|
||||
/* if the sasjs_tables param is passed, we expect param based upload */
|
||||
@@ -30476,13 +30517,17 @@ filename &fref1 clear;
|
||||
%end;
|
||||
%else %do i=1 %to &_webin_file_count;
|
||||
/* read in any files that are sent */
|
||||
/* this part needs refactoring for wide files */
|
||||
filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999;
|
||||
%if &_EXECUTIONTASKS=true %then %do;
|
||||
filename indata "%sysfunc(pathname(&&_webin_fileref&i))" lrecl=999999;
|
||||
%end;
|
||||
%else %do;
|
||||
filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999;
|
||||
%end;
|
||||
data _null_;
|
||||
infile indata termstr=crlf lrecl=32767;
|
||||
input;
|
||||
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_;
|
||||
else stop;
|
||||
%end;
|
||||
@@ -30515,6 +30560,9 @@ filename &fref1 clear;
|
||||
|
||||
/* setup json */
|
||||
data _null_;file &fref;
|
||||
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||
put '>>weboutBEGIN<<';
|
||||
%end;
|
||||
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||
run;
|
||||
@@ -30627,7 +30675,9 @@ filename &fref1 clear;
|
||||
memsize=quote(cats(memsize));
|
||||
put ',"MEMSIZE" : ' memsize;
|
||||
put "}";
|
||||
|
||||
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||
put '>>weboutEND<<';
|
||||
%end;
|
||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||
data _null_; rc=fcopy("&fref","_webout");run;
|
||||
%end;
|
||||
@@ -31434,6 +31484,155 @@ endsub;
|
||||
%end;
|
||||
|
||||
%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
|
||||
@brief Create a job in SAS 9, Viya or SASjs
|
||||
@details Creates a Stored Process in SAS 9, a Job Execution Service in SAS
|
||||
|
||||
+5
-2
@@ -31,5 +31,8 @@
|
||||
"test": "npx @sasjs/cli test -t server",
|
||||
"lint": "npx @sasjs/cli lint",
|
||||
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
|
||||
}
|
||||
}
|
||||
},
|
||||
"maintainers": [
|
||||
"https://sasapps.io"
|
||||
]
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css" />
|
||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||
<script type="text/javascript" src="$relpath^cookie.js"></script>
|
||||
$treeview $search $mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
<link rel="shortcut icon" href="$relpath^favicon.ico" type="image/x-icon" />
|
||||
@@ -39,6 +40,10 @@
|
||||
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
|
||||
})();
|
||||
</script>
|
||||
<noscript>
|
||||
<p><img referrerpolicy="no-referrer-when-downgrade" src="https://analytics.4gl.io/matomo.php?idsite=6&rec=1"
|
||||
style="border:0;" alt="" /></p>
|
||||
</noscript>
|
||||
<!-- End Matomo Code -->
|
||||
</head>
|
||||
|
||||
@@ -79,8 +84,4 @@
|
||||
</table>
|
||||
</div>
|
||||
<!--END TITLEAREA-->
|
||||
<!-- end header part -->
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- end header part -->
|
||||
@@ -25,10 +25,7 @@
|
||||
},
|
||||
"testConfig": {
|
||||
"initProgram": "tests/testinit.sas",
|
||||
"termProgram": "tests/testterm.sas",
|
||||
"macroVars": {
|
||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
||||
}
|
||||
"termProgram": "tests/testterm.sas"
|
||||
},
|
||||
"defaultTarget": "server",
|
||||
"targets": [
|
||||
|
||||
+4
-1
@@ -10,7 +10,9 @@
|
||||
**/
|
||||
|
||||
/* location in metadata or SAS Drive for temporary files */
|
||||
%let mcTestAppLoc=/Public/testresults/sasjs_core/%mf_uid();
|
||||
%let mcTestAppLoc=/Users/&sysuserid/testresults/sasjs_core/%mf_uid();
|
||||
|
||||
%let mcTestContext=SAS Job Execution compute context;
|
||||
|
||||
/* set defaults */
|
||||
%mp_init()
|
||||
@@ -23,6 +25,7 @@ options lrecl=80;
|
||||
|
||||
%macro loglevel();
|
||||
%if "&_debug"="2477" or "&_debug"="fields,log,trace" or "&_debug"="131"
|
||||
or "&_debug"="128"
|
||||
%then %do;
|
||||
%put debug mode activated;
|
||||
options mprint mprintnest;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_uid.sas
|
||||
@li mp_assert.sas
|
||||
@li mp_assertscope.sas
|
||||
@li mv_createfolder.sas
|
||||
@li mv_deleteviyafolder.sas
|
||||
@li mv_getfoldermembers.sas
|
||||
@@ -15,7 +16,11 @@
|
||||
%let folder=%mf_uid();
|
||||
|
||||
/* create a folder */
|
||||
%mp_assertscope(SNAPSHOT)
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&folder/&folder)
|
||||
%mp_assertscope(COMPARE, ignorelist=MC0_JADP1LEN MC0_JADP2LEN MC0_JADPNUM
|
||||
MC0_JADVLEN MC2_JADP1LEN MC2_JADP2LEN MC2_JADPNUM MC2_JADVLEN
|
||||
)
|
||||
|
||||
%mv_getfoldermembers(root=&mcTestAppLoc/temp/&folder, outds=work.folders)
|
||||
|
||||
@@ -32,17 +37,39 @@ run;
|
||||
)
|
||||
|
||||
/* create a folder without output dataset as part of the original macro */
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&folder/folder2,outds=folders2)
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&folder/f2
|
||||
,outds=folders2,mdebug=&sasjs_mdebug
|
||||
)
|
||||
|
||||
%let test=0;
|
||||
data _null_;
|
||||
set work.folders2;
|
||||
putlog (_all_)(=);
|
||||
if not missing(self_uri) and not missing(parent_uri)
|
||||
then call symputx('test2',1);
|
||||
if not missing(self_uri) then call symputx('test2',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&test2=1),
|
||||
desc=Check if outds param works
|
||||
)
|
||||
|
||||
/* create a folder with full stops */
|
||||
%let newfolder=%mf_uid().2.1;
|
||||
%mv_createfolder(path=&mcTestAppLoc/temp/&newfolder
|
||||
,outds=work.folders3
|
||||
,mdebug=&sasjs_mdebug
|
||||
)
|
||||
|
||||
%mv_getfoldermembers(root=&mcTestAppLoc/temp, outds=work.folders3)
|
||||
|
||||
%let test3=0;
|
||||
data _null_;
|
||||
set work.folders3;
|
||||
putlog (_all_)(=);
|
||||
if name="&newfolder" then call symputx('test3',1);
|
||||
run;
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(&test3=1),
|
||||
desc=Check if folder with full stops can be successfully created
|
||||
)
|
||||
@@ -80,7 +80,7 @@ options mprint;
|
||||
typeDefNameVar=invalidTypeDefName,
|
||||
propertiesVar=invalidProperties,
|
||||
mediaTypeVar=invalidMediaType
|
||||
)
|
||||
)
|
||||
%mp_assertscope(COMPARE
|
||||
,ignorelist=
|
||||
&mvarIgnoreList invalidTypeDefName invalidProperties invalidMediaType
|
||||
|
||||
@@ -33,19 +33,19 @@ data _null_;
|
||||
;
|
||||
run;
|
||||
|
||||
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
||||
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
||||
%mv_createjob(path=&mcTestAppLoc,name=demo1,code=testprog)
|
||||
%mv_createjob(path=&mcTestAppLoc,name=demo2,code=testprog)
|
||||
|
||||
data work.inputjobs;
|
||||
_contextName='SAS Job Execution compute context';
|
||||
_contextName="&mcTestContext";
|
||||
do flow_id=1 to 2;
|
||||
do i=1 to 4;
|
||||
_program='/Public/temp/demo1';
|
||||
_program="&mcTestAppLoc/demo1";
|
||||
macrovar1=10*i;
|
||||
macrovar2=4*i;
|
||||
output;
|
||||
i+1;
|
||||
_program='/Public/temp/demo2';
|
||||
_program="&mcTestAppLoc/demo2";
|
||||
macrovar1=40*i;
|
||||
macrovar2=44*i;
|
||||
output;
|
||||
|
||||
@@ -29,19 +29,19 @@ data _null_;
|
||||
;
|
||||
run;
|
||||
|
||||
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
||||
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
||||
%mv_createjob(path=&mcTestAppLoc,name=demo1,code=testprog)
|
||||
%mv_createjob(path=&mcTestAppLoc,name=demo2,code=testprog)
|
||||
|
||||
data work.inputjobs;
|
||||
_contextName='SAS Job Execution compute context';
|
||||
_contextName="&mcTestContext";
|
||||
do flow_id=1 to 2;
|
||||
do i=1 to 4;
|
||||
_program='/Public/temp/demo1';
|
||||
_program="&mcTestAppLoc/demo1";
|
||||
macrovar1=10*i;
|
||||
macrovar2=4*i;
|
||||
output;
|
||||
i+1;
|
||||
_program='/Public/temp/demo2';
|
||||
_program="&mcTestAppLoc/demo2";
|
||||
macrovar1=40*i;
|
||||
macrovar2=44*i;
|
||||
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
|
||||
)
|
||||
@@ -204,9 +204,10 @@ run;
|
||||
|
||||
/* Get Viya file-extension details into some macro variables */
|
||||
%mv_getViyaFileExtParms(&ext
|
||||
,propertiesVar=viyaProperties
|
||||
,typeDefNameVar=viyaTypeDefName
|
||||
,mdebug=&mdebug);
|
||||
,propertiesVar=viyaProperties
|
||||
,typeDefNameVar=viyaTypeDefName
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
|
||||
/* fetch job info */
|
||||
%local fname1;
|
||||
@@ -274,9 +275,9 @@ run;
|
||||
|
||||
/* If properties were found then patch the file to include them */
|
||||
%if not %mf_isBlank(%superq(viyaProperties)) %then %do;
|
||||
/* Wrap the properties object in a root object also containing the file name */
|
||||
/* Wrap the properties object in a root object also containing the filename */
|
||||
%local viyapatch;
|
||||
%let viyapatch = %sysfunc(pathname(work))/%mf_getuniquename(prefix=patch_json_);
|
||||
%let viyapatch=%sysfunc(pathname(work))/%mf_getuniquename(prefix=patch_json_);
|
||||
data _null_;
|
||||
length line $32767;
|
||||
file "&viyapatch" lrecl=32767;
|
||||
@@ -296,7 +297,7 @@ run;
|
||||
run;
|
||||
%end;
|
||||
|
||||
/* And apply the properties to the newly created file, using the PATCH method */
|
||||
/* Apply the properties to the newly created file, using the PATCH method */
|
||||
%let fref=%mf_getuniquefileref();
|
||||
filename &fref "&viyapatch";
|
||||
%let url=&base_uri&fileuri;
|
||||
|
||||
@@ -145,7 +145,6 @@ options noquotelenmax;
|
||||
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
|
||||
|
||||
@@ -594,14 +594,14 @@ data _null_;
|
||||
put ' ,showmeta=N,maxobs=MAX,workobs=0 ';
|
||||
put '); ';
|
||||
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; ';
|
||||
put ' sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS; ';
|
||||
put '%if %index("&_debug",log) %then %let _debug=128; ';
|
||||
put ' ';
|
||||
put '%local i tempds table; ';
|
||||
put '%let action=%upcase(&action); ';
|
||||
put ' ';
|
||||
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 ' %end; ';
|
||||
put ' ';
|
||||
@@ -609,6 +609,11 @@ data _null_;
|
||||
put ' %let _webin_file_count=%eval(&_webin_file_count+0); ';
|
||||
put ' %let _webin_fileuri1=&_webin_fileuri; ';
|
||||
put ' %let _webin_name1=&_webin_name; ';
|
||||
put ' %if &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' /* TODO - remove this once SAS Track CS0409737 is resolved */ ';
|
||||
put ' /* links: https://github.com/sasjs/adapter/issues/884 */ ';
|
||||
put ' %if %upcase(&_webin_name)=_SASJS_NOOP %then %let _webin_file_count=0; ';
|
||||
put ' %end; ';
|
||||
put ' %end; ';
|
||||
put ' ';
|
||||
put ' /* if the sasjs_tables param is passed, we expect param based upload */ ';
|
||||
@@ -649,13 +654,17 @@ data _null_;
|
||||
put ' %end; ';
|
||||
put ' %else %do i=1 %to &_webin_file_count; ';
|
||||
put ' /* read in any files that are sent */ ';
|
||||
put ' /* this part needs refactoring for wide files */ ';
|
||||
put ' filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999; ';
|
||||
put ' %if &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' filename indata "%sysfunc(pathname(&&_webin_fileref&i))" lrecl=999999; ';
|
||||
put ' %end; ';
|
||||
put ' %else %do; ';
|
||||
put ' filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999; ';
|
||||
put ' %end; ';
|
||||
put ' data _null_; ';
|
||||
put ' infile indata termstr=crlf lrecl=32767; ';
|
||||
put ' input; ';
|
||||
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 ' else stop; ';
|
||||
put ' %end; ';
|
||||
@@ -688,6 +697,9 @@ data _null_;
|
||||
put ' ';
|
||||
put ' /* setup json */ ';
|
||||
put ' data _null_;file &fref; ';
|
||||
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' put ''>>weboutBEGIN<<''; ';
|
||||
put ' %end; ';
|
||||
put ' put ''{"SYSDATE" : "'' "&SYSDATE" ''"''; ';
|
||||
put ' put '',"SYSTIME" : "'' "&SYSTIME" ''"''; ';
|
||||
put ' run; ';
|
||||
@@ -800,7 +812,9 @@ data _null_;
|
||||
put ' memsize=quote(cats(memsize)); ';
|
||||
put ' put '',"MEMSIZE" : '' memsize; ';
|
||||
put ' put "}"; ';
|
||||
put ' ';
|
||||
put ' %if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do; ';
|
||||
put ' put ''>>weboutEND<<''; ';
|
||||
put ' %end; ';
|
||||
put ' %if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do; ';
|
||||
put ' data _null_; rc=fcopy("&fref","_webout");run; ';
|
||||
put ' %end; ';
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@li mf_existds.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_getuniquelibref.sas
|
||||
@li mf_getuniquename.sas
|
||||
@li mf_getvalue.sas
|
||||
@li mf_getvarlist.sas
|
||||
@@ -48,7 +49,7 @@
|
||||
iftrue=(%mf_isBlank(&ext))
|
||||
,msg=%str(No file extension provided.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
%mp_abort(
|
||||
iftrue=(%mf_isBlank(&typeDefNameVar) and
|
||||
@@ -56,13 +57,13 @@
|
||||
%mf_isBlank(&mediaTypeVar))
|
||||
,msg=%str(MV_GETVIYAFILEEXTPARMS - No parameter was requested.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
%mp_abort(
|
||||
iftrue=(%mf_isBlank(&viyaFileExtRespLibDs))
|
||||
,msg=%str(No <libname.>dataset name provided to cache inital response.)
|
||||
,mac=MV_GETVIYAFILEEXTPARMS
|
||||
);
|
||||
)
|
||||
|
||||
/* Declare requested parameters as global macro vars and initialize blank */
|
||||
%if not %mf_isBlank(&typeDefNameVar) %then %do;
|
||||
@@ -79,9 +80,7 @@
|
||||
%end;
|
||||
|
||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||
%if &mdebug=1 %then %do;
|
||||
%put DEBUG: &=base_uri;
|
||||
%end;
|
||||
%if &mdebug=1 %then %put DEBUG: &=base_uri;
|
||||
|
||||
%let ext=%lowcase(&ext);
|
||||
|
||||
@@ -105,7 +104,7 @@
|
||||
|
||||
%if (&SYS_PROCHTTP_STATUS_CODE ne 200) %then %do;
|
||||
/* To avoid a breaking change, exit early if the request failed.
|
||||
The calling process will proceed with empty requested macro variables. */
|
||||
The calling process will proceed with empty macro variables. */
|
||||
%put INFO: &sysmacroname File extension details were not retrieved.;
|
||||
filename &viyatypedefs clear;
|
||||
%return;
|
||||
@@ -126,11 +125,12 @@
|
||||
/* Convert the content of that JSON into SAS datasets */
|
||||
/* First prepare a new WORK-based folder to receive the datasets */
|
||||
%local jsonworkfolder jsonlib opt_dlcreatedir;
|
||||
%let jsonworkfolder=%sysfunc(pathname(work))/%mf_getuniquename(prefix=json_);
|
||||
%let jsonworkfolder=%sysfunc(pathname(work))/%mf_getuniquename(prefix=jsn_);
|
||||
%let jsonlib=%mf_getuniquelibref(prefix=json);
|
||||
/* And point a libname at it */
|
||||
/* And point a libname at it */
|
||||
%let opt_dlcreatedir = %sysfunc(getoption(dlcreatedir));
|
||||
options dlcreatedir; libname &jsonlib "&jsonworkfolder"; options &opt_dlcreatedir;
|
||||
options dlcreatedir; libname &jsonlib "&jsonworkfolder";
|
||||
options &opt_dlcreatedir;
|
||||
|
||||
/* Read the json output once and copy datasets to its work folder */
|
||||
%local libref1;
|
||||
@@ -159,20 +159,22 @@
|
||||
|
||||
%end; /* If initial filetype query response didn't exist */
|
||||
|
||||
/* Find the row-group for the current file extension */
|
||||
%if &mdebug %then %put DEBUG: Find the row-group for extension &ext;
|
||||
%local itemRowGroup;
|
||||
%let itemRowGroup =
|
||||
%mf_getValue(
|
||||
&viyaFileExtRespLibDs
|
||||
,_viyaItemIdx
|
||||
,filter=%quote(p1='items' and p2='extensions' and value="&ext")
|
||||
);
|
||||
data _null_;
|
||||
set &viyaFileExtRespLibDs;
|
||||
where p1='items' and p2='extensions' and value="&ext";
|
||||
call symputx('itemRowGroup',_viyaItemIdx,'l');
|
||||
%if &mdebug %then %do;
|
||||
putlog (_all_)(=);
|
||||
%end;
|
||||
run;
|
||||
|
||||
%if &mdebug %then %put DEBUG: &=itemRowGroup;
|
||||
|
||||
%if %mf_isBlank(&itemRowGroup) %then %do;
|
||||
/* extension was not found */
|
||||
%if(&mdebug=1) %then %put DEBUG: No type details found for extension "&ext".;
|
||||
%if &mdebug %then %put DEBUG: No type details found for extension "&ext";
|
||||
%return;
|
||||
%end;
|
||||
|
||||
@@ -186,14 +188,17 @@
|
||||
|
||||
/* Populate typeDefName, if requested */
|
||||
%if (not %mf_isBlank(&typeDefNameVar)) %then %do;
|
||||
%let &typeDefNameVar = %mf_getvalue(&dsItems,value,filter=%quote(p1="items" and p2="name"));
|
||||
%if &mdebug=1 %then %put DEBUG: &=typeDefNameVar &typeDefNameVar=&&&typeDefNameVar;
|
||||
%let &typeDefNameVar = %mf_getvalue(
|
||||
&dsItems,value,filter=%quote(p1="items" and p2="name"));
|
||||
%if &mdebug %then
|
||||
%put DEBUG: &=typeDefNameVar &typeDefNameVar=&&&typeDefNameVar;
|
||||
%end;
|
||||
|
||||
/* Populate mediaType, if requested */
|
||||
%if (not %mf_isBlank(&mediaTypeVar)) %then %do;
|
||||
%let &mediaTypeVar = %mf_getvalue(&dsItems,value,filter=%quote(p1="items" and p2="mediaType"));
|
||||
%if &mdebug=1 %then %put DEBUG: &=mediaTypeVar &mediaTypeVar=&&&mediaTypeVar;
|
||||
%let &mediaTypeVar = %mf_getvalue(
|
||||
&dsItems,value,filter=%quote(p1="items" and p2="mediaType"));
|
||||
%if &mdebug %then %put DEBUG: &=mediaTypeVar &mediaTypeVar=&&&mediaTypeVar;
|
||||
%end;
|
||||
|
||||
/* Populate properties macro variable, if requested */
|
||||
@@ -210,7 +215,8 @@
|
||||
/* Check for 1+ properties */
|
||||
%if ( %mf_nobs(&dsProperties) = 0 ) %then %do;
|
||||
%let &propertiesVar = %str();
|
||||
%if &mdebug=1 %then %put DEBUG: &SYSMACRONAME - No Viya properties found for file suffix %str(%')&ext%str(%');
|
||||
%if &mdebug %then %put DEBUG: &SYSMACRONAME - No Viya properties %trim(
|
||||
)found for file suffix %str(%')&ext%str(%');
|
||||
%end;
|
||||
%else %do;
|
||||
/* Properties potentially span multiple rows in the input table */
|
||||
@@ -240,7 +246,8 @@
|
||||
end;
|
||||
run;
|
||||
|
||||
%if &mdebug=1 %then %put DEBUG: &=propertiesVar &propertiesVar=&&&propertiesVar;
|
||||
%if &mdebug %then
|
||||
%put DEBUG: &=propertiesVar &propertiesVar=&&&propertiesVar;
|
||||
%end;
|
||||
|
||||
%end;
|
||||
|
||||
+34
-19
@@ -121,7 +121,7 @@
|
||||
@li mf_nobs.sas
|
||||
@li mp_abort.sas
|
||||
@li mf_getplatform.sas
|
||||
@li mf_getuniquefileref.sas
|
||||
@li mf_getvarlist.sas
|
||||
@li mf_existvarlist.sas
|
||||
@li mv_jobwaitfor.sas
|
||||
@li mv_jobexecute.sas
|
||||
@@ -234,14 +234,12 @@ data _null_;
|
||||
if last then call symputx('flowcnt',cnt,'l');
|
||||
run;
|
||||
|
||||
/* prepare temporary datasets and frefs */
|
||||
%local fid jid jds jjson jdsapp jdsrunning jdswaitfor jfref;
|
||||
/* prepare temporary datasets */
|
||||
%local fid jid jds jdsapp jdsrunning jdswaitfor;
|
||||
data;run;%let jds=&syslast;
|
||||
data;run;%let jjson=&syslast;
|
||||
data;run;%let jdsapp=&syslast;
|
||||
data;run;%let jdsrunning=&syslast;
|
||||
data;run;%let jdswaitfor=&syslast;
|
||||
%let jfref=%mf_getuniquefileref();
|
||||
|
||||
/* start loop */
|
||||
%do fid=1 %to &flowcnt;
|
||||
@@ -259,23 +257,39 @@ data;run;%let jdswaitfor=&syslast;
|
||||
&dbg. if _n_= 1 then putlog "Loop &fid";
|
||||
&dbg. putlog (_all_)(=);
|
||||
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;
|
||||
%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_;
|
||||
infile &jfref lrecl=32767;
|
||||
input;
|
||||
jparams=cats('jparams',symget('jid'));
|
||||
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
||||
set &jds;
|
||||
if _n_=&jid;
|
||||
length _param $32767;
|
||||
_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;
|
||||
%local jobuid&jid;
|
||||
%let jobuid&jid=0; /* used in next loop */
|
||||
@@ -320,6 +334,7 @@ data;run;%let jdswaitfor=&syslast;
|
||||
,paramstring=%superq(jparams&jid)
|
||||
,outds=&jdsapp
|
||||
,contextname=&&context&jid
|
||||
,mdebug=&mdebug
|
||||
)
|
||||
data &jdsapp;
|
||||
format jobparams $32767.;
|
||||
|
||||
+21
-7
@@ -55,14 +55,14 @@
|
||||
,showmeta=N,maxobs=MAX,workobs=0
|
||||
);
|
||||
%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name
|
||||
sasjs_tables SYS_JES_JOB_URI;
|
||||
%if %index("&_debug",log) %then %let _debug=131;
|
||||
sasjs_tables SYS_JES_JOB_URI _EXECUTIONTASKS;
|
||||
%if %index("&_debug",log) %then %let _debug=128;
|
||||
|
||||
%local i tempds table;
|
||||
%let action=%upcase(&action);
|
||||
|
||||
%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;
|
||||
%end;
|
||||
|
||||
@@ -70,6 +70,11 @@
|
||||
%let _webin_file_count=%eval(&_webin_file_count+0);
|
||||
%let _webin_fileuri1=&_webin_fileuri;
|
||||
%let _webin_name1=&_webin_name;
|
||||
%if &_EXECUTIONTASKS=true %then %do;
|
||||
/* TODO - remove this once SAS Track CS0409737 is resolved */
|
||||
/* links: https://github.com/sasjs/adapter/issues/884 */
|
||||
%if %upcase(&_webin_name)=_SASJS_NOOP %then %let _webin_file_count=0;
|
||||
%end;
|
||||
%end;
|
||||
|
||||
/* if the sasjs_tables param is passed, we expect param based upload */
|
||||
@@ -110,13 +115,17 @@
|
||||
%end;
|
||||
%else %do i=1 %to &_webin_file_count;
|
||||
/* read in any files that are sent */
|
||||
/* this part needs refactoring for wide files */
|
||||
filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999;
|
||||
%if &_EXECUTIONTASKS=true %then %do;
|
||||
filename indata "%sysfunc(pathname(&&_webin_fileref&i))" lrecl=999999;
|
||||
%end;
|
||||
%else %do;
|
||||
filename indata filesrvc "&&_webin_fileuri&i" lrecl=999999;
|
||||
%end;
|
||||
data _null_;
|
||||
infile indata termstr=crlf lrecl=32767;
|
||||
input;
|
||||
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_;
|
||||
else stop;
|
||||
%end;
|
||||
@@ -149,6 +158,9 @@
|
||||
|
||||
/* setup json */
|
||||
data _null_;file &fref;
|
||||
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||
put '>>weboutBEGIN<<';
|
||||
%end;
|
||||
put '{"SYSDATE" : "' "&SYSDATE" '"';
|
||||
put ',"SYSTIME" : "' "&SYSTIME" '"';
|
||||
run;
|
||||
@@ -261,7 +273,9 @@
|
||||
memsize=quote(cats(memsize));
|
||||
put ',"MEMSIZE" : ' memsize;
|
||||
put "}";
|
||||
|
||||
%if %str(&_debug) ge 128 and &_EXECUTIONTASKS=true %then %do;
|
||||
put '>>weboutEND<<';
|
||||
%end;
|
||||
%if %upcase(&fref) ne _WEBOUT and &stream=Y %then %do;
|
||||
data _null_; rc=fcopy("&fref","_webout");run;
|
||||
%end;
|
||||
|
||||
@@ -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