mirror of
https://github.com/sasjs/core.git
synced 2026-01-04 08:00:05 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7726b0e0b0 | ||
|
|
0a536245f3 | ||
|
|
edfa9ecc07 | ||
|
|
f4982c85ca | ||
|
|
3ce771d587 | ||
|
|
72d6b446c3 | ||
|
|
40d694eec8 | ||
|
|
6af1423666 | ||
|
|
23a01347f1 | ||
|
|
7c86d6163a | ||
|
|
d7233208f1 | ||
|
|
7f587ba720 | ||
|
|
21ecc1b675 | ||
|
|
6b13dc2b87 | ||
|
|
bb89184212 | ||
|
|
56338caaca | ||
|
|
d7e2ff8ac9 | ||
|
|
582ec0a1f9 | ||
|
|
53785f5644 | ||
|
|
a8acadb8f1 | ||
|
|
23dbda302e | ||
|
|
7e7ab4275d | ||
|
|
a455a3d98d | ||
|
|
588d987c25 | ||
|
|
8ffd06343a |
@@ -1,5 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
sasjs lint
|
|
||||||
|
# Ensure lint is passing
|
||||||
|
LINT=`sasjs lint`
|
||||||
|
if [[ "$LINT" != "✔ All matched files use @sasjs/lint code style!" ]]; then
|
||||||
|
echo "$LINT"
|
||||||
|
echo "To commit in spite of these warnings, use the -n parameter."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Avoid commits to the master branch
|
# Avoid commits to the master branch
|
||||||
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- init: |
|
- init: npm install -g npm
|
||||||
nvm install --lts
|
- command: npm i
|
||||||
npm i -g @sasjs/cli
|
- command: npm i -g @sasjs/cli
|
||||||
|
|
||||||
image:
|
image:
|
||||||
file: .gitpod.dockerfile
|
file: .gitpod.dockerfile
|
||||||
@@ -24,4 +24,4 @@ github:
|
|||||||
# add a "Review in Gitpod" button to pull requests (defaults to false)
|
# add a "Review in Gitpod" button to pull requests (defaults to false)
|
||||||
addBadge: false
|
addBadge: false
|
||||||
# add a label once the prebuild is ready to pull requests (defaults to false)
|
# add a label once the prebuild is ready to pull requests (defaults to false)
|
||||||
addLabel: prebuilt-in-gitpod
|
addLabel: prebuilt-in-gitpod
|
||||||
|
|||||||
@@ -217,6 +217,15 @@ If you find this library useful, please leave a [star](https://github.com/sasjs/
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Other SAS Repositories
|
||||||
|
|
||||||
|
The following repositories are also worth checking out:
|
||||||
|
|
||||||
|
* [chris-swenson/sasmacros](https://github.com/chris-swenson/sasmacros)
|
||||||
|
* [greg-wotton/sas-programs](https://github.com/greg-wootton/sas-programs)
|
||||||
|
* [KatjaGlassConsulting/SMILE-SmartSASMacros](https://github.com/KatjaGlassConsulting/SMILE-SmartSASMacros)
|
||||||
|
* [scottbass/sas](https://github.com/scottbass/SAS)
|
||||||
|
* [yabwon/sas_packages](https://github.com/yabwon/SAS_PACKAGES)
|
||||||
|
|
||||||
## Contributors ✨
|
## Contributors ✨
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||||
|
|||||||
315
all.sas
315
all.sas
@@ -95,6 +95,37 @@ options noquotelenmax;
|
|||||||
%mend mf_dedup;
|
%mend mf_dedup;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a physical file, if it exists
|
||||||
|
@details Usage:
|
||||||
|
|
||||||
|
%mf_writefile(&sasjswork/myfile.txt,l1=some content)
|
||||||
|
|
||||||
|
%mf_deletefile(&sasjswork/myfile.txt)
|
||||||
|
|
||||||
|
%mf_deletefile(&sasjswork/myfile.txt)
|
||||||
|
|
||||||
|
|
||||||
|
@param filepath Full path to the target file
|
||||||
|
|
||||||
|
@returns The return code from the fdelete() invocation
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mf_deletefile.test.sas
|
||||||
|
@li mf_writefile.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mf_deletefile(file
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
%local rc fref;
|
||||||
|
%let rc= %sysfunc(filename(fref,&file));
|
||||||
|
%if %sysfunc(fdelete(&fref)) ne 0 %then %put %sysfunc(sysmsg());
|
||||||
|
%let rc= %sysfunc(filename(fref));
|
||||||
|
%mend mf_deletefile;
|
||||||
/**
|
/**
|
||||||
@file mf_existds.sas
|
@file mf_existds.sas
|
||||||
@brief Checks whether a dataset OR a view exists.
|
@brief Checks whether a dataset OR a view exists.
|
||||||
@@ -136,19 +167,17 @@ options noquotelenmax;
|
|||||||
|
|
||||||
%put %mf_existfeature(PROCLUA);
|
%put %mf_existfeature(PROCLUA);
|
||||||
|
|
||||||
@param feature the feature to detect. Leave blank to list all in log.
|
@param [in] feature The feature to detect.
|
||||||
|
|
||||||
@return output returns 1 or 0 (or -1 if not found)
|
@return output returns 1 or 0 (or -1 if not found)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
|
|
||||||
|
|
||||||
@version 8
|
@version 8
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
/** @cond */
|
/** @cond */
|
||||||
|
|
||||||
%macro mf_existfeature(feature
|
%macro mf_existfeature(feature
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%let feature=%upcase(&feature);
|
%let feature=%upcase(&feature);
|
||||||
@@ -156,7 +185,11 @@ options noquotelenmax;
|
|||||||
%let platform=%mf_getplatform();
|
%let platform=%mf_getplatform();
|
||||||
|
|
||||||
%if &feature= %then %do;
|
%if &feature= %then %do;
|
||||||
%put Supported features: PROCLUA;
|
%put No feature was requested for detection;
|
||||||
|
%end;
|
||||||
|
%else %if &feature=COLCONSTRAINTS %then %do;
|
||||||
|
%if %substr(&sysver,1,1)=4 %then 0;
|
||||||
|
%else 1;
|
||||||
%end;
|
%end;
|
||||||
%else %if &feature=PROCLUA %then %do;
|
%else %if &feature=PROCLUA %then %do;
|
||||||
/* https://blogs.sas.com/content/sasdummy/2015/08/03/using-lua-within-your-sas-programs */
|
/* https://blogs.sas.com/content/sasdummy/2015/08/03/using-lua-within-your-sas-programs */
|
||||||
@@ -170,8 +203,8 @@ options noquotelenmax;
|
|||||||
%put &sysmacroname: &feature not found;
|
%put &sysmacroname: &feature not found;
|
||||||
%end;
|
%end;
|
||||||
%mend mf_existfeature;
|
%mend mf_existfeature;
|
||||||
|
/** @endcond */
|
||||||
/** @endcond *//**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Checks whether a fileref exists
|
@brief Checks whether a fileref exists
|
||||||
@details You can probably do without this macro as it is just a one liner.
|
@details You can probably do without this macro as it is just a one liner.
|
||||||
@@ -2161,7 +2194,7 @@ Usage:
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
/* Stored Process Server web app context */
|
/* Stored Process Server web app context */
|
||||||
%if %symexist(_metaperson)
|
%if %symexist(_METAFOLDER)
|
||||||
or "&SYSPROCESSNAME "="Compute Server "
|
or "&SYSPROCESSNAME "="Compute Server "
|
||||||
or &mode=INCLUDE
|
or &mode=INCLUDE
|
||||||
%then %do;
|
%then %do;
|
||||||
@@ -2237,12 +2270,14 @@ Usage:
|
|||||||
/* send response in SASjs JSON format */
|
/* send response in SASjs JSON format */
|
||||||
data _null_;
|
data _null_;
|
||||||
file _webout mod lrecl=32000 encoding='utf-8';
|
file _webout mod lrecl=32000 encoding='utf-8';
|
||||||
length msg $32767 ;
|
length msg syswarningtext syserrortext $32767 ;
|
||||||
sasdatetime=datetime();
|
sasdatetime=datetime();
|
||||||
msg=symget('msg');
|
msg=symget('msg');
|
||||||
%if &logline>0 %then %do;
|
%if &logline>0 %then %do;
|
||||||
msg=cats(msg,'\n\nLog Extract:\n',symget('logmsg'));
|
msg=cats(msg,'\n\nLog Extract:\n',symget('logmsg'));
|
||||||
%end;
|
%end;
|
||||||
|
/* escape the escapes */
|
||||||
|
msg=tranwrd(msg,'\','\\');
|
||||||
/* escape the quotes */
|
/* escape the quotes */
|
||||||
msg=tranwrd(msg,'"','\"');
|
msg=tranwrd(msg,'"','\"');
|
||||||
/* ditch the CRLFs as chrome complains */
|
/* ditch the CRLFs as chrome complains */
|
||||||
@@ -2336,7 +2371,8 @@ Usage:
|
|||||||
%end;
|
%end;
|
||||||
%mend mp_abort;
|
%mend mp_abort;
|
||||||
|
|
||||||
/** @endcond *//**
|
/** @endcond */
|
||||||
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Append (concatenate) two or more files.
|
@brief Append (concatenate) two or more files.
|
||||||
@details Will append one more more `appendrefs` (filerefs) to a `baseref`.
|
@details Will append one more more `appendrefs` (filerefs) to a `baseref`.
|
||||||
@@ -3166,7 +3202,7 @@ run;
|
|||||||
|
|
||||||
proc compare
|
proc compare
|
||||||
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
|
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
|
||||||
compare=&ds;
|
compare=&ds noprint;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &sysinfo=0 %then %do;
|
%if &sysinfo=0 %then %do;
|
||||||
@@ -7918,8 +7954,8 @@ run;
|
|||||||
%mend mp_guesspk;/**
|
%mend mp_guesspk;/**
|
||||||
@file
|
@file
|
||||||
@brief Returns a unique hash for a dataset
|
@brief Returns a unique hash for a dataset
|
||||||
@details Ignores metadata attributes, used only to hash values. Compared
|
@details Ignores metadata attributes, used only to hash values. If used to
|
||||||
datasets must be in the same order.
|
compare datasets, they must have their columns and rows in the same order.
|
||||||
|
|
||||||
%mp_hashdataset(sashelp.class,outds=myhash)
|
%mp_hashdataset(sashelp.class,outds=myhash)
|
||||||
|
|
||||||
@@ -7934,7 +7970,10 @@ run;
|
|||||||
@li mf_getattrn.sas
|
@li mf_getattrn.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mf_getvarlist.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_getvartype.sas
|
@li mp_md5.sas
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mp_hashdataset.test.sas
|
||||||
|
|
||||||
@param [in] libds dataset to hash
|
@param [in] libds dataset to hash
|
||||||
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
||||||
@@ -7952,51 +7991,52 @@ run;
|
|||||||
|
|
||||||
%macro mp_hashdataset(
|
%macro mp_hashdataset(
|
||||||
libds,
|
libds,
|
||||||
outds=,
|
outds=work._data_,
|
||||||
salt=,
|
salt=,
|
||||||
iftrue=%str(1=1)
|
iftrue=%str(1=1)
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
%local keyvar /* roll up the md5 */
|
||||||
|
prevkeyvar /* retain prev record md5 */
|
||||||
|
lastvar /* last var in input ds */
|
||||||
|
cvars nvars;
|
||||||
|
|
||||||
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
%put %str(WARN)ING: Dataset &libds is empty, or is not a dataset;
|
|
||||||
%end;
|
/* avoid naming conflict for hash key vars */
|
||||||
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
%let keyvar=%mf_getuniquename();
|
||||||
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
%let prevkeyvar=%mf_getuniquename();
|
||||||
%end;
|
%let lastvar=%mf_getuniquename();
|
||||||
%else %do;
|
|
||||||
%local keyvar /* roll up the md5 */
|
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
||||||
prevkeyvar /* retain prev record md5 */
|
data &outds;
|
||||||
lastvar /* last var in input ds */
|
length hashkey $32;
|
||||||
varlist var i;
|
retain hashkey "%sysfunc(md5(%str(&salt)),$hex32.)";
|
||||||
/* avoid naming conflict for hash key vars */
|
output;
|
||||||
%let keyvar=%mf_getuniquename();
|
stop;
|
||||||
%let prevkeyvar=%mf_getuniquename();
|
run;
|
||||||
%let lastvar=%mf_getuniquename();
|
%put &sysmacroname: Dataset &libds is empty, or is not a dataset;
|
||||||
%let varlist=%mf_getvarlist(&libds);
|
%put &sysmacroname: hashkey of &outds is based on salt (&salt) only;
|
||||||
data &outds(rename=(&keyvar=hashkey) keep=&keyvar);
|
%end;
|
||||||
length &prevkeyvar &keyvar $32;
|
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
||||||
retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
|
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
||||||
set &libds end=&lastvar;
|
%end;
|
||||||
/* hash should include previous row */
|
%else %do;
|
||||||
&keyvar=put(md5(&prevkeyvar
|
data &outds(rename=(&keyvar=hashkey) keep=&keyvar)/nonote2err;
|
||||||
/* loop every column, hashing every individual value */
|
length &prevkeyvar &keyvar $32;
|
||||||
%do i=1 %to %sysfunc(countw(&varlist));
|
retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
|
||||||
%let var=%scan(&varlist,&i,%str( ));
|
set &libds end=&lastvar;
|
||||||
%if %mf_getvartype(&libds,&var)=C %then %do;
|
/* hash should include previous row */
|
||||||
!!put(md5(trim(&var)),$hex32.)
|
&keyvar=%mp_md5(
|
||||||
%end;
|
cvars=%mf_getvarlist(&libds,typefilter=C) &prevkeyvar,
|
||||||
%else %do;
|
nvars=%mf_getvarlist(&libds,typefilter=N)
|
||||||
!!put(md5(trim(put(&var*1,binary64.))),$hex32.)
|
);
|
||||||
%end;
|
&prevkeyvar=&keyvar;
|
||||||
%end;
|
if &lastvar then output;
|
||||||
),$hex32.);
|
run;
|
||||||
&prevkeyvar=&keyvar;
|
%end;
|
||||||
if &lastvar then output;
|
%mend mp_hashdataset;
|
||||||
run;
|
/**
|
||||||
%end;
|
|
||||||
%mend mp_hashdataset;/**
|
|
||||||
@file
|
@file
|
||||||
@brief Performs a wrapped \%include
|
@brief Performs a wrapped \%include
|
||||||
@details This macro wrapper is necessary if you need your included code to
|
@details This macro wrapper is necessary if you need your included code to
|
||||||
@@ -8381,8 +8421,15 @@ options
|
|||||||
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
||||||
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
||||||
prxchange('s/'!!'09'x!!'/\t/',-1,
|
prxchange('s/'!!'09'x!!'/\t/',-1,
|
||||||
|
prxchange('s/'!!'00'x!!'/\\u0000/',-1, /* NUL */
|
||||||
|
prxchange('s/'!!'0E'x!!'/\\u000E/',-1, /* SS */
|
||||||
|
prxchange('s/'!!'0F'x!!'/\\u000F/',-1, /* SF */
|
||||||
|
prxchange('s/'!!'01'x!!'/\\u0001/',-1, /* SOH */
|
||||||
|
prxchange('s/'!!'02'x!!'/\\u0002/',-1, /* STX */
|
||||||
|
prxchange('s/'!!'02'x!!'/\\u0010/',-1, /* DLE */
|
||||||
|
prxchange('s/'!!'11'x!!'/\\u0011/',-1, /* DC1 */
|
||||||
prxchange('s/\\/\\\\/',-1,&&name&i)
|
prxchange('s/\\/\\\\/',-1,&&name&i)
|
||||||
)))))!!'"';
|
))))))))))))!!'"';
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
@@ -8737,7 +8784,7 @@ run;
|
|||||||
* First, extract only relevant formats from the catalog
|
* First, extract only relevant formats from the catalog
|
||||||
*/
|
*/
|
||||||
proc sql noprint;
|
proc sql noprint;
|
||||||
select distinct fmtname into: fmtlist separated by ' ' from &libds;
|
select distinct upcase(fmtname) into: fmtlist separated by ' ' from &libds;
|
||||||
|
|
||||||
%mp_cntlout(libcat=&libcat,fmtlist=&fmtlist,cntlout=&base_fmts)
|
%mp_cntlout(libcat=&libcat,fmtlist=&fmtlist,cntlout=&base_fmts)
|
||||||
|
|
||||||
@@ -8747,8 +8794,11 @@ select distinct fmtname into: fmtlist separated by ' ' from &libds;
|
|||||||
*/
|
*/
|
||||||
%mddl_sas_cntlout(libds=&template)
|
%mddl_sas_cntlout(libds=&template)
|
||||||
data &inlibds;
|
data &inlibds;
|
||||||
|
length &delete_col $3;
|
||||||
if 0 then set &template;
|
if 0 then set &template;
|
||||||
set &libds;
|
set &libds;
|
||||||
|
if &delete_col='' then &delete_col='No';
|
||||||
|
fmtname=upcase(fmtname);
|
||||||
if missing(type) then do;
|
if missing(type) then do;
|
||||||
if substr(fmtname,1,1)='$' then type='C';
|
if substr(fmtname,1,1)='$' then type='C';
|
||||||
else type='N';
|
else type='N';
|
||||||
@@ -8759,7 +8809,6 @@ data &inlibds;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identify new records
|
* Identify new records
|
||||||
*/
|
*/
|
||||||
@@ -8866,7 +8915,7 @@ options ibufsize=&ibufsize;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mp_storediffs(&libcat-FC
|
%mp_storediffs(&libcat-FC
|
||||||
,&inlibds
|
,&base_fmts
|
||||||
,FMTNAME START
|
,FMTNAME START
|
||||||
,delds=&outds_del
|
,delds=&outds_del
|
||||||
,modds=&outds_mod
|
,modds=&outds_mod
|
||||||
@@ -13322,8 +13371,8 @@ run;
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
|
||||||
@param libref the libref (not name) of the metadata library
|
@param [in] libref The libref (not name) of the metadata library
|
||||||
@param mAbort= If not assigned, HARD will call %mp_abort(), SOFT will
|
@param [in] mAbort= If not assigned, HARD will call %mp_abort(), SOFT will
|
||||||
silently return
|
silently return
|
||||||
|
|
||||||
@returns libname statement
|
@returns libname statement
|
||||||
@@ -13337,11 +13386,11 @@ run;
|
|||||||
libref
|
libref
|
||||||
,mAbort=HARD
|
,mAbort=HARD
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
%local mp_abort msg;
|
||||||
|
%let mp_abort=0;
|
||||||
%if %sysfunc(libref(&libref)) %then %do;
|
%if %sysfunc(libref(&libref)) %then %do;
|
||||||
%local mp_abort msg; %let mp_abort=0;
|
|
||||||
data _null_;
|
data _null_;
|
||||||
length liburi LibName $200;
|
length liburi LibName msg $200;
|
||||||
call missing(of _all_);
|
call missing(of _all_);
|
||||||
nobj=metadata_getnobj("omsobj:SASLibrary?@Libref='&libref'",1,liburi);
|
nobj=metadata_getnobj("omsobj:SASLibrary?@Libref='&libref'",1,liburi);
|
||||||
if nobj=1 then do;
|
if nobj=1 then do;
|
||||||
@@ -13355,7 +13404,24 @@ run;
|
|||||||
* not always helpful though. One example, previously received:
|
* not always helpful though. One example, previously received:
|
||||||
* NOTE: Libref XX refers to the same library metadata as libref XX.
|
* NOTE: Libref XX refers to the same library metadata as libref XX.
|
||||||
*/
|
*/
|
||||||
call symputx('msg',sysmsg(),'l');
|
msg=sysmsg();
|
||||||
|
if msg=:'ERROR: Libref SAVE is not assigned.' then do;
|
||||||
|
msg=catx(" ",
|
||||||
|
"Could not assign %upcase(&libref).",
|
||||||
|
"Please check metadata permissions! Libname:",libname,
|
||||||
|
"Liburi:",liburi
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
else if msg="ERROR: User does not have appropriate authorization "!!
|
||||||
|
"level for library SAVE."
|
||||||
|
then do;
|
||||||
|
msg=catx(" ",
|
||||||
|
"ERROR: User does not have appropriate authorization level",
|
||||||
|
"for library %upcase(&libref), libname:",libname,
|
||||||
|
"Liburi:",liburi
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
call symputx('msg',msg,'l');
|
||||||
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
|
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
|
||||||
end;
|
end;
|
||||||
else do;
|
else do;
|
||||||
@@ -13374,22 +13440,18 @@ run;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mp_abort=1 %then %do;
|
%put NOTE: &msg;
|
||||||
%mp_abort(iftrue= (&mp_abort=1)
|
|
||||||
,mac=mm_assignlib.sas
|
|
||||||
,msg=&msg
|
|
||||||
)
|
|
||||||
%return;
|
|
||||||
%end;
|
|
||||||
%else %if %length(&msg)>2 %then %do;
|
|
||||||
%put NOTE: &msg;
|
|
||||||
%return;
|
|
||||||
%end;
|
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put NOTE: Library &libref is already assigned;
|
%put NOTE: Library &libref is already assigned;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (&mp_abort=1)
|
||||||
|
,mac=mm_assignlib.sas
|
||||||
|
,msg=%superq(msg)
|
||||||
|
)
|
||||||
|
|
||||||
%mend mm_assignlib;
|
%mend mm_assignlib;
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@@ -14876,8 +14938,15 @@ data _null_;
|
|||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
||||||
|
put ' prxchange(''s/''!!''00''x!!''/\\u0000/'',-1, /* NUL */ ';
|
||||||
|
put ' prxchange(''s/''!!''0E''x!!''/\\u000E/'',-1, /* SS */ ';
|
||||||
|
put ' prxchange(''s/''!!''0F''x!!''/\\u000F/'',-1, /* SF */ ';
|
||||||
|
put ' prxchange(''s/''!!''01''x!!''/\\u0001/'',-1, /* SOH */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0002/'',-1, /* STX */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0010/'',-1, /* DLE */ ';
|
||||||
|
put ' prxchange(''s/''!!''11''x!!''/\\u0011/'',-1, /* DC1 */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' )))))!!''"''; ';
|
put ' ))))))))))))!!''"''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -17781,7 +17850,7 @@ filename __shake clear;
|
|||||||
%let platform_object_path=%mf_loc(POF);
|
%let platform_object_path=%mf_loc(POF);
|
||||||
%let ds=%mf_getuniquename(prefix=spkexportable);
|
%let ds=%mf_getuniquename(prefix=spkexportable);
|
||||||
|
|
||||||
%mm_tree(root=%str(&metaloc) ,types=EXPORTABLE ,outds=&ds)
|
%mm_tree(root=%str(&metaloc),types=EXPORTABLE ,outds=&ds)
|
||||||
|
|
||||||
%if %mf_isblank(&outref)=1 %then %let outref=%mf_getuniquefileref();
|
%if %mf_isblank(&outref)=1 %then %let outref=%mf_getuniquefileref();
|
||||||
|
|
||||||
@@ -17790,19 +17859,27 @@ data _null_;
|
|||||||
file &outref lrecl=32767;
|
file &outref lrecl=32767;
|
||||||
length str $32767;
|
length str $32767;
|
||||||
if _n_=1 then do;
|
if _n_=1 then do;
|
||||||
|
put "# Script generated by &sysuserid on %sysfunc(datetime(),datetime19.)";
|
||||||
put "cd ""&platform_object_path"" \";
|
put "cd ""&platform_object_path"" \";
|
||||||
put "; ./ExportPackage -host &host -port &port -user &mmxuser \";
|
put "; ./ExportPackage -host &host -port &port -user &mmxuser \";
|
||||||
put " -disableX11 -password &mmxpass \"
|
put " -disableX11 -password &mmxpass \";
|
||||||
put " -package ""&cmdoutloc/&cmdoutname..spk"" \";
|
put " -package ""&cmdoutloc/&cmdoutname..spk"" \";
|
||||||
end;
|
end;
|
||||||
/* exclude particular patterns from the exported SPK */
|
/* exclude particular patterns from the exported SPK */
|
||||||
%if "&excludevars" ne "0" %then %do;
|
%if "&excludevars" ne "0" %then %do;
|
||||||
/* ignore top level folder else all subcontent will be exported regardless */
|
|
||||||
if _n_>1;
|
|
||||||
%do i=1 %to %sysfunc(countw(&excludevars));
|
%do i=1 %to %sysfunc(countw(&excludevars));
|
||||||
%let var=%scan(&excludevars,&i);
|
%let var=%scan(&excludevars,&i);
|
||||||
if index(path,symget("&var")) ne 0;
|
if _n_=1 then do;
|
||||||
|
length excludestr&i $1000;
|
||||||
|
retain excludestr&i;
|
||||||
|
excludestr&i=symget("&var");
|
||||||
|
putlog excludestr&i=;
|
||||||
|
putlog path=;
|
||||||
|
end;
|
||||||
|
if index(path,cats(excludestr&i))=0 and index(name,cats(excludestr&i))=0;
|
||||||
%end;
|
%end;
|
||||||
|
/* ignore top level folder else all subcontent will be exported regardless */
|
||||||
|
if _n_>1;
|
||||||
%end;
|
%end;
|
||||||
str=' -objects '!!cats('"',path,'/',name,"(",publictype,')" \');
|
str=' -objects '!!cats('"',path,'/',name,"(",publictype,')" \');
|
||||||
put str;
|
put str;
|
||||||
@@ -18825,9 +18902,10 @@ run;
|
|||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
|
||||||
%local fname0 fname1 boundary fname statcd msg;
|
%local fname0 fname1 fname2 boundary fname statcd msg;
|
||||||
%let fname0=%mf_getuniquefileref();
|
%let fname0=%mf_getuniquefileref();
|
||||||
%let fname1=%mf_getuniquefileref();
|
%let fname1=%mf_getuniquefileref();
|
||||||
|
%let fname2=%mf_getuniquefileref();
|
||||||
%let boundary=%mf_getuniquename();
|
%let boundary=%mf_getuniquename();
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
@@ -18851,17 +18929,25 @@ data _null_;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &fname1;
|
||||||
|
put "Content-Type: multipart/form-data; boundary=&boundary";
|
||||||
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname0;
|
infile &fname0;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
|
data _null_;
|
||||||
|
infile &fname1;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc http method='POST' in=&fname0 out=&fname1
|
proc http method='POST' in=&fname0 headerin=&fname1 out=&fname2
|
||||||
url="&_sasjs_apiserverurl/SASjsApi/drive/file";
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file";
|
||||||
headers "Content-Type"="multipart/form-data; boundary=&boundary";
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level=1;
|
debug level=1;
|
||||||
%end;
|
%end;
|
||||||
@@ -18869,7 +18955,7 @@ run;
|
|||||||
|
|
||||||
%let statcd=0;
|
%let statcd=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname1;
|
infile &fname2;
|
||||||
input;
|
input;
|
||||||
putlog _infile_;
|
putlog _infile_;
|
||||||
if _infile_='{"status":"success"}' then call symputx('statcd',1,'l');
|
if _infile_='{"status":"success"}' then call symputx('statcd',1,'l');
|
||||||
@@ -18883,6 +18969,41 @@ run;
|
|||||||
)
|
)
|
||||||
|
|
||||||
%mend ms_createfile;
|
%mend ms_createfile;
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a file from SASjs Drive
|
||||||
|
@details Deletes a file from SASjs Drive, if it exists.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
filename stpcode temp;
|
||||||
|
data _null_;
|
||||||
|
file stpcode;
|
||||||
|
put '%put hello world;';
|
||||||
|
run;
|
||||||
|
%ms_createfile(/some/stored/program.sas, inref=stpcode)
|
||||||
|
|
||||||
|
%ms_deletefile(/some/stored/program.sas)
|
||||||
|
|
||||||
|
@param [in] driveloc The full path to the file in SASjs Drive
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_deletefile(driveloc
|
||||||
|
,mdebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
proc http method='DELETE'
|
||||||
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file?_filePath=&driveloc";
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
debug level=2;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
|
||||||
|
%mend ms_deletefile;
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Gets a file from SASjs Drive
|
@brief Gets a file from SASjs Drive
|
||||||
@@ -18896,6 +19017,9 @@ run;
|
|||||||
@param [out] outref= (msgetfil) The fileref to contain the file.
|
@param [out] outref= (msgetfil) The fileref to contain the file.
|
||||||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -18904,15 +19028,21 @@ run;
|
|||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
|
||||||
filename &outref temp;
|
/* use the recfm in a separate fileref to avoid issues with subsequent reads */
|
||||||
|
%local binaryfref floc;
|
||||||
|
%let binaryfref=%mf_getuniquefileref();
|
||||||
|
%let floc=%sysfunc(pathname(work))/%mf_getuniquename().txt;
|
||||||
|
filename &outref "&floc";
|
||||||
|
filename &binaryfref "&floc" recfm=n;
|
||||||
|
|
||||||
proc http method='GET' out=&outref
|
proc http method='GET' out=&binaryfref
|
||||||
url="&_sasjs_apiserverurl/SASjsApi/drive/file?filePath=&driveloc";
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file?_filePath=&driveloc";
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level=2;
|
debug level=2;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
filename &binaryfref clear;
|
||||||
|
|
||||||
%mend ms_getfile;
|
%mend ms_getfile;
|
||||||
/**
|
/**
|
||||||
@@ -19107,6 +19237,7 @@ run;
|
|||||||
data _null_;
|
data _null_;
|
||||||
set &tempds;
|
set &tempds;
|
||||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||||
|
if not (upcase(name)=:"_DATA_");
|
||||||
i+1;
|
i+1;
|
||||||
call symputx(cats('wt',i),name,'l');
|
call symputx(cats('wt',i),name,'l');
|
||||||
call symputx('wtcnt',i,'l');
|
call symputx('wtcnt',i,'l');
|
||||||
@@ -20285,8 +20416,15 @@ data _null_;
|
|||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
||||||
|
put ' prxchange(''s/''!!''00''x!!''/\\u0000/'',-1, /* NUL */ ';
|
||||||
|
put ' prxchange(''s/''!!''0E''x!!''/\\u000E/'',-1, /* SS */ ';
|
||||||
|
put ' prxchange(''s/''!!''0F''x!!''/\\u000F/'',-1, /* SF */ ';
|
||||||
|
put ' prxchange(''s/''!!''01''x!!''/\\u0001/'',-1, /* SOH */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0002/'',-1, /* STX */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0010/'',-1, /* DLE */ ';
|
||||||
|
put ' prxchange(''s/''!!''11''x!!''/\\u0011/'',-1, /* DC1 */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' )))))!!''"''; ';
|
put ' ))))))))))))!!''"''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -21048,6 +21186,7 @@ libname &libref1a clear;
|
|||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
@li mf_existds.sas
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
@li mf_getuniquelibref.sas
|
@li mf_getuniquelibref.sas
|
||||||
|
|||||||
31
base/mf_deletefile.sas
Normal file
31
base/mf_deletefile.sas
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a physical file, if it exists
|
||||||
|
@details Usage:
|
||||||
|
|
||||||
|
%mf_writefile(&sasjswork/myfile.txt,l1=some content)
|
||||||
|
|
||||||
|
%mf_deletefile(&sasjswork/myfile.txt)
|
||||||
|
|
||||||
|
%mf_deletefile(&sasjswork/myfile.txt)
|
||||||
|
|
||||||
|
|
||||||
|
@param filepath Full path to the target file
|
||||||
|
|
||||||
|
@returns The return code from the fdelete() invocation
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mf_deletefile.test.sas
|
||||||
|
@li mf_writefile.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mf_deletefile(file
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
%local rc fref;
|
||||||
|
%let rc= %sysfunc(filename(fref,&file));
|
||||||
|
%if %sysfunc(fdelete(&fref)) ne 0 %then %put %sysfunc(sysmsg());
|
||||||
|
%let rc= %sysfunc(filename(fref));
|
||||||
|
%mend mf_deletefile;
|
||||||
@@ -9,19 +9,17 @@
|
|||||||
|
|
||||||
%put %mf_existfeature(PROCLUA);
|
%put %mf_existfeature(PROCLUA);
|
||||||
|
|
||||||
@param feature the feature to detect. Leave blank to list all in log.
|
@param [in] feature The feature to detect.
|
||||||
|
|
||||||
@return output returns 1 or 0 (or -1 if not found)
|
@return output returns 1 or 0 (or -1 if not found)
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
|
|
||||||
|
|
||||||
@version 8
|
@version 8
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
/** @cond */
|
/** @cond */
|
||||||
|
|
||||||
%macro mf_existfeature(feature
|
%macro mf_existfeature(feature
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%let feature=%upcase(&feature);
|
%let feature=%upcase(&feature);
|
||||||
@@ -29,7 +27,11 @@
|
|||||||
%let platform=%mf_getplatform();
|
%let platform=%mf_getplatform();
|
||||||
|
|
||||||
%if &feature= %then %do;
|
%if &feature= %then %do;
|
||||||
%put Supported features: PROCLUA;
|
%put No feature was requested for detection;
|
||||||
|
%end;
|
||||||
|
%else %if &feature=COLCONSTRAINTS %then %do;
|
||||||
|
%if %substr(&sysver,1,1)=4 %then 0;
|
||||||
|
%else 1;
|
||||||
%end;
|
%end;
|
||||||
%else %if &feature=PROCLUA %then %do;
|
%else %if &feature=PROCLUA %then %do;
|
||||||
/* https://blogs.sas.com/content/sasdummy/2015/08/03/using-lua-within-your-sas-programs */
|
/* https://blogs.sas.com/content/sasdummy/2015/08/03/using-lua-within-your-sas-programs */
|
||||||
@@ -43,5 +45,4 @@
|
|||||||
%put &sysmacroname: &feature not found;
|
%put &sysmacroname: &feature not found;
|
||||||
%end;
|
%end;
|
||||||
%mend mf_existfeature;
|
%mend mf_existfeature;
|
||||||
|
/** @endcond */
|
||||||
/** @endcond */
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
/* Stored Process Server web app context */
|
/* Stored Process Server web app context */
|
||||||
%if %symexist(_metaperson)
|
%if %symexist(_METAFOLDER)
|
||||||
or "&SYSPROCESSNAME "="Compute Server "
|
or "&SYSPROCESSNAME "="Compute Server "
|
||||||
or &mode=INCLUDE
|
or &mode=INCLUDE
|
||||||
%then %do;
|
%then %do;
|
||||||
@@ -161,12 +161,14 @@
|
|||||||
/* send response in SASjs JSON format */
|
/* send response in SASjs JSON format */
|
||||||
data _null_;
|
data _null_;
|
||||||
file _webout mod lrecl=32000 encoding='utf-8';
|
file _webout mod lrecl=32000 encoding='utf-8';
|
||||||
length msg $32767 ;
|
length msg syswarningtext syserrortext $32767 ;
|
||||||
sasdatetime=datetime();
|
sasdatetime=datetime();
|
||||||
msg=symget('msg');
|
msg=symget('msg');
|
||||||
%if &logline>0 %then %do;
|
%if &logline>0 %then %do;
|
||||||
msg=cats(msg,'\n\nLog Extract:\n',symget('logmsg'));
|
msg=cats(msg,'\n\nLog Extract:\n',symget('logmsg'));
|
||||||
%end;
|
%end;
|
||||||
|
/* escape the escapes */
|
||||||
|
msg=tranwrd(msg,'\','\\');
|
||||||
/* escape the quotes */
|
/* escape the quotes */
|
||||||
msg=tranwrd(msg,'"','\"');
|
msg=tranwrd(msg,'"','\"');
|
||||||
/* ditch the CRLFs as chrome complains */
|
/* ditch the CRLFs as chrome complains */
|
||||||
@@ -260,4 +262,4 @@
|
|||||||
%end;
|
%end;
|
||||||
%mend mp_abort;
|
%mend mp_abort;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
proc compare
|
proc compare
|
||||||
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
|
base=&scopeds(where=(upcase(name) not in (%mf_getquotedstr(&ilist))))
|
||||||
compare=&ds;
|
compare=&ds noprint;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &sysinfo=0 %then %do;
|
%if &sysinfo=0 %then %do;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Returns a unique hash for a dataset
|
@brief Returns a unique hash for a dataset
|
||||||
@details Ignores metadata attributes, used only to hash values. Compared
|
@details Ignores metadata attributes, used only to hash values. If used to
|
||||||
datasets must be in the same order.
|
compare datasets, they must have their columns and rows in the same order.
|
||||||
|
|
||||||
%mp_hashdataset(sashelp.class,outds=myhash)
|
%mp_hashdataset(sashelp.class,outds=myhash)
|
||||||
|
|
||||||
@@ -17,7 +17,10 @@
|
|||||||
@li mf_getattrn.sas
|
@li mf_getattrn.sas
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mf_getvarlist.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_getvartype.sas
|
@li mp_md5.sas
|
||||||
|
|
||||||
|
<h4> Related Files </h4>
|
||||||
|
@li mp_hashdataset.test.sas
|
||||||
|
|
||||||
@param [in] libds dataset to hash
|
@param [in] libds dataset to hash
|
||||||
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
@param [in] salt= Provide a salt (could be, for instance, the dataset name)
|
||||||
@@ -35,48 +38,48 @@
|
|||||||
|
|
||||||
%macro mp_hashdataset(
|
%macro mp_hashdataset(
|
||||||
libds,
|
libds,
|
||||||
outds=,
|
outds=work._data_,
|
||||||
salt=,
|
salt=,
|
||||||
iftrue=%str(1=1)
|
iftrue=%str(1=1)
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
%local keyvar /* roll up the md5 */
|
||||||
|
prevkeyvar /* retain prev record md5 */
|
||||||
|
lastvar /* last var in input ds */
|
||||||
|
cvars nvars;
|
||||||
|
|
||||||
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
%put %str(WARN)ING: Dataset &libds is empty, or is not a dataset;
|
|
||||||
%end;
|
/* avoid naming conflict for hash key vars */
|
||||||
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
%let keyvar=%mf_getuniquename();
|
||||||
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
%let prevkeyvar=%mf_getuniquename();
|
||||||
%end;
|
%let lastvar=%mf_getuniquename();
|
||||||
%else %do;
|
|
||||||
%local keyvar /* roll up the md5 */
|
%if %mf_getattrn(&libds,NLOBS)=0 %then %do;
|
||||||
prevkeyvar /* retain prev record md5 */
|
data &outds;
|
||||||
lastvar /* last var in input ds */
|
length hashkey $32;
|
||||||
varlist var i;
|
retain hashkey "%sysfunc(md5(%str(&salt)),$hex32.)";
|
||||||
/* avoid naming conflict for hash key vars */
|
output;
|
||||||
%let keyvar=%mf_getuniquename();
|
stop;
|
||||||
%let prevkeyvar=%mf_getuniquename();
|
run;
|
||||||
%let lastvar=%mf_getuniquename();
|
%put &sysmacroname: Dataset &libds is empty, or is not a dataset;
|
||||||
%let varlist=%mf_getvarlist(&libds);
|
%put &sysmacroname: hashkey of &outds is based on salt (&salt) only;
|
||||||
data &outds(rename=(&keyvar=hashkey) keep=&keyvar);
|
%end;
|
||||||
length &prevkeyvar &keyvar $32;
|
%else %if %mf_getattrn(&libds,NLOBS)<0 %then %do;
|
||||||
retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
|
%put %str(ERR)OR: Dataset &libds is not a dataset;
|
||||||
set &libds end=&lastvar;
|
%end;
|
||||||
/* hash should include previous row */
|
%else %do;
|
||||||
&keyvar=put(md5(&prevkeyvar
|
data &outds(rename=(&keyvar=hashkey) keep=&keyvar)/nonote2err;
|
||||||
/* loop every column, hashing every individual value */
|
length &prevkeyvar &keyvar $32;
|
||||||
%do i=1 %to %sysfunc(countw(&varlist));
|
retain &prevkeyvar "%sysfunc(md5(%str(&salt)),$hex32.)";
|
||||||
%let var=%scan(&varlist,&i,%str( ));
|
set &libds end=&lastvar;
|
||||||
%if %mf_getvartype(&libds,&var)=C %then %do;
|
/* hash should include previous row */
|
||||||
!!put(md5(trim(&var)),$hex32.)
|
&keyvar=%mp_md5(
|
||||||
%end;
|
cvars=%mf_getvarlist(&libds,typefilter=C) &prevkeyvar,
|
||||||
%else %do;
|
nvars=%mf_getvarlist(&libds,typefilter=N)
|
||||||
!!put(md5(trim(put(&var*1,binary64.))),$hex32.)
|
);
|
||||||
%end;
|
&prevkeyvar=&keyvar;
|
||||||
%end;
|
if &lastvar then output;
|
||||||
),$hex32.);
|
run;
|
||||||
&prevkeyvar=&keyvar;
|
%end;
|
||||||
if &lastvar then output;
|
%mend mp_hashdataset;
|
||||||
run;
|
|
||||||
%end;
|
|
||||||
%mend mp_hashdataset;
|
|
||||||
|
|||||||
@@ -203,8 +203,15 @@
|
|||||||
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
prxchange('s/'!!'0A'x!!'/\n/',-1,
|
||||||
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
prxchange('s/'!!'0D'x!!'/\r/',-1,
|
||||||
prxchange('s/'!!'09'x!!'/\t/',-1,
|
prxchange('s/'!!'09'x!!'/\t/',-1,
|
||||||
|
prxchange('s/'!!'00'x!!'/\\u0000/',-1, /* NUL */
|
||||||
|
prxchange('s/'!!'0E'x!!'/\\u000E/',-1, /* SS */
|
||||||
|
prxchange('s/'!!'0F'x!!'/\\u000F/',-1, /* SF */
|
||||||
|
prxchange('s/'!!'01'x!!'/\\u0001/',-1, /* SOH */
|
||||||
|
prxchange('s/'!!'02'x!!'/\\u0002/',-1, /* STX */
|
||||||
|
prxchange('s/'!!'02'x!!'/\\u0010/',-1, /* DLE */
|
||||||
|
prxchange('s/'!!'11'x!!'/\\u0011/',-1, /* DC1 */
|
||||||
prxchange('s/\\/\\\\/',-1,&&name&i)
|
prxchange('s/\\/\\\\/',-1,&&name&i)
|
||||||
)))))!!'"';
|
))))))))))))!!'"';
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ run;
|
|||||||
* First, extract only relevant formats from the catalog
|
* First, extract only relevant formats from the catalog
|
||||||
*/
|
*/
|
||||||
proc sql noprint;
|
proc sql noprint;
|
||||||
select distinct fmtname into: fmtlist separated by ' ' from &libds;
|
select distinct upcase(fmtname) into: fmtlist separated by ' ' from &libds;
|
||||||
|
|
||||||
%mp_cntlout(libcat=&libcat,fmtlist=&fmtlist,cntlout=&base_fmts)
|
%mp_cntlout(libcat=&libcat,fmtlist=&fmtlist,cntlout=&base_fmts)
|
||||||
|
|
||||||
@@ -144,8 +144,11 @@ select distinct fmtname into: fmtlist separated by ' ' from &libds;
|
|||||||
*/
|
*/
|
||||||
%mddl_sas_cntlout(libds=&template)
|
%mddl_sas_cntlout(libds=&template)
|
||||||
data &inlibds;
|
data &inlibds;
|
||||||
|
length &delete_col $3;
|
||||||
if 0 then set &template;
|
if 0 then set &template;
|
||||||
set &libds;
|
set &libds;
|
||||||
|
if &delete_col='' then &delete_col='No';
|
||||||
|
fmtname=upcase(fmtname);
|
||||||
if missing(type) then do;
|
if missing(type) then do;
|
||||||
if substr(fmtname,1,1)='$' then type='C';
|
if substr(fmtname,1,1)='$' then type='C';
|
||||||
else type='N';
|
else type='N';
|
||||||
@@ -156,7 +159,6 @@ data &inlibds;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identify new records
|
* Identify new records
|
||||||
*/
|
*/
|
||||||
@@ -263,7 +265,7 @@ options ibufsize=&ibufsize;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mp_storediffs(&libcat-FC
|
%mp_storediffs(&libcat-FC
|
||||||
,&inlibds
|
,&base_fmts
|
||||||
,FMTNAME START
|
,FMTNAME START
|
||||||
,delds=&outds_del
|
,delds=&outds_del
|
||||||
,modds=&outds_mod
|
,modds=&outds_mod
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
|
||||||
@param libref the libref (not name) of the metadata library
|
@param [in] libref The libref (not name) of the metadata library
|
||||||
@param mAbort= If not assigned, HARD will call %mp_abort(), SOFT will
|
@param [in] mAbort= If not assigned, HARD will call %mp_abort(), SOFT will
|
||||||
silently return
|
silently return
|
||||||
|
|
||||||
@returns libname statement
|
@returns libname statement
|
||||||
@@ -28,11 +28,11 @@
|
|||||||
libref
|
libref
|
||||||
,mAbort=HARD
|
,mAbort=HARD
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
%local mp_abort msg;
|
||||||
|
%let mp_abort=0;
|
||||||
%if %sysfunc(libref(&libref)) %then %do;
|
%if %sysfunc(libref(&libref)) %then %do;
|
||||||
%local mp_abort msg; %let mp_abort=0;
|
|
||||||
data _null_;
|
data _null_;
|
||||||
length liburi LibName $200;
|
length liburi LibName msg $200;
|
||||||
call missing(of _all_);
|
call missing(of _all_);
|
||||||
nobj=metadata_getnobj("omsobj:SASLibrary?@Libref='&libref'",1,liburi);
|
nobj=metadata_getnobj("omsobj:SASLibrary?@Libref='&libref'",1,liburi);
|
||||||
if nobj=1 then do;
|
if nobj=1 then do;
|
||||||
@@ -46,7 +46,24 @@
|
|||||||
* not always helpful though. One example, previously received:
|
* not always helpful though. One example, previously received:
|
||||||
* NOTE: Libref XX refers to the same library metadata as libref XX.
|
* NOTE: Libref XX refers to the same library metadata as libref XX.
|
||||||
*/
|
*/
|
||||||
call symputx('msg',sysmsg(),'l');
|
msg=sysmsg();
|
||||||
|
if msg=:'ERROR: Libref SAVE is not assigned.' then do;
|
||||||
|
msg=catx(" ",
|
||||||
|
"Could not assign %upcase(&libref).",
|
||||||
|
"Please check metadata permissions! Libname:",libname,
|
||||||
|
"Liburi:",liburi
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
else if msg="ERROR: User does not have appropriate authorization "!!
|
||||||
|
"level for library SAVE."
|
||||||
|
then do;
|
||||||
|
msg=catx(" ",
|
||||||
|
"ERROR: User does not have appropriate authorization level",
|
||||||
|
"for library %upcase(&libref), libname:",libname,
|
||||||
|
"Liburi:",liburi
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
call symputx('msg',msg,'l');
|
||||||
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
|
if "&mabort"='HARD' then call symputx('mp_abort',1,'l');
|
||||||
end;
|
end;
|
||||||
else do;
|
else do;
|
||||||
@@ -65,20 +82,16 @@
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &mp_abort=1 %then %do;
|
%put NOTE: &msg;
|
||||||
%mp_abort(iftrue= (&mp_abort=1)
|
|
||||||
,mac=mm_assignlib.sas
|
|
||||||
,msg=&msg
|
|
||||||
)
|
|
||||||
%return;
|
|
||||||
%end;
|
|
||||||
%else %if %length(&msg)>2 %then %do;
|
|
||||||
%put NOTE: &msg;
|
|
||||||
%return;
|
|
||||||
%end;
|
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put NOTE: Library &libref is already assigned;
|
%put NOTE: Library &libref is already assigned;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
%mp_abort(iftrue= (&mp_abort=1)
|
||||||
|
,mac=mm_assignlib.sas
|
||||||
|
,msg=%superq(msg)
|
||||||
|
)
|
||||||
|
|
||||||
%mend mm_assignlib;
|
%mend mm_assignlib;
|
||||||
|
|||||||
@@ -236,8 +236,15 @@ data _null_;
|
|||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
||||||
|
put ' prxchange(''s/''!!''00''x!!''/\\u0000/'',-1, /* NUL */ ';
|
||||||
|
put ' prxchange(''s/''!!''0E''x!!''/\\u000E/'',-1, /* SS */ ';
|
||||||
|
put ' prxchange(''s/''!!''0F''x!!''/\\u000F/'',-1, /* SF */ ';
|
||||||
|
put ' prxchange(''s/''!!''01''x!!''/\\u0001/'',-1, /* SOH */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0002/'',-1, /* STX */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0010/'',-1, /* DLE */ ';
|
||||||
|
put ' prxchange(''s/''!!''11''x!!''/\\u0011/'',-1, /* DC1 */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' )))))!!''"''; ';
|
put ' ))))))))))))!!''"''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
%let platform_object_path=%mf_loc(POF);
|
%let platform_object_path=%mf_loc(POF);
|
||||||
%let ds=%mf_getuniquename(prefix=spkexportable);
|
%let ds=%mf_getuniquename(prefix=spkexportable);
|
||||||
|
|
||||||
%mm_tree(root=%str(&metaloc) ,types=EXPORTABLE ,outds=&ds)
|
%mm_tree(root=%str(&metaloc),types=EXPORTABLE ,outds=&ds)
|
||||||
|
|
||||||
%if %mf_isblank(&outref)=1 %then %let outref=%mf_getuniquefileref();
|
%if %mf_isblank(&outref)=1 %then %let outref=%mf_getuniquefileref();
|
||||||
|
|
||||||
@@ -111,19 +111,27 @@ data _null_;
|
|||||||
file &outref lrecl=32767;
|
file &outref lrecl=32767;
|
||||||
length str $32767;
|
length str $32767;
|
||||||
if _n_=1 then do;
|
if _n_=1 then do;
|
||||||
|
put "# Script generated by &sysuserid on %sysfunc(datetime(),datetime19.)";
|
||||||
put "cd ""&platform_object_path"" \";
|
put "cd ""&platform_object_path"" \";
|
||||||
put "; ./ExportPackage -host &host -port &port -user &mmxuser \";
|
put "; ./ExportPackage -host &host -port &port -user &mmxuser \";
|
||||||
put " -disableX11 -password &mmxpass \"
|
put " -disableX11 -password &mmxpass \";
|
||||||
put " -package ""&cmdoutloc/&cmdoutname..spk"" \";
|
put " -package ""&cmdoutloc/&cmdoutname..spk"" \";
|
||||||
end;
|
end;
|
||||||
/* exclude particular patterns from the exported SPK */
|
/* exclude particular patterns from the exported SPK */
|
||||||
%if "&excludevars" ne "0" %then %do;
|
%if "&excludevars" ne "0" %then %do;
|
||||||
/* ignore top level folder else all subcontent will be exported regardless */
|
|
||||||
if _n_>1;
|
|
||||||
%do i=1 %to %sysfunc(countw(&excludevars));
|
%do i=1 %to %sysfunc(countw(&excludevars));
|
||||||
%let var=%scan(&excludevars,&i);
|
%let var=%scan(&excludevars,&i);
|
||||||
if index(path,symget("&var")) ne 0;
|
if _n_=1 then do;
|
||||||
|
length excludestr&i $1000;
|
||||||
|
retain excludestr&i;
|
||||||
|
excludestr&i=symget("&var");
|
||||||
|
putlog excludestr&i=;
|
||||||
|
putlog path=;
|
||||||
|
end;
|
||||||
|
if index(path,cats(excludestr&i))=0 and index(name,cats(excludestr&i))=0;
|
||||||
%end;
|
%end;
|
||||||
|
/* ignore top level folder else all subcontent will be exported regardless */
|
||||||
|
if _n_>1;
|
||||||
%end;
|
%end;
|
||||||
str=' -objects '!!cats('"',path,'/',name,"(",publictype,')" \');
|
str=' -objects '!!cats('"',path,'/',name,"(",publictype,')" \');
|
||||||
put str;
|
put str;
|
||||||
|
|||||||
@@ -4,11 +4,8 @@
|
|||||||
"base",
|
"base",
|
||||||
"ddl",
|
"ddl",
|
||||||
"fcmp",
|
"fcmp",
|
||||||
"meta",
|
|
||||||
"metax",
|
|
||||||
"server",
|
|
||||||
"viya",
|
|
||||||
"lua",
|
"lua",
|
||||||
|
"server",
|
||||||
"tests/crossplatform",
|
"tests/crossplatform",
|
||||||
"tests/ddl"
|
"tests/ddl"
|
||||||
],
|
],
|
||||||
@@ -39,6 +36,7 @@
|
|||||||
},
|
},
|
||||||
"appLoc": "/Public/temp/macrocore",
|
"appLoc": "/Public/temp/macrocore",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
|
"viya",
|
||||||
"tests/viyaonly"
|
"tests/viyaonly"
|
||||||
],
|
],
|
||||||
"programFolders": [],
|
"programFolders": [],
|
||||||
@@ -58,6 +56,8 @@
|
|||||||
},
|
},
|
||||||
"appLoc": "/Shared Data/temp/macrocore",
|
"appLoc": "/Shared Data/temp/macrocore",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
|
"meta",
|
||||||
|
"metax",
|
||||||
"tests/sas9only"
|
"tests/sas9only"
|
||||||
],
|
],
|
||||||
"programFolders": [],
|
"programFolders": [],
|
||||||
@@ -78,6 +78,7 @@
|
|||||||
},
|
},
|
||||||
"appLoc": "/sasjs/core",
|
"appLoc": "/sasjs/core",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
|
"server",
|
||||||
"tests/serveronly"
|
"tests/serveronly"
|
||||||
],
|
],
|
||||||
"programFolders": [],
|
"programFolders": [],
|
||||||
@@ -92,6 +93,10 @@
|
|||||||
"serverType": "SAS9",
|
"serverType": "SAS9",
|
||||||
"appLoc": "dummy",
|
"appLoc": "dummy",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
|
"meta",
|
||||||
|
"metax",
|
||||||
|
"server",
|
||||||
|
"viya",
|
||||||
"tests/sas9only",
|
"tests/sas9only",
|
||||||
"tests/viyaonly"
|
"tests/viyaonly"
|
||||||
]
|
]
|
||||||
@@ -102,6 +107,7 @@
|
|||||||
"serverType": "SASVIYA",
|
"serverType": "SASVIYA",
|
||||||
"appLoc": "/Public/temp/macrocore",
|
"appLoc": "/Public/temp/macrocore",
|
||||||
"macroFolders": [
|
"macroFolders": [
|
||||||
|
"viya",
|
||||||
"tests/viyaonly"
|
"tests/viyaonly"
|
||||||
],
|
],
|
||||||
"deployConfig": {
|
"deployConfig": {
|
||||||
@@ -110,4 +116,4 @@
|
|||||||
"contextName": "SAS Job Execution compute context"
|
"contextName": "SAS Job Execution compute context"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,10 @@
|
|||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
|
||||||
%local fname0 fname1 boundary fname statcd msg;
|
%local fname0 fname1 fname2 boundary fname statcd msg;
|
||||||
%let fname0=%mf_getuniquefileref();
|
%let fname0=%mf_getuniquefileref();
|
||||||
%let fname1=%mf_getuniquefileref();
|
%let fname1=%mf_getuniquefileref();
|
||||||
|
%let fname2=%mf_getuniquefileref();
|
||||||
%let boundary=%mf_getuniquename();
|
%let boundary=%mf_getuniquename();
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
@@ -55,17 +56,25 @@ data _null_;
|
|||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
file &fname1;
|
||||||
|
put "Content-Type: multipart/form-data; boundary=&boundary";
|
||||||
|
run;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname0;
|
infile &fname0;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
|
data _null_;
|
||||||
|
infile &fname1;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc http method='POST' in=&fname0 out=&fname1
|
proc http method='POST' in=&fname0 headerin=&fname1 out=&fname2
|
||||||
url="&_sasjs_apiserverurl/SASjsApi/drive/file";
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file";
|
||||||
headers "Content-Type"="multipart/form-data; boundary=&boundary";
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level=1;
|
debug level=1;
|
||||||
%end;
|
%end;
|
||||||
@@ -73,7 +82,7 @@ run;
|
|||||||
|
|
||||||
%let statcd=0;
|
%let statcd=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname1;
|
infile &fname2;
|
||||||
input;
|
input;
|
||||||
putlog _infile_;
|
putlog _infile_;
|
||||||
if _infile_='{"status":"success"}' then call symputx('statcd',1,'l');
|
if _infile_='{"status":"success"}' then call symputx('statcd',1,'l');
|
||||||
|
|||||||
35
server/ms_deletefile.sas
Normal file
35
server/ms_deletefile.sas
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Deletes a file from SASjs Drive
|
||||||
|
@details Deletes a file from SASjs Drive, if it exists.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
filename stpcode temp;
|
||||||
|
data _null_;
|
||||||
|
file stpcode;
|
||||||
|
put '%put hello world;';
|
||||||
|
run;
|
||||||
|
%ms_createfile(/some/stored/program.sas, inref=stpcode)
|
||||||
|
|
||||||
|
%ms_deletefile(/some/stored/program.sas)
|
||||||
|
|
||||||
|
@param [in] driveloc The full path to the file in SASjs Drive
|
||||||
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro ms_deletefile(driveloc
|
||||||
|
,mdebug=0
|
||||||
|
);
|
||||||
|
|
||||||
|
proc http method='DELETE'
|
||||||
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file?_filePath=&driveloc";
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
debug level=2;
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
|
||||||
|
%mend ms_deletefile;
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
@param [out] outref= (msgetfil) The fileref to contain the file.
|
@param [out] outref= (msgetfil) The fileref to contain the file.
|
||||||
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -19,14 +22,20 @@
|
|||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
|
||||||
filename &outref temp;
|
/* use the recfm in a separate fileref to avoid issues with subsequent reads */
|
||||||
|
%local binaryfref floc;
|
||||||
|
%let binaryfref=%mf_getuniquefileref();
|
||||||
|
%let floc=%sysfunc(pathname(work))/%mf_getuniquename().txt;
|
||||||
|
filename &outref "&floc";
|
||||||
|
filename &binaryfref "&floc" recfm=n;
|
||||||
|
|
||||||
proc http method='GET' out=&outref
|
proc http method='GET' out=&binaryfref
|
||||||
url="&_sasjs_apiserverurl/SASjsApi/drive/file?filePath=&driveloc";
|
url="&_sasjs_apiserverurl/SASjsApi/drive/file?_filePath=&driveloc";
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level=2;
|
debug level=2;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
filename &binaryfref clear;
|
||||||
|
|
||||||
%mend ms_getfile;
|
%mend ms_getfile;
|
||||||
|
|||||||
@@ -114,6 +114,7 @@
|
|||||||
data _null_;
|
data _null_;
|
||||||
set &tempds;
|
set &tempds;
|
||||||
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
if not (upcase(name) =:"DATA"); /* ignore temp datasets */
|
||||||
|
if not (upcase(name)=:"_DATA_");
|
||||||
i+1;
|
i+1;
|
||||||
call symputx(cats('wt',i),name,'l');
|
call symputx(cats('wt',i),name,'l');
|
||||||
call symputx('wtcnt',i,'l');
|
call symputx('wtcnt',i,'l');
|
||||||
|
|||||||
29
tests/crossplatform/mf_deletefile.test.sas
Normal file
29
tests/crossplatform/mf_deletefile.test.sas
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mf_deletefile.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_deletefile.sas
|
||||||
|
@li mf_writefile.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%let test1file=&sasjswork/myfile1.txt;
|
||||||
|
|
||||||
|
%mf_writefile(&test1file,l1=some content)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%sysfunc(fileexist(&test1file))=1),
|
||||||
|
desc=Check &test1file exists
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mf_deletefile(&test1file)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%sysfunc(fileexist(&test1file))=0),
|
||||||
|
desc=Check &test1file no longer exists
|
||||||
|
)
|
||||||
60
tests/crossplatform/mp_hashdataset.test.sas
Normal file
60
tests/crossplatform/mp_hashdataset.test.sas
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_hashdataset.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_hashdataset.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* test 1 - regular DS */
|
||||||
|
data work.test;
|
||||||
|
set sashelp.vextfl;
|
||||||
|
missval=.;
|
||||||
|
misscval='';
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%mp_hashdataset(test)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=Regular test works,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_hashdataset(test,outds=work.test2)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=hash with output runs without errors,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.test2)=1),
|
||||||
|
desc=output has 1 row,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
data work.test3a;
|
||||||
|
set work.test;
|
||||||
|
stop;
|
||||||
|
run;
|
||||||
|
%mp_hashdataset(test3a,outds=work.test3b)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=hash with zero-row input runs without errors,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.test3b)=1),
|
||||||
|
desc=test 3 output has 1 row,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -82,3 +82,12 @@ run;
|
|||||||
desc=Test 1 - audit table updated,
|
desc=Test 1 - audit table updated,
|
||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
data work.difftest;
|
||||||
|
set perm.audit;
|
||||||
|
where is_diff=1;
|
||||||
|
run;
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%mf_nobs(work.difftest)>0),
|
||||||
|
desc=Test 1 - diffs were found,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|||||||
61
tests/serveronly/ms_deletefile.test.sas
Normal file
61
tests/serveronly/ms_deletefile.test.sas
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing ms_deletefile.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li ms_createfile.sas
|
||||||
|
@li ms_deletefile.sas
|
||||||
|
@li ms_getfile.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertscope.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
/* first make a remote file */
|
||||||
|
filename stpcode temp;
|
||||||
|
%let fname=%mf_getuniquename();
|
||||||
|
data _null_;
|
||||||
|
file stpcode;
|
||||||
|
put "data &fname;run;";
|
||||||
|
run;
|
||||||
|
%ms_createfile(/sasjs/tests/&fname..sas
|
||||||
|
,inref=stpcode
|
||||||
|
,mdebug=1
|
||||||
|
)
|
||||||
|
|
||||||
|
%ms_getfile(/sasjs/tests/&fname..sas,outref=testref)
|
||||||
|
|
||||||
|
%let test1=0;
|
||||||
|
data _null_;
|
||||||
|
infile testref;
|
||||||
|
input;
|
||||||
|
call symputx('test1',_infile_);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=("&test1"="data &fname;run;"),
|
||||||
|
desc=Make sure the file was created,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assertscope(SNAPSHOT)
|
||||||
|
%ms_deletefile(/sasjs/tests/&fname..sas,mdebug=1)
|
||||||
|
%mp_assertscope(COMPARE)
|
||||||
|
|
||||||
|
%ms_getfile(/sasjs/tests/&fname..sas,outref=testref2)
|
||||||
|
|
||||||
|
%let test2=0;
|
||||||
|
data _null_;
|
||||||
|
infile testref2;
|
||||||
|
input;
|
||||||
|
call symputx('test2',_infile_);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=("&test2"="%str(Err)or: File does not exist."),
|
||||||
|
desc=Make sure the file was deleted,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -380,8 +380,15 @@ data _null_;
|
|||||||
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
put ' prxchange(''s/''!!''0A''x!!''/\n/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
put ' prxchange(''s/''!!''0D''x!!''/\r/'',-1, ';
|
||||||
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
put ' prxchange(''s/''!!''09''x!!''/\t/'',-1, ';
|
||||||
|
put ' prxchange(''s/''!!''00''x!!''/\\u0000/'',-1, /* NUL */ ';
|
||||||
|
put ' prxchange(''s/''!!''0E''x!!''/\\u000E/'',-1, /* SS */ ';
|
||||||
|
put ' prxchange(''s/''!!''0F''x!!''/\\u000F/'',-1, /* SF */ ';
|
||||||
|
put ' prxchange(''s/''!!''01''x!!''/\\u0001/'',-1, /* SOH */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0002/'',-1, /* STX */ ';
|
||||||
|
put ' prxchange(''s/''!!''02''x!!''/\\u0010/'',-1, /* DLE */ ';
|
||||||
|
put ' prxchange(''s/''!!''11''x!!''/\\u0011/'',-1, /* DC1 */ ';
|
||||||
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
put ' prxchange(''s/\\/\\\\/'',-1,&&name&i) ';
|
||||||
put ' )))))!!''"''; ';
|
put ' ))))))))))))!!''"''; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
@li mf_existds.sas
|
||||||
@li mf_getplatform.sas
|
@li mf_getplatform.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
@li mf_getuniquelibref.sas
|
@li mf_getuniquelibref.sas
|
||||||
|
|||||||
Reference in New Issue
Block a user